Commit b39415b2 authored by Rik van Riel's avatar Rik van Riel Committed by Linus Torvalds

vmscan: do not evict inactive pages when skipping an active list scan

In AIM7 runs, recent kernels start swapping out anonymous pages well
before they should.  This is due to shrink_list falling through to
shrink_inactive_list if !inactive_anon_is_low(zone, sc), when all we
really wanted to do is pre-age some anonymous pages to give them extra
time to be referenced while on the inactive list.

The obvious fix is to make sure that shrink_list does not fall through to
scanning/reclaiming inactive pages when we called it to scan one of the
active lists.

This change should be safe because the loop in shrink_zone ensures that we
will still shrink the anon and file inactive lists whenever we should.

[kosaki.motohiro@jp.fujitsu.com: inactive_file_is_low() should be inactive_anon_is_low()]
Reported-by: default avatarLarry Woodman <lwoodman@redhat.com>
Signed-off-by: default avatarRik van Riel <riel@redhat.com>
Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Cc: Tomasz Chmielewski <mangoo@wpkg.org>
Signed-off-by: default avatarKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8aa043d7
...@@ -1463,20 +1463,26 @@ static int inactive_file_is_low(struct zone *zone, struct scan_control *sc) ...@@ -1463,20 +1463,26 @@ static int inactive_file_is_low(struct zone *zone, struct scan_control *sc)
return low; return low;
} }
static int inactive_list_is_low(struct zone *zone, struct scan_control *sc,
int file)
{
if (file)
return inactive_file_is_low(zone, sc);
else
return inactive_anon_is_low(zone, sc);
}
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
struct zone *zone, struct scan_control *sc, int priority) struct zone *zone, struct scan_control *sc, int priority)
{ {
int file = is_file_lru(lru); int file = is_file_lru(lru);
if (lru == LRU_ACTIVE_FILE && inactive_file_is_low(zone, sc)) { if (is_active_lru(lru)) {
shrink_active_list(nr_to_scan, zone, sc, priority, file); if (inactive_list_is_low(zone, sc, file))
shrink_active_list(nr_to_scan, zone, sc, priority, file);
return 0; return 0;
} }
if (lru == LRU_ACTIVE_ANON && inactive_anon_is_low(zone, sc)) {
shrink_active_list(nr_to_scan, zone, sc, priority, file);
return 0;
}
return shrink_inactive_list(nr_to_scan, zone, sc, priority, file); return shrink_inactive_list(nr_to_scan, zone, sc, priority, file);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment