On Thu, Mar 21, 2019 at 10:39:10AM +0500, Mikhail Gavrilov wrote: > > # first bad commit: [e332f741a8dd1ec9a6dc8aa997296ecbfe64323e] mm, > > compaction: be selective about what pageblocks to clear skip hints > > > > Also I see that two patches already proposed for fixing this issue. > > [1] https://patchwork.kernel.org/patch/10862267/ > > [2] https://patchwork.kernel.org/patch/10862519/ > > > > If I understand correctly, it is enough to apply only the second patch [2]. > > > > I am right now tested the patch [1] and can said that unfortunately it > not fix my issue. > [1] https://patchwork.kernel.org/patch/10862519/ > Build-tested only but can you try this? diff --git a/mm/compaction.c b/mm/compaction.c index f171a83707ce..ba3afcc00d50 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, bool check_target) { struct page *page = pfn_to_online_page(pfn); + struct page *block_page; struct page *end_page; unsigned long block_pfn; @@ -267,20 +268,26 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source, get_pageblock_migratetype(page) != MIGRATE_MOVABLE) return false; + /* Ensure the start of the pageblock or zone is online and valid */ + block_pfn = pageblock_start_pfn(pfn); + block_page = pfn_to_online_page(max(block_pfn, zone->zone_start_pfn)); + if (block_page) { + page = block_page; + pfn = block_pfn; + } + + /* Ensure the end of the pageblock or zone is online and valid */ + block_pfn += pageblock_nr_pages; + block_pfn = min(block_pfn, zone_end_pfn(zone)); + end_page = pfn_to_online_page(block_pfn); + if (!end_page) + 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)) {