diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 70412ab9a706..c4b5c29060aa 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -495,8 +495,6 @@ struct zone { unsigned long compact_cached_free_pfn; /* pfn where async and sync compaction migration scanner should start */ unsigned long compact_cached_migrate_pfn[2]; - unsigned long compact_init_migrate_pfn; - unsigned long compact_init_free_pfn; #endif #ifdef CONFIG_COMPACTION diff --git a/mm/compaction.c b/mm/compaction.c index b8ced23f6c5c..da30406b32fb 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -237,70 +237,6 @@ static bool pageblock_skip_persistent(struct page *page) return false; } -static bool -__reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source, - bool check_target) -{ - struct page *page = pfn_to_online_page(pfn); - struct page *end_page; - unsigned long block_pfn; - - if (!page) - return false; - if (zone != page_zone(page)) - return false; - if (pageblock_skip_persistent(page)) - return false; - - /* - * If skip is already cleared do no further checking once the - * restart points have been set. - */ - if (check_source && check_target && !get_pageblock_skip(page)) - return true; - - /* - * If clearing skip for the target scanner, do not select a - * non-movable pageblock as the starting point. - */ - if (!check_source && check_target && - get_pageblock_migratetype(page) != MIGRATE_MOVABLE) - return false; - - /* - * Only clear the hint if a sample indicates there is either a - * free page or an LRU page in the block. One or other condition - * is necessary for the block to be a migration source/target. - */ - block_pfn = pageblock_start_pfn(pfn); - pfn = max(block_pfn, zone->zone_start_pfn); - page = pfn_to_page(pfn); - if (zone != page_zone(page)) - return false; - pfn = block_pfn + pageblock_nr_pages; - pfn = min(pfn, zone_end_pfn(zone)); - end_page = pfn_to_page(pfn); - - do { - if (pfn_valid_within(pfn)) { - if (check_source && PageLRU(page)) { - clear_pageblock_skip(page); - return true; - } - - if (check_target && PageBuddy(page)) { - clear_pageblock_skip(page); - return true; - } - } - - page += (1 << PAGE_ALLOC_COSTLY_ORDER); - pfn += (1 << PAGE_ALLOC_COSTLY_ORDER); - } while (page < end_page); - - return false; -} - /* * This function is called to clear all cached information on pageblocks that * should be skipped for page isolation when the migrate and free page scanner @@ -308,54 +244,30 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source, */ static void __reset_isolation_suitable(struct zone *zone) { - unsigned long migrate_pfn = zone->zone_start_pfn; - unsigned long free_pfn = zone_end_pfn(zone); - unsigned long reset_migrate = free_pfn; - unsigned long reset_free = migrate_pfn; - bool source_set = false; - bool free_set = false; - - if (!zone->compact_blockskip_flush) - return; + unsigned long start_pfn = zone->zone_start_pfn; + unsigned long end_pfn = zone_end_pfn(zone); + unsigned long pfn; zone->compact_blockskip_flush = false; - /* - * Walk the zone and update pageblock skip information. Source looks - * for PageLRU while target looks for PageBuddy. When the scanner - * is found, both PageBuddy and PageLRU are checked as the pageblock - * is suitable as both source and target. - */ - for (; migrate_pfn < free_pfn; migrate_pfn += pageblock_nr_pages, - free_pfn -= pageblock_nr_pages) { + /* Walk the zone and mark every pageblock as suitable for isolation */ + for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { + struct page *page; + cond_resched(); - /* Update the migrate PFN */ - if (__reset_isolation_pfn(zone, migrate_pfn, true, source_set) && - migrate_pfn < reset_migrate) { - source_set = true; - reset_migrate = migrate_pfn; - zone->compact_init_migrate_pfn = reset_migrate; - zone->compact_cached_migrate_pfn[0] = reset_migrate; - zone->compact_cached_migrate_pfn[1] = reset_migrate; - } + page = pfn_to_online_page(pfn); + if (!page) + continue; + if (zone != page_zone(page)) + continue; + if (pageblock_skip_persistent(page)) + continue; - /* Update the free PFN */ - if (__reset_isolation_pfn(zone, free_pfn, free_set, true) && - free_pfn > reset_free) { - free_set = true; - reset_free = free_pfn; - zone->compact_init_free_pfn = reset_free; - zone->compact_cached_free_pfn = reset_free; - } + clear_pageblock_skip(page); } - /* Leave no distance if no suitable block was reset */ - if (reset_migrate >= reset_free) { - zone->compact_cached_migrate_pfn[0] = migrate_pfn; - zone->compact_cached_migrate_pfn[1] = migrate_pfn; - zone->compact_cached_free_pfn = free_pfn; - } + reset_cached_positions(zone); } void reset_isolation_suitable(pg_data_t *pgdat) @@ -1679,7 +1591,7 @@ static enum compact_result compact_zone(struct zone *zone, struct compact_contro zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn; } - if (cc->migrate_pfn <= cc->zone->compact_init_migrate_pfn) + if (cc->migrate_pfn == start_pfn) cc->whole_zone = true; }