diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 197 |
1 files changed, 125 insertions, 72 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index b07c48b09a93..9a27c44aa327 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -125,11 +125,30 @@ static LIST_HEAD(shrinker_list); | |||
125 | static DECLARE_RWSEM(shrinker_rwsem); | 125 | static DECLARE_RWSEM(shrinker_rwsem); |
126 | 126 | ||
127 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | 127 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
128 | #define scan_global_lru(sc) (!(sc)->mem_cgroup) | 128 | #define scanning_global_lru(sc) (!(sc)->mem_cgroup) |
129 | #else | 129 | #else |
130 | #define scan_global_lru(sc) (1) | 130 | #define scanning_global_lru(sc) (1) |
131 | #endif | 131 | #endif |
132 | 132 | ||
133 | static struct zone_reclaim_stat *get_reclaim_stat(struct zone *zone, | ||
134 | struct scan_control *sc) | ||
135 | { | ||
136 | if (!scanning_global_lru(sc)) | ||
137 | return mem_cgroup_get_reclaim_stat(sc->mem_cgroup, zone); | ||
138 | |||
139 | return &zone->reclaim_stat; | ||
140 | } | ||
141 | |||
142 | static unsigned long zone_nr_pages(struct zone *zone, struct scan_control *sc, | ||
143 | enum lru_list lru) | ||
144 | { | ||
145 | if (!scanning_global_lru(sc)) | ||
146 | return mem_cgroup_zone_nr_pages(sc->mem_cgroup, zone, lru); | ||
147 | |||
148 | return zone_page_state(zone, NR_LRU_BASE + lru); | ||
149 | } | ||
150 | |||
151 | |||
133 | /* | 152 | /* |
134 | * Add a shrinker callback to be called from the vm | 153 | * Add a shrinker callback to be called from the vm |
135 | */ | 154 | */ |
@@ -512,7 +531,6 @@ redo: | |||
512 | lru = LRU_UNEVICTABLE; | 531 | lru = LRU_UNEVICTABLE; |
513 | add_page_to_unevictable_list(page); | 532 | add_page_to_unevictable_list(page); |
514 | } | 533 | } |
515 | mem_cgroup_move_lists(page, lru); | ||
516 | 534 | ||
517 | /* | 535 | /* |
518 | * page's status can change while we move it among lru. If an evictable | 536 | * page's status can change while we move it among lru. If an evictable |
@@ -547,7 +565,6 @@ void putback_lru_page(struct page *page) | |||
547 | 565 | ||
548 | lru = !!TestClearPageActive(page) + page_is_file_cache(page); | 566 | lru = !!TestClearPageActive(page) + page_is_file_cache(page); |
549 | lru_cache_add_lru(page, lru); | 567 | lru_cache_add_lru(page, lru); |
550 | mem_cgroup_move_lists(page, lru); | ||
551 | put_page(page); | 568 | put_page(page); |
552 | } | 569 | } |
553 | #endif /* CONFIG_UNEVICTABLE_LRU */ | 570 | #endif /* CONFIG_UNEVICTABLE_LRU */ |
@@ -813,6 +830,7 @@ int __isolate_lru_page(struct page *page, int mode, int file) | |||
813 | return ret; | 830 | return ret; |
814 | 831 | ||
815 | ret = -EBUSY; | 832 | ret = -EBUSY; |
833 | |||
816 | if (likely(get_page_unless_zero(page))) { | 834 | if (likely(get_page_unless_zero(page))) { |
817 | /* | 835 | /* |
818 | * Be careful not to clear PageLRU until after we're | 836 | * Be careful not to clear PageLRU until after we're |
@@ -821,6 +839,7 @@ int __isolate_lru_page(struct page *page, int mode, int file) | |||
821 | */ | 839 | */ |
822 | ClearPageLRU(page); | 840 | ClearPageLRU(page); |
823 | ret = 0; | 841 | ret = 0; |
842 | mem_cgroup_del_lru(page); | ||
824 | } | 843 | } |
825 | 844 | ||
826 | return ret; | 845 | return ret; |
@@ -1029,6 +1048,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1029 | struct pagevec pvec; | 1048 | struct pagevec pvec; |
1030 | unsigned long nr_scanned = 0; | 1049 | unsigned long nr_scanned = 0; |
1031 | unsigned long nr_reclaimed = 0; | 1050 | unsigned long nr_reclaimed = 0; |
1051 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | ||
1032 | 1052 | ||
1033 | pagevec_init(&pvec, 1); | 1053 | pagevec_init(&pvec, 1); |
1034 | 1054 | ||
@@ -1070,13 +1090,14 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1070 | __mod_zone_page_state(zone, NR_INACTIVE_ANON, | 1090 | __mod_zone_page_state(zone, NR_INACTIVE_ANON, |
1071 | -count[LRU_INACTIVE_ANON]); | 1091 | -count[LRU_INACTIVE_ANON]); |
1072 | 1092 | ||
1073 | if (scan_global_lru(sc)) { | 1093 | if (scanning_global_lru(sc)) |
1074 | zone->pages_scanned += nr_scan; | 1094 | zone->pages_scanned += nr_scan; |
1075 | zone->recent_scanned[0] += count[LRU_INACTIVE_ANON]; | 1095 | |
1076 | zone->recent_scanned[0] += count[LRU_ACTIVE_ANON]; | 1096 | reclaim_stat->recent_scanned[0] += count[LRU_INACTIVE_ANON]; |
1077 | zone->recent_scanned[1] += count[LRU_INACTIVE_FILE]; | 1097 | reclaim_stat->recent_scanned[0] += count[LRU_ACTIVE_ANON]; |
1078 | zone->recent_scanned[1] += count[LRU_ACTIVE_FILE]; | 1098 | reclaim_stat->recent_scanned[1] += count[LRU_INACTIVE_FILE]; |
1079 | } | 1099 | reclaim_stat->recent_scanned[1] += count[LRU_ACTIVE_FILE]; |
1100 | |||
1080 | spin_unlock_irq(&zone->lru_lock); | 1101 | spin_unlock_irq(&zone->lru_lock); |
1081 | 1102 | ||
1082 | nr_scanned += nr_scan; | 1103 | nr_scanned += nr_scan; |
@@ -1108,7 +1129,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1108 | if (current_is_kswapd()) { | 1129 | if (current_is_kswapd()) { |
1109 | __count_zone_vm_events(PGSCAN_KSWAPD, zone, nr_scan); | 1130 | __count_zone_vm_events(PGSCAN_KSWAPD, zone, nr_scan); |
1110 | __count_vm_events(KSWAPD_STEAL, nr_freed); | 1131 | __count_vm_events(KSWAPD_STEAL, nr_freed); |
1111 | } else if (scan_global_lru(sc)) | 1132 | } else if (scanning_global_lru(sc)) |
1112 | __count_zone_vm_events(PGSCAN_DIRECT, zone, nr_scan); | 1133 | __count_zone_vm_events(PGSCAN_DIRECT, zone, nr_scan); |
1113 | 1134 | ||
1114 | __count_zone_vm_events(PGSTEAL, zone, nr_freed); | 1135 | __count_zone_vm_events(PGSTEAL, zone, nr_freed); |
@@ -1134,10 +1155,9 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
1134 | SetPageLRU(page); | 1155 | SetPageLRU(page); |
1135 | lru = page_lru(page); | 1156 | lru = page_lru(page); |
1136 | add_page_to_lru_list(zone, page, lru); | 1157 | add_page_to_lru_list(zone, page, lru); |
1137 | mem_cgroup_move_lists(page, lru); | 1158 | if (PageActive(page)) { |
1138 | if (PageActive(page) && scan_global_lru(sc)) { | ||
1139 | int file = !!page_is_file_cache(page); | 1159 | int file = !!page_is_file_cache(page); |
1140 | zone->recent_rotated[file]++; | 1160 | reclaim_stat->recent_rotated[file]++; |
1141 | } | 1161 | } |
1142 | if (!pagevec_add(&pvec, page)) { | 1162 | if (!pagevec_add(&pvec, page)) { |
1143 | spin_unlock_irq(&zone->lru_lock); | 1163 | spin_unlock_irq(&zone->lru_lock); |
@@ -1197,6 +1217,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1197 | struct page *page; | 1217 | struct page *page; |
1198 | struct pagevec pvec; | 1218 | struct pagevec pvec; |
1199 | enum lru_list lru; | 1219 | enum lru_list lru; |
1220 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | ||
1200 | 1221 | ||
1201 | lru_add_drain(); | 1222 | lru_add_drain(); |
1202 | spin_lock_irq(&zone->lru_lock); | 1223 | spin_lock_irq(&zone->lru_lock); |
@@ -1207,10 +1228,10 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1207 | * zone->pages_scanned is used for detect zone's oom | 1228 | * zone->pages_scanned is used for detect zone's oom |
1208 | * mem_cgroup remembers nr_scan by itself. | 1229 | * mem_cgroup remembers nr_scan by itself. |
1209 | */ | 1230 | */ |
1210 | if (scan_global_lru(sc)) { | 1231 | if (scanning_global_lru(sc)) { |
1211 | zone->pages_scanned += pgscanned; | 1232 | zone->pages_scanned += pgscanned; |
1212 | zone->recent_scanned[!!file] += pgmoved; | ||
1213 | } | 1233 | } |
1234 | reclaim_stat->recent_scanned[!!file] += pgmoved; | ||
1214 | 1235 | ||
1215 | if (file) | 1236 | if (file) |
1216 | __mod_zone_page_state(zone, NR_ACTIVE_FILE, -pgmoved); | 1237 | __mod_zone_page_state(zone, NR_ACTIVE_FILE, -pgmoved); |
@@ -1251,8 +1272,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1251 | * This helps balance scan pressure between file and anonymous | 1272 | * This helps balance scan pressure between file and anonymous |
1252 | * pages in get_scan_ratio. | 1273 | * pages in get_scan_ratio. |
1253 | */ | 1274 | */ |
1254 | if (scan_global_lru(sc)) | 1275 | reclaim_stat->recent_rotated[!!file] += pgmoved; |
1255 | zone->recent_rotated[!!file] += pgmoved; | ||
1256 | 1276 | ||
1257 | while (!list_empty(&l_inactive)) { | 1277 | while (!list_empty(&l_inactive)) { |
1258 | page = lru_to_page(&l_inactive); | 1278 | page = lru_to_page(&l_inactive); |
@@ -1263,7 +1283,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1263 | ClearPageActive(page); | 1283 | ClearPageActive(page); |
1264 | 1284 | ||
1265 | list_move(&page->lru, &zone->lru[lru].list); | 1285 | list_move(&page->lru, &zone->lru[lru].list); |
1266 | mem_cgroup_move_lists(page, lru); | 1286 | mem_cgroup_add_lru_list(page, lru); |
1267 | pgmoved++; | 1287 | pgmoved++; |
1268 | if (!pagevec_add(&pvec, page)) { | 1288 | if (!pagevec_add(&pvec, page)) { |
1269 | __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved); | 1289 | __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved); |
@@ -1292,6 +1312,38 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1292 | pagevec_release(&pvec); | 1312 | pagevec_release(&pvec); |
1293 | } | 1313 | } |
1294 | 1314 | ||
1315 | static int inactive_anon_is_low_global(struct zone *zone) | ||
1316 | { | ||
1317 | unsigned long active, inactive; | ||
1318 | |||
1319 | active = zone_page_state(zone, NR_ACTIVE_ANON); | ||
1320 | inactive = zone_page_state(zone, NR_INACTIVE_ANON); | ||
1321 | |||
1322 | if (inactive * zone->inactive_ratio < active) | ||
1323 | return 1; | ||
1324 | |||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | /** | ||
1329 | * inactive_anon_is_low - check if anonymous pages need to be deactivated | ||
1330 | * @zone: zone to check | ||
1331 | * @sc: scan control of this context | ||
1332 | * | ||
1333 | * Returns true if the zone does not have enough inactive anon pages, | ||
1334 | * meaning some active anon pages need to be deactivated. | ||
1335 | */ | ||
1336 | static int inactive_anon_is_low(struct zone *zone, struct scan_control *sc) | ||
1337 | { | ||
1338 | int low; | ||
1339 | |||
1340 | if (scanning_global_lru(sc)) | ||
1341 | low = inactive_anon_is_low_global(zone); | ||
1342 | else | ||
1343 | low = mem_cgroup_inactive_anon_is_low(sc->mem_cgroup); | ||
1344 | return low; | ||
1345 | } | ||
1346 | |||
1295 | static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, | 1347 | static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, |
1296 | struct zone *zone, struct scan_control *sc, int priority) | 1348 | struct zone *zone, struct scan_control *sc, int priority) |
1297 | { | 1349 | { |
@@ -1302,8 +1354,7 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, | |||
1302 | return 0; | 1354 | return 0; |
1303 | } | 1355 | } |
1304 | 1356 | ||
1305 | if (lru == LRU_ACTIVE_ANON && | 1357 | if (lru == LRU_ACTIVE_ANON && inactive_anon_is_low(zone, sc)) { |
1306 | (!scan_global_lru(sc) || inactive_anon_is_low(zone))) { | ||
1307 | shrink_active_list(nr_to_scan, zone, sc, priority, file); | 1358 | shrink_active_list(nr_to_scan, zone, sc, priority, file); |
1308 | return 0; | 1359 | return 0; |
1309 | } | 1360 | } |
@@ -1325,6 +1376,7 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1325 | unsigned long anon, file, free; | 1376 | unsigned long anon, file, free; |
1326 | unsigned long anon_prio, file_prio; | 1377 | unsigned long anon_prio, file_prio; |
1327 | unsigned long ap, fp; | 1378 | unsigned long ap, fp; |
1379 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | ||
1328 | 1380 | ||
1329 | /* If we have no swap space, do not bother scanning anon pages. */ | 1381 | /* If we have no swap space, do not bother scanning anon pages. */ |
1330 | if (nr_swap_pages <= 0) { | 1382 | if (nr_swap_pages <= 0) { |
@@ -1333,17 +1385,20 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1333 | return; | 1385 | return; |
1334 | } | 1386 | } |
1335 | 1387 | ||
1336 | anon = zone_page_state(zone, NR_ACTIVE_ANON) + | 1388 | anon = zone_nr_pages(zone, sc, LRU_ACTIVE_ANON) + |
1337 | zone_page_state(zone, NR_INACTIVE_ANON); | 1389 | zone_nr_pages(zone, sc, LRU_INACTIVE_ANON); |
1338 | file = zone_page_state(zone, NR_ACTIVE_FILE) + | 1390 | file = zone_nr_pages(zone, sc, LRU_ACTIVE_FILE) + |
1339 | zone_page_state(zone, NR_INACTIVE_FILE); | 1391 | zone_nr_pages(zone, sc, LRU_INACTIVE_FILE); |
1340 | free = zone_page_state(zone, NR_FREE_PAGES); | 1392 | |
1341 | 1393 | if (scanning_global_lru(sc)) { | |
1342 | /* If we have very few page cache pages, force-scan anon pages. */ | 1394 | free = zone_page_state(zone, NR_FREE_PAGES); |
1343 | if (unlikely(file + free <= zone->pages_high)) { | 1395 | /* If we have very few page cache pages, |
1344 | percent[0] = 100; | 1396 | force-scan anon pages. */ |
1345 | percent[1] = 0; | 1397 | if (unlikely(file + free <= zone->pages_high)) { |
1346 | return; | 1398 | percent[0] = 100; |
1399 | percent[1] = 0; | ||
1400 | return; | ||
1401 | } | ||
1347 | } | 1402 | } |
1348 | 1403 | ||
1349 | /* | 1404 | /* |
@@ -1357,17 +1412,17 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1357 | * | 1412 | * |
1358 | * anon in [0], file in [1] | 1413 | * anon in [0], file in [1] |
1359 | */ | 1414 | */ |
1360 | if (unlikely(zone->recent_scanned[0] > anon / 4)) { | 1415 | if (unlikely(reclaim_stat->recent_scanned[0] > anon / 4)) { |
1361 | spin_lock_irq(&zone->lru_lock); | 1416 | spin_lock_irq(&zone->lru_lock); |
1362 | zone->recent_scanned[0] /= 2; | 1417 | reclaim_stat->recent_scanned[0] /= 2; |
1363 | zone->recent_rotated[0] /= 2; | 1418 | reclaim_stat->recent_rotated[0] /= 2; |
1364 | spin_unlock_irq(&zone->lru_lock); | 1419 | spin_unlock_irq(&zone->lru_lock); |
1365 | } | 1420 | } |
1366 | 1421 | ||
1367 | if (unlikely(zone->recent_scanned[1] > file / 4)) { | 1422 | if (unlikely(reclaim_stat->recent_scanned[1] > file / 4)) { |
1368 | spin_lock_irq(&zone->lru_lock); | 1423 | spin_lock_irq(&zone->lru_lock); |
1369 | zone->recent_scanned[1] /= 2; | 1424 | reclaim_stat->recent_scanned[1] /= 2; |
1370 | zone->recent_rotated[1] /= 2; | 1425 | reclaim_stat->recent_rotated[1] /= 2; |
1371 | spin_unlock_irq(&zone->lru_lock); | 1426 | spin_unlock_irq(&zone->lru_lock); |
1372 | } | 1427 | } |
1373 | 1428 | ||
@@ -1383,11 +1438,11 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1383 | * proportional to the fraction of recently scanned pages on | 1438 | * proportional to the fraction of recently scanned pages on |
1384 | * each list that were recently referenced and in active use. | 1439 | * each list that were recently referenced and in active use. |
1385 | */ | 1440 | */ |
1386 | ap = (anon_prio + 1) * (zone->recent_scanned[0] + 1); | 1441 | ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1); |
1387 | ap /= zone->recent_rotated[0] + 1; | 1442 | ap /= reclaim_stat->recent_rotated[0] + 1; |
1388 | 1443 | ||
1389 | fp = (file_prio + 1) * (zone->recent_scanned[1] + 1); | 1444 | fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1); |
1390 | fp /= zone->recent_rotated[1] + 1; | 1445 | fp /= reclaim_stat->recent_rotated[1] + 1; |
1391 | 1446 | ||
1392 | /* Normalize to percentages */ | 1447 | /* Normalize to percentages */ |
1393 | percent[0] = 100 * ap / (ap + fp + 1); | 1448 | percent[0] = 100 * ap / (ap + fp + 1); |
@@ -1411,30 +1466,23 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1411 | get_scan_ratio(zone, sc, percent); | 1466 | get_scan_ratio(zone, sc, percent); |
1412 | 1467 | ||
1413 | for_each_evictable_lru(l) { | 1468 | for_each_evictable_lru(l) { |
1414 | if (scan_global_lru(sc)) { | 1469 | int file = is_file_lru(l); |
1415 | int file = is_file_lru(l); | 1470 | int scan; |
1416 | int scan; | 1471 | |
1417 | 1472 | scan = zone_page_state(zone, NR_LRU_BASE + l); | |
1418 | scan = zone_page_state(zone, NR_LRU_BASE + l); | 1473 | if (priority) { |
1419 | if (priority) { | 1474 | scan >>= priority; |
1420 | scan >>= priority; | 1475 | scan = (scan * percent[file]) / 100; |
1421 | scan = (scan * percent[file]) / 100; | 1476 | } |
1422 | } | 1477 | if (scanning_global_lru(sc)) { |
1423 | zone->lru[l].nr_scan += scan; | 1478 | zone->lru[l].nr_scan += scan; |
1424 | nr[l] = zone->lru[l].nr_scan; | 1479 | nr[l] = zone->lru[l].nr_scan; |
1425 | if (nr[l] >= swap_cluster_max) | 1480 | if (nr[l] >= swap_cluster_max) |
1426 | zone->lru[l].nr_scan = 0; | 1481 | zone->lru[l].nr_scan = 0; |
1427 | else | 1482 | else |
1428 | nr[l] = 0; | 1483 | nr[l] = 0; |
1429 | } else { | 1484 | } else |
1430 | /* | 1485 | nr[l] = scan; |
1431 | * This reclaim occurs not because zone memory shortage | ||
1432 | * but because memory controller hits its limit. | ||
1433 | * Don't modify zone reclaim related data. | ||
1434 | */ | ||
1435 | nr[l] = mem_cgroup_calc_reclaim(sc->mem_cgroup, zone, | ||
1436 | priority, l); | ||
1437 | } | ||
1438 | } | 1486 | } |
1439 | 1487 | ||
1440 | while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || | 1488 | while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || |
@@ -1467,9 +1515,7 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1467 | * Even if we did not try to evict anon pages at all, we want to | 1515 | * Even if we did not try to evict anon pages at all, we want to |
1468 | * rebalance the anon lru active/inactive ratio. | 1516 | * rebalance the anon lru active/inactive ratio. |
1469 | */ | 1517 | */ |
1470 | if (!scan_global_lru(sc) || inactive_anon_is_low(zone)) | 1518 | if (inactive_anon_is_low(zone, sc)) |
1471 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); | ||
1472 | else if (!scan_global_lru(sc)) | ||
1473 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); | 1519 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); |
1474 | 1520 | ||
1475 | throttle_vm_writeout(sc->gfp_mask); | 1521 | throttle_vm_writeout(sc->gfp_mask); |
@@ -1504,7 +1550,7 @@ static void shrink_zones(int priority, struct zonelist *zonelist, | |||
1504 | * Take care memory controller reclaiming has small influence | 1550 | * Take care memory controller reclaiming has small influence |
1505 | * to global LRU. | 1551 | * to global LRU. |
1506 | */ | 1552 | */ |
1507 | if (scan_global_lru(sc)) { | 1553 | if (scanning_global_lru(sc)) { |
1508 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | 1554 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) |
1509 | continue; | 1555 | continue; |
1510 | note_zone_scanning_priority(zone, priority); | 1556 | note_zone_scanning_priority(zone, priority); |
@@ -1557,12 +1603,12 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1557 | 1603 | ||
1558 | delayacct_freepages_start(); | 1604 | delayacct_freepages_start(); |
1559 | 1605 | ||
1560 | if (scan_global_lru(sc)) | 1606 | if (scanning_global_lru(sc)) |
1561 | count_vm_event(ALLOCSTALL); | 1607 | count_vm_event(ALLOCSTALL); |
1562 | /* | 1608 | /* |
1563 | * mem_cgroup will not do shrink_slab. | 1609 | * mem_cgroup will not do shrink_slab. |
1564 | */ | 1610 | */ |
1565 | if (scan_global_lru(sc)) { | 1611 | if (scanning_global_lru(sc)) { |
1566 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { | 1612 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { |
1567 | 1613 | ||
1568 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | 1614 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) |
@@ -1581,7 +1627,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1581 | * Don't shrink slabs when reclaiming memory from | 1627 | * Don't shrink slabs when reclaiming memory from |
1582 | * over limit cgroups | 1628 | * over limit cgroups |
1583 | */ | 1629 | */ |
1584 | if (scan_global_lru(sc)) { | 1630 | if (scanning_global_lru(sc)) { |
1585 | shrink_slab(sc->nr_scanned, sc->gfp_mask, lru_pages); | 1631 | shrink_slab(sc->nr_scanned, sc->gfp_mask, lru_pages); |
1586 | if (reclaim_state) { | 1632 | if (reclaim_state) { |
1587 | sc->nr_reclaimed += reclaim_state->reclaimed_slab; | 1633 | sc->nr_reclaimed += reclaim_state->reclaimed_slab; |
@@ -1612,7 +1658,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1612 | congestion_wait(WRITE, HZ/10); | 1658 | congestion_wait(WRITE, HZ/10); |
1613 | } | 1659 | } |
1614 | /* top priority shrink_zones still had more to do? don't OOM, then */ | 1660 | /* top priority shrink_zones still had more to do? don't OOM, then */ |
1615 | if (!sc->all_unreclaimable && scan_global_lru(sc)) | 1661 | if (!sc->all_unreclaimable && scanning_global_lru(sc)) |
1616 | ret = sc->nr_reclaimed; | 1662 | ret = sc->nr_reclaimed; |
1617 | out: | 1663 | out: |
1618 | /* | 1664 | /* |
@@ -1625,7 +1671,7 @@ out: | |||
1625 | if (priority < 0) | 1671 | if (priority < 0) |
1626 | priority = 0; | 1672 | priority = 0; |
1627 | 1673 | ||
1628 | if (scan_global_lru(sc)) { | 1674 | if (scanning_global_lru(sc)) { |
1629 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { | 1675 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { |
1630 | 1676 | ||
1631 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | 1677 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) |
@@ -1661,19 +1707,24 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, | |||
1661 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | 1707 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
1662 | 1708 | ||
1663 | unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, | 1709 | unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, |
1664 | gfp_t gfp_mask) | 1710 | gfp_t gfp_mask, |
1711 | bool noswap, | ||
1712 | unsigned int swappiness) | ||
1665 | { | 1713 | { |
1666 | struct scan_control sc = { | 1714 | struct scan_control sc = { |
1667 | .may_writepage = !laptop_mode, | 1715 | .may_writepage = !laptop_mode, |
1668 | .may_swap = 1, | 1716 | .may_swap = 1, |
1669 | .swap_cluster_max = SWAP_CLUSTER_MAX, | 1717 | .swap_cluster_max = SWAP_CLUSTER_MAX, |
1670 | .swappiness = vm_swappiness, | 1718 | .swappiness = swappiness, |
1671 | .order = 0, | 1719 | .order = 0, |
1672 | .mem_cgroup = mem_cont, | 1720 | .mem_cgroup = mem_cont, |
1673 | .isolate_pages = mem_cgroup_isolate_pages, | 1721 | .isolate_pages = mem_cgroup_isolate_pages, |
1674 | }; | 1722 | }; |
1675 | struct zonelist *zonelist; | 1723 | struct zonelist *zonelist; |
1676 | 1724 | ||
1725 | if (noswap) | ||
1726 | sc.may_swap = 0; | ||
1727 | |||
1677 | sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | | 1728 | sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | |
1678 | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); | 1729 | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); |
1679 | zonelist = NODE_DATA(numa_node_id())->node_zonelists; | 1730 | zonelist = NODE_DATA(numa_node_id())->node_zonelists; |
@@ -1761,7 +1812,7 @@ loop_again: | |||
1761 | * Do some background aging of the anon list, to give | 1812 | * Do some background aging of the anon list, to give |
1762 | * pages a chance to be referenced before reclaiming. | 1813 | * pages a chance to be referenced before reclaiming. |
1763 | */ | 1814 | */ |
1764 | if (inactive_anon_is_low(zone)) | 1815 | if (inactive_anon_is_low(zone, &sc)) |
1765 | shrink_active_list(SWAP_CLUSTER_MAX, zone, | 1816 | shrink_active_list(SWAP_CLUSTER_MAX, zone, |
1766 | &sc, priority, 0); | 1817 | &sc, priority, 0); |
1767 | 1818 | ||
@@ -2404,6 +2455,7 @@ retry: | |||
2404 | 2455 | ||
2405 | __dec_zone_state(zone, NR_UNEVICTABLE); | 2456 | __dec_zone_state(zone, NR_UNEVICTABLE); |
2406 | list_move(&page->lru, &zone->lru[l].list); | 2457 | list_move(&page->lru, &zone->lru[l].list); |
2458 | mem_cgroup_move_lists(page, LRU_UNEVICTABLE, l); | ||
2407 | __inc_zone_state(zone, NR_INACTIVE_ANON + l); | 2459 | __inc_zone_state(zone, NR_INACTIVE_ANON + l); |
2408 | __count_vm_event(UNEVICTABLE_PGRESCUED); | 2460 | __count_vm_event(UNEVICTABLE_PGRESCUED); |
2409 | } else { | 2461 | } else { |
@@ -2412,6 +2464,7 @@ retry: | |||
2412 | */ | 2464 | */ |
2413 | SetPageUnevictable(page); | 2465 | SetPageUnevictable(page); |
2414 | list_move(&page->lru, &zone->lru[LRU_UNEVICTABLE].list); | 2466 | list_move(&page->lru, &zone->lru[LRU_UNEVICTABLE].list); |
2467 | mem_cgroup_rotate_lru_list(page, LRU_UNEVICTABLE); | ||
2415 | if (page_evictable(page, NULL)) | 2468 | if (page_evictable(page, NULL)) |
2416 | goto retry; | 2469 | goto retry; |
2417 | } | 2470 | } |