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

mm, compaction: use correct watermark when checking compaction success

The __compact_finished() function uses low watermark in a check that has
to pass if the direct compaction is to finish and allocation should
succeed.  This is too pessimistic, as the allocation will typically use
min watermark.  It may happen that during compaction, we drop below the
low watermark (due to parallel activity), but still form the target
high-order page.  By checking against low watermark, we might needlessly
continue compaction.

Similarly, __compaction_suitable() uses low watermark in a check whether
allocation can succeed without compaction.  Again, this is unnecessarily
pessimistic.

After this patch, these check will use direct compactor's alloc_flags to
determine the watermark, which is effectively the min watermark.

Link: http://lkml.kernel.org/r/20160810091226.6709-8-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 a8e025e5
...@@ -1316,7 +1316,7 @@ static enum compact_result __compact_finished(struct zone *zone, struct compact_ ...@@ -1316,7 +1316,7 @@ static enum compact_result __compact_finished(struct zone *zone, struct compact_
return COMPACT_CONTINUE; return COMPACT_CONTINUE;
/* Compaction run is not finished if the watermark is not met */ /* Compaction run is not finished if the watermark is not met */
watermark = low_wmark_pages(zone); watermark = zone->watermark[cc->alloc_flags & ALLOC_WMARK_MASK];
if (!zone_watermark_ok(zone, cc->order, watermark, cc->classzone_idx, if (!zone_watermark_ok(zone, cc->order, watermark, cc->classzone_idx,
cc->alloc_flags)) cc->alloc_flags))
...@@ -1381,7 +1381,7 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order, ...@@ -1381,7 +1381,7 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order,
if (is_via_compact_memory(order)) if (is_via_compact_memory(order))
return COMPACT_CONTINUE; return COMPACT_CONTINUE;
watermark = low_wmark_pages(zone); watermark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK];
/* /*
* If watermarks for high-order allocation are already met, there * If watermarks for high-order allocation are already met, there
* should be no need for compaction at all. * should be no need for compaction at all.
...@@ -1395,7 +1395,7 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order, ...@@ -1395,7 +1395,7 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order,
* This is because during migration, copies of pages need to be * This is because during migration, copies of pages need to be
* allocated and for a short time, the footprint is higher * allocated and for a short time, the footprint is higher
*/ */
watermark += (2UL << order); watermark = low_wmark_pages(zone) + (2UL << order);
if (!__zone_watermark_ok(zone, 0, watermark, classzone_idx, if (!__zone_watermark_ok(zone, 0, watermark, classzone_idx,
alloc_flags, wmark_target)) alloc_flags, wmark_target))
return COMPACT_SKIPPED; return COMPACT_SKIPPED;
......
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