[RFC PATCH 1/8] mm, compaction: don't mark pageblocks unsuitable when not fully scanned

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Compaction migration scanner marks a pageblock as unsuitable (via pageblock
skip bit) if it fails to isolate any pages in them. When scanning for async
direct compaction, it skips all pages of a order-aligned block once a page
fails isolation, because a single page is enough to prevent forming a free page
of given order. But the skipped pages might still be migratable and form a free
page of a lower order. Therefore we should not mark pageblock unsuitable, if
skipping has happened. The worst example would be a THP allocation attempt
marking pageblock unsuitable due to a single page, so the following lower-order
and more critical allocation will skip the pageblock.

Signed-off-by: Vlastimil Babka <vbabka@xxxxxxx>
---
 mm/compaction.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index b8c23882c8ae..ce73badad464 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -698,7 +698,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
 	bool locked = false;
 	struct page *page = NULL, *valid_page = NULL;
 	unsigned long start_pfn = low_pfn;
-	bool skip_on_failure = false;
+	bool skip_on_failure = false, skipped_pages = false;
 	unsigned long next_skip_pfn = 0;
 
 	/*
@@ -920,13 +920,14 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
 			nr_isolated = 0;
 		}
 
-		if (low_pfn < next_skip_pfn) {
+		if (low_pfn < next_skip_pfn - 1) {
 			low_pfn = next_skip_pfn - 1;
 			/*
 			 * The check near the loop beginning would have updated
 			 * next_skip_pfn too, but this is a bit simpler.
 			 */
 			next_skip_pfn += 1UL << cc->order;
+			skipped_pages = true;
 		}
 	}
 
@@ -944,7 +945,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
 	 * Update the pageblock-skip information and cached scanner pfn,
 	 * if the whole pageblock was scanned without isolating any page.
 	 */
-	if (low_pfn == end_pfn)
+	if (low_pfn == end_pfn && !skipped_pages)
 		update_pageblock_skip(cc, valid_page, nr_isolated, true);
 
 	trace_mm_compaction_isolate_migratepages(start_pfn, low_pfn,
-- 
2.15.1

--
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>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]
  Powered by Linux