aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/compaction.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index f171a83707ce..b4930bf93c8a 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -242,6 +242,7 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source,
242 bool check_target) 242 bool check_target)
243{ 243{
244 struct page *page = pfn_to_online_page(pfn); 244 struct page *page = pfn_to_online_page(pfn);
245 struct page *block_page;
245 struct page *end_page; 246 struct page *end_page;
246 unsigned long block_pfn; 247 unsigned long block_pfn;
247 248
@@ -267,20 +268,26 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source,
267 get_pageblock_migratetype(page) != MIGRATE_MOVABLE) 268 get_pageblock_migratetype(page) != MIGRATE_MOVABLE)
268 return false; 269 return false;
269 270
271 /* Ensure the start of the pageblock or zone is online and valid */
272 block_pfn = pageblock_start_pfn(pfn);
273 block_page = pfn_to_online_page(max(block_pfn, zone->zone_start_pfn));
274 if (block_page) {
275 page = block_page;
276 pfn = block_pfn;
277 }
278
279 /* Ensure the end of the pageblock or zone is online and valid */
280 block_pfn += pageblock_nr_pages;
281 block_pfn = min(block_pfn, zone_end_pfn(zone) - 1);
282 end_page = pfn_to_online_page(block_pfn);
283 if (!end_page)
284 return false;
285
270 /* 286 /*
271 * Only clear the hint if a sample indicates there is either a 287 * Only clear the hint if a sample indicates there is either a
272 * free page or an LRU page in the block. One or other condition 288 * free page or an LRU page in the block. One or other condition
273 * is necessary for the block to be a migration source/target. 289 * is necessary for the block to be a migration source/target.
274 */ 290 */
275 block_pfn = pageblock_start_pfn(pfn);
276 pfn = max(block_pfn, zone->zone_start_pfn);
277 page = pfn_to_page(pfn);
278 if (zone != page_zone(page))
279 return false;
280 pfn = block_pfn + pageblock_nr_pages;
281 pfn = min(pfn, zone_end_pfn(zone));
282 end_page = pfn_to_page(pfn);
283
284 do { 291 do {
285 if (pfn_valid_within(pfn)) { 292 if (pfn_valid_within(pfn)) {
286 if (check_source && PageLRU(page)) { 293 if (check_source && PageLRU(page)) {
@@ -309,7 +316,7 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source,
309static void __reset_isolation_suitable(struct zone *zone) 316static void __reset_isolation_suitable(struct zone *zone)
310{ 317{
311 unsigned long migrate_pfn = zone->zone_start_pfn; 318 unsigned long migrate_pfn = zone->zone_start_pfn;
312 unsigned long free_pfn = zone_end_pfn(zone); 319 unsigned long free_pfn = zone_end_pfn(zone) - 1;
313 unsigned long reset_migrate = free_pfn; 320 unsigned long reset_migrate = free_pfn;
314 unsigned long reset_free = migrate_pfn; 321 unsigned long reset_free = migrate_pfn;
315 bool source_set = false; 322 bool source_set = false;