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

mm, compaction: ignore fragindex from compaction_zonelist_suitable()

The compaction_zonelist_suitable() function tries to determine if
compaction will be able to proceed after sufficient reclaim, i.e.
whether there are enough reclaimable pages to provide enough order-0
freepages for compaction.

This addition of reclaimable pages to the free pages works well for the
order-0 watermark check, but in the fragmentation index check we only
consider truly free pages.  Thus we can get fragindex value close to 0
which indicates failure do to lack of memory, and wrongly decide that
compaction won't be suitable even after reclaim.

Instead of trying to somehow adjust fragindex for reclaimable pages,
let's just skip it from compaction_zonelist_suitable().

Link: http://lkml.kernel.org/r/20160926162025.21555-4-vbabka@suse.czSigned-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
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 423b452e
...@@ -1379,7 +1379,6 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order, ...@@ -1379,7 +1379,6 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order,
int classzone_idx, int classzone_idx,
unsigned long wmark_target) unsigned long wmark_target)
{ {
int fragindex;
unsigned long watermark; unsigned long watermark;
if (is_via_compact_memory(order)) if (is_via_compact_memory(order))
...@@ -1415,6 +1414,18 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order, ...@@ -1415,6 +1414,18 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order,
ALLOC_CMA, wmark_target)) ALLOC_CMA, wmark_target))
return COMPACT_SKIPPED; return COMPACT_SKIPPED;
return COMPACT_CONTINUE;
}
enum compact_result compaction_suitable(struct zone *zone, int order,
unsigned int alloc_flags,
int classzone_idx)
{
enum compact_result ret;
int fragindex;
ret = __compaction_suitable(zone, order, alloc_flags, classzone_idx,
zone_page_state(zone, NR_FREE_PAGES));
/* /*
* fragmentation index determines if allocation failures are due to * fragmentation index determines if allocation failures are due to
* low memory or external fragmentation * low memory or external fragmentation
...@@ -1426,21 +1437,12 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order, ...@@ -1426,21 +1437,12 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order,
* *
* Only compact if a failure would be due to fragmentation. * Only compact if a failure would be due to fragmentation.
*/ */
fragindex = fragmentation_index(zone, order); if (ret == COMPACT_CONTINUE) {
if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold) fragindex = fragmentation_index(zone, order);
return COMPACT_NOT_SUITABLE_ZONE; if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold)
ret = COMPACT_NOT_SUITABLE_ZONE;
return COMPACT_CONTINUE; }
}
enum compact_result compaction_suitable(struct zone *zone, int order,
unsigned int alloc_flags,
int classzone_idx)
{
enum compact_result ret;
ret = __compaction_suitable(zone, order, alloc_flags, classzone_idx,
zone_page_state(zone, NR_FREE_PAGES));
trace_mm_compaction_suitable(zone, order, ret); trace_mm_compaction_suitable(zone, order, ret);
if (ret == COMPACT_NOT_SUITABLE_ZONE) if (ret == COMPACT_NOT_SUITABLE_ZONE)
ret = COMPACT_SKIPPED; ret = COMPACT_SKIPPED;
...@@ -1473,8 +1475,7 @@ bool compaction_zonelist_suitable(struct alloc_context *ac, int order, ...@@ -1473,8 +1475,7 @@ bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
available += zone_page_state_snapshot(zone, NR_FREE_PAGES); available += zone_page_state_snapshot(zone, NR_FREE_PAGES);
compact_result = __compaction_suitable(zone, order, alloc_flags, compact_result = __compaction_suitable(zone, order, alloc_flags,
ac_classzone_idx(ac), available); ac_classzone_idx(ac), available);
if (compact_result != COMPACT_SKIPPED && if (compact_result != COMPACT_SKIPPED)
compact_result != COMPACT_NOT_SUITABLE_ZONE)
return true; return true;
} }
......
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