summaryrefslogtreecommitdiff
path: root/mm/compaction.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-11-19 05:43:46 +0300
committerJens Axboe <axboe@fb.com>2014-11-19 05:43:46 +0300
commitb3521729769ec71567a2e32a38609f87e781e41b (patch)
tree66a8494968706420c3eb043caa5868702d440d18 /mm/compaction.c
parent139768895309c6c1d6913e909e9c9422f81a1640 (diff)
parentfc14f9c1272f62c3e8d01300f52467c0d9af50f9 (diff)
downloadlinux-b3521729769ec71567a2e32a38609f87e781e41b.tar.xz
Merge branch 'master' into for-3.19/drivers
Diffstat (limited to 'mm/compaction.c')
-rw-r--r--mm/compaction.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index edba18aed173..f9792ba3537c 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -479,6 +479,16 @@ isolate_freepages_range(struct compact_control *cc,
block_end_pfn = min(block_end_pfn, end_pfn);
+ /*
+ * pfn could pass the block_end_pfn if isolated freepage
+ * is more than pageblock order. In this case, we adjust
+ * scanning range to right one.
+ */
+ if (pfn >= block_end_pfn) {
+ block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
+ block_end_pfn = min(block_end_pfn, end_pfn);
+ }
+
if (!pageblock_pfn_to_page(pfn, block_end_pfn, cc->zone))
break;
@@ -784,6 +794,9 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
cc->nr_migratepages = 0;
break;
}
+
+ if (cc->nr_migratepages == COMPACT_CLUSTER_MAX)
+ break;
}
acct_isolated(cc->zone, cc);
@@ -1026,8 +1039,12 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
}
acct_isolated(zone, cc);
- /* Record where migration scanner will be restarted */
- cc->migrate_pfn = low_pfn;
+ /*
+ * 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;
return cc->nr_migratepages ? ISOLATE_SUCCESS : ISOLATE_NONE;
}