diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2009-01-07 21:08:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 11:31:08 -0500 |
commit | 14797e2363c2b2f1ce139fd1c5a215e4e05aa1d9 (patch) | |
tree | a56edaa680c7c338a5a3043aa24897d7f668b6c9 /mm/vmscan.c | |
parent | 549927620b04a8f8073ce2ee2a8977f209af2ee5 (diff) |
memcg: add inactive_anon_is_low()
The inactive_anon_is_low() is key component of active/inactive anon
balancing on reclaim. However current inactive_anon_is_low() function
only consider global reclaim.
Therefore, we need following ugly scan_global_lru() condition.
if (lru == LRU_ACTIVE_ANON &&
(!scan_global_lru(sc) || inactive_anon_is_low(zone))) {
shrink_active_list(nr_to_scan, zone, sc, priority, file);
return 0;
it cause that memcg reclaim always deactivate pages when shrink_list() is
called. To make mem_cgroup_inactive_anon_is_low() improve active/inactive
anon balancing of memcgroup.
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: "Pekka Enberg" <penberg@cs.helsinki.fi>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index e2b31a522a66..b2bc06bffcfb 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1310,14 +1310,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
1310 | pagevec_release(&pvec); | 1310 | pagevec_release(&pvec); |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | /** | 1313 | static int inactive_anon_is_low_global(struct zone *zone) |
1314 | * inactive_anon_is_low - check if anonymous pages need to be deactivated | ||
1315 | * @zone: zone to check | ||
1316 | * | ||
1317 | * Returns true if the zone does not have enough inactive anon pages, | ||
1318 | * meaning some active anon pages need to be deactivated. | ||
1319 | */ | ||
1320 | static int inactive_anon_is_low(struct zone *zone) | ||
1321 | { | 1314 | { |
1322 | unsigned long active, inactive; | 1315 | unsigned long active, inactive; |
1323 | 1316 | ||
@@ -1330,6 +1323,25 @@ static int inactive_anon_is_low(struct zone *zone) | |||
1330 | return 0; | 1323 | return 0; |
1331 | } | 1324 | } |
1332 | 1325 | ||
1326 | /** | ||
1327 | * inactive_anon_is_low - check if anonymous pages need to be deactivated | ||
1328 | * @zone: zone to check | ||
1329 | * @sc: scan control of this context | ||
1330 | * | ||
1331 | * Returns true if the zone does not have enough inactive anon pages, | ||
1332 | * meaning some active anon pages need to be deactivated. | ||
1333 | */ | ||
1334 | static int inactive_anon_is_low(struct zone *zone, struct scan_control *sc) | ||
1335 | { | ||
1336 | int low; | ||
1337 | |||
1338 | if (scan_global_lru(sc)) | ||
1339 | low = inactive_anon_is_low_global(zone); | ||
1340 | else | ||
1341 | low = mem_cgroup_inactive_anon_is_low(sc->mem_cgroup, zone); | ||
1342 | return low; | ||
1343 | } | ||
1344 | |||
1333 | static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, | 1345 | static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, |
1334 | struct zone *zone, struct scan_control *sc, int priority) | 1346 | struct zone *zone, struct scan_control *sc, int priority) |
1335 | { | 1347 | { |
@@ -1340,8 +1352,7 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, | |||
1340 | return 0; | 1352 | return 0; |
1341 | } | 1353 | } |
1342 | 1354 | ||
1343 | if (lru == LRU_ACTIVE_ANON && | 1355 | if (lru == LRU_ACTIVE_ANON && inactive_anon_is_low(zone, sc)) { |
1344 | (!scan_global_lru(sc) || inactive_anon_is_low(zone))) { | ||
1345 | shrink_active_list(nr_to_scan, zone, sc, priority, file); | 1356 | shrink_active_list(nr_to_scan, zone, sc, priority, file); |
1346 | return 0; | 1357 | return 0; |
1347 | } | 1358 | } |
@@ -1509,9 +1520,7 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1509 | * Even if we did not try to evict anon pages at all, we want to | 1520 | * Even if we did not try to evict anon pages at all, we want to |
1510 | * rebalance the anon lru active/inactive ratio. | 1521 | * rebalance the anon lru active/inactive ratio. |
1511 | */ | 1522 | */ |
1512 | if (!scan_global_lru(sc) || inactive_anon_is_low(zone)) | 1523 | if (inactive_anon_is_low(zone, sc)) |
1513 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); | ||
1514 | else if (!scan_global_lru(sc)) | ||
1515 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); | 1524 | shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0); |
1516 | 1525 | ||
1517 | throttle_vm_writeout(sc->gfp_mask); | 1526 | throttle_vm_writeout(sc->gfp_mask); |
@@ -1807,7 +1816,7 @@ loop_again: | |||
1807 | * Do some background aging of the anon list, to give | 1816 | * Do some background aging of the anon list, to give |
1808 | * pages a chance to be referenced before reclaiming. | 1817 | * pages a chance to be referenced before reclaiming. |
1809 | */ | 1818 | */ |
1810 | if (inactive_anon_is_low(zone)) | 1819 | if (inactive_anon_is_low(zone, &sc)) |
1811 | shrink_active_list(SWAP_CLUSTER_MAX, zone, | 1820 | shrink_active_list(SWAP_CLUSTER_MAX, zone, |
1812 | &sc, priority, 0); | 1821 | &sc, priority, 0); |
1813 | 1822 | ||