Commit fdd4c614 authored by Vlastimil Babka's avatar Vlastimil Babka Committed by Linus Torvalds

mm, vmscan: make compaction_ready() more accurate and readable

The compaction_ready() is used during direct reclaim for costly order
allocations to skip reclaim for zones where compaction should be
attempted instead.  It's combining the standard compaction_suitable()
check with its own watermark check based on high watermark with extra
gap, and the result is confusing at best.

This patch attempts to better structure and document the checks
involved.  First, compaction_suitable() can determine that the
allocation should either succeed already, or that compaction doesn't
have enough free pages to proceed.  The third possibility is that
compaction has enough free pages, but we still decide to reclaim first -
unless we are already above the high watermark with gap.  This does not
mean that the reclaim will actually reach this watermark during single
attempt, this is rather an over-reclaim protection.  So document the
code as such.  The check for compaction_deferred() is removed
completely, as it in fact had no proper role here.

The result after this patch is mainly a less confusing code.  We also
skip some over-reclaim in cases where the allocation should already
succed.

Link: http://lkml.kernel.org/r/20160810091226.6709-12-vbabka@suse.czSigned-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
Tested-by: default avatarLorenzo Stoakes <lstoakes@gmail.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8348faf9
...@@ -2598,38 +2598,35 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc) ...@@ -2598,38 +2598,35 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc)
} }
/* /*
* Returns true if compaction should go ahead for a high-order request, or * Returns true if compaction should go ahead for a costly-order request, or
* the high-order allocation would succeed without compaction. * the allocation would already succeed without compaction. Return false if we
* should reclaim first.
*/ */
static inline bool compaction_ready(struct zone *zone, struct scan_control *sc) static inline bool compaction_ready(struct zone *zone, struct scan_control *sc)
{ {
unsigned long watermark; unsigned long watermark;
bool watermark_ok; enum compact_result suitable;
/* suitable = compaction_suitable(zone, sc->order, 0, sc->reclaim_idx);
* Compaction takes time to run and there are potentially other if (suitable == COMPACT_SUCCESS)
* callers using the pages just freed. Continue reclaiming until /* Allocation should succeed already. Don't reclaim. */
* there is a buffer of free pages available to give compaction return true;
* a reasonable chance of completing and allocating the page if (suitable == COMPACT_SKIPPED)
*/ /* Compaction cannot yet proceed. Do reclaim. */
watermark = high_wmark_pages(zone) + compact_gap(sc->order); return false;
watermark_ok = zone_watermark_ok_safe(zone, 0, watermark, sc->reclaim_idx);
/*
* If compaction is deferred, reclaim up to a point where
* compaction will have a chance of success when re-enabled
*/
if (compaction_deferred(zone, sc->order))
return watermark_ok;
/* /*
* If compaction is not ready to start and allocation is not likely * Compaction is already possible, but it takes time to run and there
* to succeed without it, then keep reclaiming. * are potentially other callers using the pages just freed. So proceed
* with reclaim to make a buffer of free pages available to give
* compaction a reasonable chance of completing and allocating the page.
* Note that we won't actually reclaim the whole buffer in one attempt
* as the target watermark in should_continue_reclaim() is lower. But if
* we are already above the high+gap watermark, don't reclaim at all.
*/ */
if (compaction_suitable(zone, sc->order, 0, sc->reclaim_idx) == COMPACT_SKIPPED) watermark = high_wmark_pages(zone) + compact_gap(sc->order);
return false;
return watermark_ok; return zone_watermark_ok_safe(zone, 0, watermark, sc->reclaim_idx);
} }
/* /*
......
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