diff options
author | Hugh Dickins <hughd@google.com> | 2012-07-11 17:02:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-11 19:04:48 -0400 |
commit | b065b4321fa78e83bf8f5b0d79d0b5424b57998b (patch) | |
tree | 353111b96469e4499faf8513c039ac9043236443 /mm/shmem.c | |
parent | d189922862e03ce6c7adc1e99d3b94e632dc8e89 (diff) |
shmem: cleanup shmem_add_to_page_cache
shmem_add_to_page_cache() has three callsites, but only one of them wants
the radix_tree_preload() (an exceptional entry guarantees that the radix
tree node is present in the other cases), and only that site can achieve
mem_cgroup_uncharge_cache_page() (PageSwapCache makes it a no-op in the
other cases). We did it this way originally to reflect
add_to_page_cache_locked(); but it's confusing now, so move the radix_tree
preloading and mem_cgroup uncharging to that one caller.
Signed-off-by: Hugh Dickins <hughd@google.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Michal Hocko <mhocko@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 294364a24a1..bd106361be4 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -288,40 +288,31 @@ static int shmem_add_to_page_cache(struct page *page, | |||
288 | struct address_space *mapping, | 288 | struct address_space *mapping, |
289 | pgoff_t index, gfp_t gfp, void *expected) | 289 | pgoff_t index, gfp_t gfp, void *expected) |
290 | { | 290 | { |
291 | int error = 0; | 291 | int error; |
292 | 292 | ||
293 | VM_BUG_ON(!PageLocked(page)); | 293 | VM_BUG_ON(!PageLocked(page)); |
294 | VM_BUG_ON(!PageSwapBacked(page)); | 294 | VM_BUG_ON(!PageSwapBacked(page)); |
295 | 295 | ||
296 | page_cache_get(page); | ||
297 | page->mapping = mapping; | ||
298 | page->index = index; | ||
299 | |||
300 | spin_lock_irq(&mapping->tree_lock); | ||
296 | if (!expected) | 301 | if (!expected) |
297 | error = radix_tree_preload(gfp & GFP_RECLAIM_MASK); | 302 | error = radix_tree_insert(&mapping->page_tree, index, page); |
303 | else | ||
304 | error = shmem_radix_tree_replace(mapping, index, expected, | ||
305 | page); | ||
298 | if (!error) { | 306 | if (!error) { |
299 | page_cache_get(page); | 307 | mapping->nrpages++; |
300 | page->mapping = mapping; | 308 | __inc_zone_page_state(page, NR_FILE_PAGES); |
301 | page->index = index; | 309 | __inc_zone_page_state(page, NR_SHMEM); |
302 | 310 | spin_unlock_irq(&mapping->tree_lock); | |
303 | spin_lock_irq(&mapping->tree_lock); | 311 | } else { |
304 | if (!expected) | 312 | page->mapping = NULL; |
305 | error = radix_tree_insert(&mapping->page_tree, | 313 | spin_unlock_irq(&mapping->tree_lock); |
306 | index, page); | 314 | page_cache_release(page); |
307 | else | ||
308 | error = shmem_radix_tree_replace(mapping, index, | ||
309 | expected, page); | ||
310 | if (!error) { | ||
311 | mapping->nrpages++; | ||
312 | __inc_zone_page_state(page, NR_FILE_PAGES); | ||
313 | __inc_zone_page_state(page, NR_SHMEM); | ||
314 | spin_unlock_irq(&mapping->tree_lock); | ||
315 | } else { | ||
316 | page->mapping = NULL; | ||
317 | spin_unlock_irq(&mapping->tree_lock); | ||
318 | page_cache_release(page); | ||
319 | } | ||
320 | if (!expected) | ||
321 | radix_tree_preload_end(); | ||
322 | } | 315 | } |
323 | if (error) | ||
324 | mem_cgroup_uncharge_cache_page(page); | ||
325 | return error; | 316 | return error; |
326 | } | 317 | } |
327 | 318 | ||
@@ -1202,11 +1193,18 @@ repeat: | |||
1202 | __set_page_locked(page); | 1193 | __set_page_locked(page); |
1203 | error = mem_cgroup_cache_charge(page, current->mm, | 1194 | error = mem_cgroup_cache_charge(page, current->mm, |
1204 | gfp & GFP_RECLAIM_MASK); | 1195 | gfp & GFP_RECLAIM_MASK); |
1205 | if (!error) | ||
1206 | error = shmem_add_to_page_cache(page, mapping, index, | ||
1207 | gfp, NULL); | ||
1208 | if (error) | 1196 | if (error) |
1209 | goto decused; | 1197 | goto decused; |
1198 | error = radix_tree_preload(gfp & GFP_RECLAIM_MASK); | ||
1199 | if (!error) { | ||
1200 | error = shmem_add_to_page_cache(page, mapping, index, | ||
1201 | gfp, NULL); | ||
1202 | radix_tree_preload_end(); | ||
1203 | } | ||
1204 | if (error) { | ||
1205 | mem_cgroup_uncharge_cache_page(page); | ||
1206 | goto decused; | ||
1207 | } | ||
1210 | lru_cache_add_anon(page); | 1208 | lru_cache_add_anon(page); |
1211 | 1209 | ||
1212 | spin_lock(&info->lock); | 1210 | spin_lock(&info->lock); |