From ee6192a2c4321e8cfde0e09131a72ab304e2d4f0 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Fri, 12 Jun 2026 11:58:52 +0800 Subject: [PATCH] mm/mm_init: defer sparse_init() until after zone initialization free_area_init() is responsible for initializing pgdat and zone state. Calling sparse_init() from there mixes in later vmemmap and struct page setup, which makes the initialization flow less clear. Defer sparse_init(), sparse_vmemmap_init_nid_late(), and memmap_init() until after free_area_init() completes, when zone initialization is fully done. This keeps free_area_init() focused on zone setup and ensures that sparse_init() runs with the relevant zone state already available. This is also a prerequisite for later hugetlb vmemmap changes that need zone information during early sparse vmemmap setup. Link: https://lore.kernel.org/20260612035903.2468601-9-songmuchun@bytedance.com Signed-off-by: Muchun Song Reviewed-by: Mike Rapoport (Microsoft) Reviewed-by: Oscar Salvador (SUSE) Cc: "Aneesh Kumar K.V" Cc: David Hildenbrand Cc: Frank van der Linden Cc: Liam R. Howlett Cc: Lorenzo Stoakes Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Oscar Salvador Cc: "Ritesh Harjani (IBM)" Cc: Usama Arif Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- mm/mm_init.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mm/mm_init.c b/mm/mm_init.c index 0394150be24b..bd18862ac30b 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -1821,7 +1821,6 @@ static void __init free_area_init(void) bool descending; arch_zone_limits_init(max_zone_pfn); - sparse_init(); start_pfn = PHYS_PFN(memblock_start_of_DRAM()); descending = arch_has_descending_max_zone_pfns(); @@ -1910,11 +1909,7 @@ static void __init free_area_init(void) } } - for_each_node_state(nid, N_MEMORY) - sparse_vmemmap_init_nid_late(nid); - calc_nr_kernel_pages(); - memmap_init(); /* disable hash distribution for systems with a single node */ fixup_hashdist(); @@ -2686,10 +2681,17 @@ void __init __weak mem_init(void) void __init mm_core_init_early(void) { + int nid; + hugetlb_cma_reserve(); hugetlb_bootmem_alloc(); free_area_init(); + + sparse_init(); + for_each_node_state(nid, N_MEMORY) + sparse_vmemmap_init_nid_late(nid); + memmap_init(); } /*