|
@@ -943,8 +943,7 @@ static void isolate_freepages(struct compact_control *cc)
|
|
|
* pages on cc->migratepages. We stop searching if the migrate
|
|
|
* and free page scanners meet or enough free pages are isolated.
|
|
|
*/
|
|
|
- for (; block_start_pfn >= low_pfn &&
|
|
|
- cc->nr_migratepages > cc->nr_freepages;
|
|
|
+ for (; block_start_pfn >= low_pfn;
|
|
|
block_end_pfn = block_start_pfn,
|
|
|
block_start_pfn -= pageblock_nr_pages,
|
|
|
isolate_start_pfn = block_start_pfn) {
|
|
@@ -976,6 +975,8 @@ static void isolate_freepages(struct compact_control *cc)
|
|
|
block_end_pfn, freelist, false);
|
|
|
|
|
|
/*
|
|
|
+ * If we isolated enough freepages, or aborted due to async
|
|
|
+ * compaction being contended, terminate the loop.
|
|
|
* Remember where the free scanner should restart next time,
|
|
|
* which is where isolate_freepages_block() left off.
|
|
|
* But if it scanned the whole pageblock, isolate_start_pfn
|
|
@@ -984,27 +985,31 @@ static void isolate_freepages(struct compact_control *cc)
|
|
|
* In that case we will however want to restart at the start
|
|
|
* of the previous pageblock.
|
|
|
*/
|
|
|
- cc->free_pfn = (isolate_start_pfn < block_end_pfn) ?
|
|
|
- isolate_start_pfn :
|
|
|
- block_start_pfn - pageblock_nr_pages;
|
|
|
-
|
|
|
- /*
|
|
|
- * isolate_freepages_block() might have aborted due to async
|
|
|
- * compaction being contended
|
|
|
- */
|
|
|
- if (cc->contended)
|
|
|
+ if ((cc->nr_freepages >= cc->nr_migratepages)
|
|
|
+ || cc->contended) {
|
|
|
+ if (isolate_start_pfn >= block_end_pfn)
|
|
|
+ isolate_start_pfn =
|
|
|
+ block_start_pfn - pageblock_nr_pages;
|
|
|
break;
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * isolate_freepages_block() should not terminate
|
|
|
+ * prematurely unless contended, or isolated enough
|
|
|
+ */
|
|
|
+ VM_BUG_ON(isolate_start_pfn < block_end_pfn);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* split_free_page does not map the pages */
|
|
|
map_pages(freelist);
|
|
|
|
|
|
/*
|
|
|
- * If we crossed the migrate scanner, we want to keep it that way
|
|
|
- * so that compact_finished() may detect this
|
|
|
+ * Record where the free scanner will restart next time. Either we
|
|
|
+ * broke from the loop and set isolate_start_pfn based on the last
|
|
|
+ * call to isolate_freepages_block(), or we met the migration scanner
|
|
|
+ * and the loop terminated due to isolate_start_pfn < low_pfn
|
|
|
*/
|
|
|
- if (block_start_pfn < low_pfn)
|
|
|
- cc->free_pfn = cc->migrate_pfn;
|
|
|
+ cc->free_pfn = isolate_start_pfn;
|
|
|
}
|
|
|
|
|
|
/*
|