aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 0f246c44a574..85bed948fafc 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -912,9 +912,13 @@ found:
912 error = 1; 912 error = 1;
913 if (!inode) 913 if (!inode)
914 goto out; 914 goto out;
915 error = radix_tree_preload(GFP_KERNEL); 915 /* Precharge page while we can wait, compensate afterwards */
916 error = mem_cgroup_cache_charge(page, current->mm, GFP_KERNEL);
916 if (error) 917 if (error)
917 goto out; 918 goto out;
919 error = radix_tree_preload(GFP_KERNEL);
920 if (error)
921 goto uncharge;
918 error = 1; 922 error = 1;
919 923
920 spin_lock(&info->lock); 924 spin_lock(&info->lock);
@@ -947,6 +951,8 @@ found:
947 shmem_swp_unmap(ptr); 951 shmem_swp_unmap(ptr);
948 spin_unlock(&info->lock); 952 spin_unlock(&info->lock);
949 radix_tree_preload_end(); 953 radix_tree_preload_end();
954uncharge:
955 mem_cgroup_uncharge_page(page);
950out: 956out:
951 unlock_page(page); 957 unlock_page(page);
952 page_cache_release(page); 958 page_cache_release(page);
@@ -1308,6 +1314,13 @@ repeat:
1308 spin_unlock(&info->lock); 1314 spin_unlock(&info->lock);
1309 unlock_page(swappage); 1315 unlock_page(swappage);
1310 page_cache_release(swappage); 1316 page_cache_release(swappage);
1317 if (error == -ENOMEM) {
1318 /* allow reclaim from this memory cgroup */
1319 error = mem_cgroup_cache_charge(NULL,
1320 current->mm, gfp & ~__GFP_HIGHMEM);
1321 if (error)
1322 goto failed;
1323 }
1311 goto repeat; 1324 goto repeat;
1312 } 1325 }
1313 } else if (sgp == SGP_READ && !filepage) { 1326 } else if (sgp == SGP_READ && !filepage) {
@@ -1353,6 +1366,17 @@ repeat:
1353 goto failed; 1366 goto failed;
1354 } 1367 }
1355 1368
1369 /* Precharge page while we can wait, compensate after */
1370 error = mem_cgroup_cache_charge(filepage, current->mm,
1371 gfp & ~__GFP_HIGHMEM);
1372 if (error) {
1373 page_cache_release(filepage);
1374 shmem_unacct_blocks(info->flags, 1);
1375 shmem_free_blocks(inode, 1);
1376 filepage = NULL;
1377 goto failed;
1378 }
1379
1356 spin_lock(&info->lock); 1380 spin_lock(&info->lock);
1357 entry = shmem_swp_alloc(info, idx, sgp); 1381 entry = shmem_swp_alloc(info, idx, sgp);
1358 if (IS_ERR(entry)) 1382 if (IS_ERR(entry))
@@ -1364,6 +1388,7 @@ repeat:
1364 if (error || swap.val || 0 != add_to_page_cache_lru( 1388 if (error || swap.val || 0 != add_to_page_cache_lru(
1365 filepage, mapping, idx, GFP_NOWAIT)) { 1389 filepage, mapping, idx, GFP_NOWAIT)) {
1366 spin_unlock(&info->lock); 1390 spin_unlock(&info->lock);
1391 mem_cgroup_uncharge_page(filepage);
1367 page_cache_release(filepage); 1392 page_cache_release(filepage);
1368 shmem_unacct_blocks(info->flags, 1); 1393 shmem_unacct_blocks(info->flags, 1);
1369 shmem_free_blocks(inode, 1); 1394 shmem_free_blocks(inode, 1);
@@ -1372,6 +1397,7 @@ repeat:
1372 goto failed; 1397 goto failed;
1373 goto repeat; 1398 goto repeat;
1374 } 1399 }
1400 mem_cgroup_uncharge_page(filepage);
1375 info->flags |= SHMEM_PAGEIN; 1401 info->flags |= SHMEM_PAGEIN;
1376 } 1402 }
1377 1403