mm/mm_init: add zone mismatch warning during page init

For vmemmap-optimized sections, tail struct pages may be backed by shared
vmemmap pages.  Those shared pages must carry the same page zone ID as the
struct pages initialized for the section.

Warn in __init_single_page() if the shared tail page has a different
page_zone_id(), which would indicate inconsistent initialization.

[muchun.song@linux.dev: document ordering of shared and retained struct page initialization]
  Link: https://lore.kernel.org/20261010115523.4005071-1-songmuchun@bytedance.com
Link: https://lore.kernel.org/20261010075755.83339-7-songmuchun@bytedance.com
Signed-off-by: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Acked-by: Qi Zheng <qi.zheng@linux.dev>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <chleroy@kernel.org>
Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Cc: Shrikanth Hegde <sshegde@linux.ibm.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
This commit is contained in:
Muchun Song 2026-10-10 15:57:55 +08:00 committed by Andrew Morton
parent cc1fd8f401
commit 3d670c0dce

View File

@ -593,6 +593,15 @@ static void __init find_zone_movable_pfns_for_nodes(void)
node_states[N_MEMORY] = saved_node_state;
}
static inline void vmemmap_optimization_verify_zone(struct page *page)
{
const unsigned int order = pfn_to_section_compound_order(page_to_pfn(page));
VM_WARN_ON_ONCE(vmemmap_optimizable_order(order) &&
page_zone_id(page + VMEMMAP_OPTIMIZATION_NR_STRUCT_PAGES) !=
page_zone_id(page));
}
void __meminit __init_single_page(struct page *page, unsigned long pfn,
unsigned long zone, int nid)
{
@ -609,6 +618,11 @@ void __meminit __init_single_page(struct page *page, unsigned long pfn,
if (!is_highmem_idx(zone))
set_page_address(page, __va(pfn << PAGE_SHIFT));
#endif
/*
* Shared tail struct pages are initialized during vmemmap population,
* before retained struct pages reach here.
*/
vmemmap_optimization_verify_zone(page);
}
#ifdef CONFIG_NUMA