diff options
author | Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> | 2009-06-16 18:33:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 22:47:45 -0400 |
commit | 9198e96c06744517e3b18fce8be6db61e96a3227 (patch) | |
tree | 3d79e58771cc27204980a0350abafaf6e7524447 /mm | |
parent | 3eb4140f0389bdada022d5e8efd88504ad30df14 (diff) |
vmscan: handle may_swap more strictly
Commit 2e2e425989080cc534fc0fca154cae515f971cf5 ("vmscan,memcg:
reintroduce sc->may_swap) add may_swap flag and handle it at
get_scan_ratio().
But the result of get_scan_ratio() is ignored when priority == 0, so anon
lru is scanned even if may_swap == 0 or nr_swap_pages == 0. IMHO, this is
not an expected behavior.
As for memcg especially, because of this behavior many and many pages are
swapped-out just in vain when oom is invoked by mem+swap limit.
This patch is for handling may_swap flag more strictly.
Signed-off-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/vmscan.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index f3a55d1f9ab7..057e44b97aa1 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1430,13 +1430,6 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc, | |||
1430 | unsigned long ap, fp; | 1430 | unsigned long ap, fp; |
1431 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); | 1431 | struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); |
1432 | 1432 | ||
1433 | /* If we have no swap space, do not bother scanning anon pages. */ | ||
1434 | if (!sc->may_swap || (nr_swap_pages <= 0)) { | ||
1435 | percent[0] = 0; | ||
1436 | percent[1] = 100; | ||
1437 | return; | ||
1438 | } | ||
1439 | |||
1440 | anon = zone_nr_pages(zone, sc, LRU_ACTIVE_ANON) + | 1433 | anon = zone_nr_pages(zone, sc, LRU_ACTIVE_ANON) + |
1441 | zone_nr_pages(zone, sc, LRU_INACTIVE_ANON); | 1434 | zone_nr_pages(zone, sc, LRU_INACTIVE_ANON); |
1442 | file = zone_nr_pages(zone, sc, LRU_ACTIVE_FILE) + | 1435 | file = zone_nr_pages(zone, sc, LRU_ACTIVE_FILE) + |
@@ -1534,15 +1527,22 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1534 | enum lru_list l; | 1527 | enum lru_list l; |
1535 | unsigned long nr_reclaimed = sc->nr_reclaimed; | 1528 | unsigned long nr_reclaimed = sc->nr_reclaimed; |
1536 | unsigned long swap_cluster_max = sc->swap_cluster_max; | 1529 | unsigned long swap_cluster_max = sc->swap_cluster_max; |
1530 | int noswap = 0; | ||
1537 | 1531 | ||
1538 | get_scan_ratio(zone, sc, percent); | 1532 | /* If we have no swap space, do not bother scanning anon pages. */ |
1533 | if (!sc->may_swap || (nr_swap_pages <= 0)) { | ||
1534 | noswap = 1; | ||
1535 | percent[0] = 0; | ||
1536 | percent[1] = 100; | ||
1537 | } else | ||
1538 | get_scan_ratio(zone, sc, percent); | ||
1539 | 1539 | ||
1540 | for_each_evictable_lru(l) { | 1540 | for_each_evictable_lru(l) { |
1541 | int file = is_file_lru(l); | 1541 | int file = is_file_lru(l); |
1542 | unsigned long scan; | 1542 | unsigned long scan; |
1543 | 1543 | ||
1544 | scan = zone_nr_pages(zone, sc, l); | 1544 | scan = zone_nr_pages(zone, sc, l); |
1545 | if (priority) { | 1545 | if (priority || noswap) { |
1546 | scan >>= priority; | 1546 | scan >>= priority; |
1547 | scan = (scan * percent[file]) / 100; | 1547 | scan = (scan * percent[file]) / 100; |
1548 | } | 1548 | } |