Skip to content

Commit 493614d

Browse files
hnazakpm00
authored andcommitted
mm: compaction: fix endless looping over same migrate block
During stress testing, the following situation was observed: 70 root 39 19 0 0 0 R 100.0 0.0 959:29.92 khugepaged 310936 root 20 0 84416 25620 512 R 99.7 1.5 642:37.22 hugealloc Tracing shows isolate_migratepages_block() endlessly looping over the first block in the DMA zone: hugealloc-310936 [001] ..... 237297.415718: mm_compaction_finished: node=0 zone=DMA order=9 ret=no_suitable_page hugealloc-310936 [001] ..... 237297.415718: mm_compaction_isolate_migratepages: range=(0x1 ~ 0x400) nr_scanned=513 nr_taken=0 hugealloc-310936 [001] ..... 237297.415718: mm_compaction_finished: node=0 zone=DMA order=9 ret=no_suitable_page hugealloc-310936 [001] ..... 237297.415718: mm_compaction_isolate_migratepages: range=(0x1 ~ 0x400) nr_scanned=513 nr_taken=0 hugealloc-310936 [001] ..... 237297.415718: mm_compaction_finished: node=0 zone=DMA order=9 ret=no_suitable_page hugealloc-310936 [001] ..... 237297.415718: mm_compaction_isolate_migratepages: range=(0x1 ~ 0x400) nr_scanned=513 nr_taken=0 hugealloc-310936 [001] ..... 237297.415718: mm_compaction_finished: node=0 zone=DMA order=9 ret=no_suitable_page hugealloc-310936 [001] ..... 237297.415718: mm_compaction_isolate_migratepages: range=(0x1 ~ 0x400) nr_scanned=513 nr_taken=0 The problem is that the functions tries to test and set the skip bit once on the block, to avoid skipping on its own skip-set, using pageblock_aligned() on the pfn as a test. But because this is the DMA zone which starts at pfn 1, this is never true for the first block, and the skip bit isn't set or tested at all. As a result, fast_find_migrateblock() returns the same pageblock over and over. If the pfn isn't pageblock-aligned, also check if it's the start of the zone to ensure test-and-set-exactly-once on unaligned ranges. Thanks to Vlastimil Babka for the help in debugging this. Link: https://lkml.kernel.org/r/[email protected] Fixes: 90ed667 ("Revert "Revert "mm/compaction: fix set skip in fast_find_migrateblock""") Signed-off-by: Johannes Weiner <[email protected]> Reviewed-by: Vlastimil Babka <[email protected]> Acked-by: Mel Gorman <[email protected]> Reviewed-by: Baolin Wang <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 65294de commit 493614d

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

mm/compaction.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -912,11 +912,12 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
912912

913913
/*
914914
* Check if the pageblock has already been marked skipped.
915-
* Only the aligned PFN is checked as the caller isolates
915+
* Only the first PFN is checked as the caller isolates
916916
* COMPACT_CLUSTER_MAX at a time so the second call must
917917
* not falsely conclude that the block should be skipped.
918918
*/
919-
if (!valid_page && pageblock_aligned(low_pfn)) {
919+
if (!valid_page && (pageblock_aligned(low_pfn) ||
920+
low_pfn == cc->zone->zone_start_pfn)) {
920921
if (!isolation_suitable(cc, page)) {
921922
low_pfn = end_pfn;
922923
folio = NULL;
@@ -2002,7 +2003,8 @@ static isolate_migrate_t isolate_migratepages(struct compact_control *cc)
20022003
* before making it "skip" so other compaction instances do
20032004
* not scan the same block.
20042005
*/
2005-
if (pageblock_aligned(low_pfn) &&
2006+
if ((pageblock_aligned(low_pfn) ||
2007+
low_pfn == cc->zone->zone_start_pfn) &&
20062008
!fast_find_block && !isolation_suitable(cc, page))
20072009
continue;
20082010

0 commit comments

Comments
 (0)