[PATCH v2 5/5] mm/page_alloc: remove the zone_spans_pfn() check from get_pfnblock_bitmap_bitidx()

From: Vlastimil Babka (SUSE)

Date: Tue Nov 03 2026 - 11:44:39 EST


Whenever the flags of a pageblock are read or written, a kernel with
CONFIG_DEBUG_VM makes sure that the pfn lies within the zone of the page.
Unlike bad_range(), that check reads zone->zone_start_pfn and
zone->spanned_pages without zone->span_seqlock.

Memory hotplug changes the two fields one after the other. If the lower
end of a zone moves, the zone seems to end before its last pages in
between. A page of that part which is freed at that moment, on another
CPU, ends in

page dumped because: VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn))
kernel BUG at mm/page_alloc.c:372!
free_unref_folios+0x55e/0xed0
folios_put_refs+0x2b5/0x530

An attempt has been made [1] to fix this with the span seqlock check.
But that can trigger all sorts of problems in restricted contexts, as
noted by sashiko [2].

Since this is just a sanity debug check and anything with BUG_ON is
frowned upon anyway, just remove it altogether.

Reported-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Closes: https://lore.kernel.org/all/20261027-pgalloc-ai-hotfixes-v1-9-9c7d1aca801e@xxxxxxxxxx/ [1]
Link: https://lore.kernel.org/all/sashiko-outbox-188081@xxxxxxxxxx/ [2]
Fixes: 86051ca5eaf5 ("mm: fix usemap initialization")
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>
---
mm/page_alloc.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 41fd80c0c762..3a7b9b533368 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -370,7 +370,6 @@ get_pfnblock_bitmap_bitidx(const struct page *page, unsigned long pfn,
BUILD_BUG_ON(NR_PAGEBLOCK_BITS != 4);
#endif
BUILD_BUG_ON(__MIGRATE_TYPE_END > PAGEBLOCK_MIGRATETYPE_MASK);
- VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page);

bitmap = get_pageblock_bitmap(page, pfn);
*bitidx = pfn_to_bitidx(page, pfn);

--
2.56.0