Commit b37d0e59 authored by Mel Gorman's avatar Mel Gorman Committed by Ben Hutchings

mm: vmscan: do not OOM if aborting reclaim to start compaction

commit 7335084d upstream.

Stable note: Not tracked in Bugzilla. This patch makes later patches
	easier to apply but otherwise has little to justify it. The
	problem it fixes was never observed but the source of the
	theoretical problem did not exist for very long.

During direct reclaim it is possible that reclaim will be aborted so that
compaction can be attempted to satisfy a high-order allocation.  If this
decision is made before any pages are reclaimed, it is possible that 0 is
returned to the page allocator potentially triggering an OOM.  This has
not been observed but it is a possibility so this patch addresses it.
Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
Reviewed-by: default avatarRik van Riel <riel@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
Cc: Dave Jones <davej@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Andy Isaacson <adi@hexapodia.org>
Cc: Nai Xia <nai.xia@gmail.com>
Cc: Johannes Weiner <jweiner@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 553ae61f
...@@ -2284,6 +2284,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, ...@@ -2284,6 +2284,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
struct zoneref *z; struct zoneref *z;
struct zone *zone; struct zone *zone;
unsigned long writeback_threshold; unsigned long writeback_threshold;
bool should_abort_reclaim;
get_mems_allowed(); get_mems_allowed();
delayacct_freepages_start(); delayacct_freepages_start();
...@@ -2295,7 +2296,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, ...@@ -2295,7 +2296,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
sc->nr_scanned = 0; sc->nr_scanned = 0;
if (!priority) if (!priority)
disable_swap_token(sc->mem_cgroup); disable_swap_token(sc->mem_cgroup);
if (shrink_zones(priority, zonelist, sc)) should_abort_reclaim = shrink_zones(priority, zonelist, sc);
if (should_abort_reclaim)
break; break;
/* /*
...@@ -2363,6 +2365,10 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, ...@@ -2363,6 +2365,10 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
if (oom_killer_disabled) if (oom_killer_disabled)
return 0; return 0;
/* Aborting reclaim to try compaction? don't OOM, then */
if (should_abort_reclaim)
return 1;
/* top priority shrink_zones still had more to do? don't OOM, then */ /* top priority shrink_zones still had more to do? don't OOM, then */
if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc)) if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc))
return 1; return 1;
......
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