|
@@ -660,7 +660,7 @@ static void isolate_freepages(struct zone *zone,
|
|
|
* is the end of the pageblock the migration scanner is using.
|
|
|
*/
|
|
|
pfn = cc->free_pfn;
|
|
|
- low_pfn = cc->migrate_pfn + pageblock_nr_pages;
|
|
|
+ low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages);
|
|
|
|
|
|
/*
|
|
|
* Take care that if the migration scanner is at the end of the zone
|
|
@@ -676,7 +676,7 @@ static void isolate_freepages(struct zone *zone,
|
|
|
* pages on cc->migratepages. We stop searching if the migrate
|
|
|
* and free page scanners meet or enough free pages are isolated.
|
|
|
*/
|
|
|
- for (; pfn > low_pfn && cc->nr_migratepages > nr_freepages;
|
|
|
+ for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
|
|
|
pfn -= pageblock_nr_pages) {
|
|
|
unsigned long isolated;
|
|
|
|
|
@@ -738,7 +738,14 @@ static void isolate_freepages(struct zone *zone,
|
|
|
/* split_free_page does not map the pages */
|
|
|
map_pages(freelist);
|
|
|
|
|
|
- cc->free_pfn = high_pfn;
|
|
|
+ /*
|
|
|
+ * If we crossed the migrate scanner, we want to keep it that way
|
|
|
+ * so that compact_finished() may detect this
|
|
|
+ */
|
|
|
+ if (pfn < low_pfn)
|
|
|
+ cc->free_pfn = max(pfn, zone->zone_start_pfn);
|
|
|
+ else
|
|
|
+ cc->free_pfn = high_pfn;
|
|
|
cc->nr_freepages = nr_freepages;
|
|
|
}
|
|
|
|
|
@@ -1005,7 +1012,11 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
|
|
|
if (err) {
|
|
|
putback_movable_pages(&cc->migratepages);
|
|
|
cc->nr_migratepages = 0;
|
|
|
- if (err == -ENOMEM) {
|
|
|
+ /*
|
|
|
+ * 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) {
|
|
|
ret = COMPACT_PARTIAL;
|
|
|
goto out;
|
|
|
}
|