When isolating free pages as miration targets in __isolate_free_page(), compaction respects the min watermark. Although it checks that there's enough free pages above the watermark in __compaction_suitable() before starting to compact, parallel allocation may result in their depletion. Compaction will detect this only after needlessly scanning many pages for migration, potentially wasting CPU time. After this patch, we check if we are still above the watermark in __compact_finished(). For kcompactd, we check the low watermark instead of min watermark, because that's the point when kswapd is woken up and it's better to let kswapd finish freeing memory before doing kcompactd work. Signed-off-by: Vlastimil Babka <vbabka@xxxxxxx> --- mm/compaction.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mm/compaction.c b/mm/compaction.c index 613c59e928cb..6647359dc8e3 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1291,6 +1291,7 @@ static enum compact_result __compact_finished(struct zone *zone, { unsigned int order; const int migratetype = cc->migratetype; + unsigned long watermark; if (cc->contended || fatal_signal_pending(current)) return COMPACT_CONTENDED; @@ -1374,6 +1375,23 @@ static enum compact_result __compact_finished(struct zone *zone, } } + /* + * It's possible that the number of free pages has dropped below + * watermark during our compaction, and __isolate_free_page() would fail. + * In that case, let's stop now and not waste time searching for migrate + * pages. + * For direct compaction, the check is close to the one in + * __isolate_free_page(). For kcompactd, we use the low watermark, + * because that's the point when kswapd gets woken up, so it's better + * for kcompactd to let kswapd free memory first. + */ + if (cc->direct_compaction) + watermark = min_wmark_pages(zone); + else + watermark = low_wmark_pages(zone); + if (!zone_watermark_ok(zone, 0, watermark, 0, ALLOC_CMA)) + return COMPACT_PARTIAL_SKIPPED; + return COMPACT_NO_SUITABLE_PAGE; } -- 2.13.3 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>