|
@@ -897,6 +897,16 @@ static bool suitable_migration_target(struct page *page)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Test whether the free scanner has reached the same or lower pageblock than
|
|
|
+ * the migration scanner, and compaction should thus terminate.
|
|
|
+ */
|
|
|
+static inline bool compact_scanners_met(struct compact_control *cc)
|
|
|
+{
|
|
|
+ return (cc->free_pfn >> pageblock_order)
|
|
|
+ <= (cc->migrate_pfn >> pageblock_order);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Based on information in the current compact_control, find blocks
|
|
|
* suitable for isolating free pages from and then isolate them.
|
|
@@ -1127,12 +1137,8 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
|
|
|
}
|
|
|
|
|
|
acct_isolated(zone, cc);
|
|
|
- /*
|
|
|
- * Record where migration scanner will be restarted. If we end up in
|
|
|
- * the same pageblock as the free scanner, make the scanners fully
|
|
|
- * meet so that compact_finished() terminates compaction.
|
|
|
- */
|
|
|
- cc->migrate_pfn = (end_pfn <= cc->free_pfn) ? low_pfn : cc->free_pfn;
|
|
|
+ /* Record where migration scanner will be restarted. */
|
|
|
+ cc->migrate_pfn = low_pfn;
|
|
|
|
|
|
return cc->nr_migratepages ? ISOLATE_SUCCESS : ISOLATE_NONE;
|
|
|
}
|
|
@@ -1147,7 +1153,7 @@ static int __compact_finished(struct zone *zone, struct compact_control *cc,
|
|
|
return COMPACT_PARTIAL;
|
|
|
|
|
|
/* Compaction run completes if the migrate and free scanner meet */
|
|
|
- if (cc->free_pfn <= cc->migrate_pfn) {
|
|
|
+ if (compact_scanners_met(cc)) {
|
|
|
/* Let the next compaction start anew. */
|
|
|
zone->compact_cached_migrate_pfn[0] = zone->zone_start_pfn;
|
|
|
zone->compact_cached_migrate_pfn[1] = zone->zone_start_pfn;
|
|
@@ -1376,7 +1382,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
|
|
|
* migrate_pages() may return -ENOMEM when scanners meet
|
|
|
* and we want compact_finished() to detect it
|
|
|
*/
|
|
|
- if (err == -ENOMEM && cc->free_pfn > cc->migrate_pfn) {
|
|
|
+ if (err == -ENOMEM && !compact_scanners_met(cc)) {
|
|
|
ret = COMPACT_PARTIAL;
|
|
|
goto out;
|
|
|
}
|