aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2012-07-11 17:02:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-11 19:04:48 -0400
commitb065b4321fa78e83bf8f5b0d79d0b5424b57998b (patch)
tree353111b96469e4499faf8513c039ac9043236443 /mm/shmem.c
parentd189922862e03ce6c7adc1e99d3b94e632dc8e89 (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.c58
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);