From 89e2b6e3d345cd4dca822a5ccea764ee7f9e0ae4 Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (Arm)" Date: Mon, 21 Sep 2026 21:58:54 +0200 Subject: [PATCH] mm/sparse: refactor sparse_sections_init() memory_present() really identifies+prepares all early sections so the initialization in sparse_init() can properly iterating them to initialize metadata. Let's just inline memory_present() into sparse_sections_init() and cleaning up the code a bit while at it: make it clear that we are operating on pfns. Note that we call set_section_nid() now only if the section was not already created earlier. Now, there is no more inconsistency between what we (temporarily) store in ms->section_mem_map and what we store in our section->nid array. Link: https://lore.kernel.org/20260921-b4-sparsemem_cleanups-v2-2-54d81d65e125@kernel.org Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Andrew Morton Acked-by: Oscar Salvador Acked-by: Lorenzo Stoakes (ARM) Reviewed-by: Mike Rapoport (Microsoft) Cc: Liam R. Howlett Cc: Vlastimil Babka Cc: Suren Baghdasaryan Cc: Michal Hocko Cc: Kairui Song Cc: Qi Zheng Cc: Shakeel Butt Cc: Barry Song Cc: Axel Rasmussen Cc: Yuanchu Xie Cc: Wei Xu Cc: Baoquan He Cc: Baolin Wang Cc: Brendan Jackman Cc: Johannes Weiner Cc: Zi Yan Cc: Jan Kiszka Cc: Kieran Bingham Cc: Greg Kroah-Hartman Cc: Rafael J. Wysocki Cc: Danilo Krummrich --- mm/sparse.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/mm/sparse.c b/mm/sparse.c index 8cd2b06b231a..2b285653abf1 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -179,40 +179,33 @@ static inline unsigned long first_present_section_nr(void) return next_present_section_nr(-1); } -/* Record a memory area against a node. */ -static void __init memory_present(int nid, unsigned long start, unsigned long end) +void __init sparse_sections_init(void) { - unsigned long pfn; + unsigned long pfn, start_pfn, end_pfn; + int i, nid; - start &= PAGE_SECTION_MASK; - mminit_validate_memmodel_limits(&start, &end); - for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { - unsigned long section_nr = pfn_to_section_nr(pfn); - struct mem_section *ms; + sparse_extreme_init(); - sparse_index_init(section_nr, nid); - set_section_nid(section_nr, nid); + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { + start_pfn &= PAGE_SECTION_MASK; + mminit_validate_memmodel_limits(&start_pfn, &end_pfn); - ms = __nr_to_section(section_nr); - if (!ms->section_mem_map) { + for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { + unsigned long section_nr = pfn_to_section_nr(pfn); + struct mem_section *ms; + + sparse_index_init(section_nr, nid); + ms = __nr_to_section(section_nr); + if (ms->section_mem_map) + continue; + + set_section_nid(section_nr, nid); ms->section_mem_map = sparse_encode_early_nid(nid) | SECTION_IS_ONLINE; __section_mark_present(ms, section_nr); } } } - -void __init sparse_sections_init(void) -{ - unsigned long start, end; - int i, nid; - - sparse_extreme_init(); - - for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid) - memory_present(nid, start, end); -} - #ifndef CONFIG_SPARSEMEM_VMEMMAP struct page __init *__populate_section_memmap(unsigned long pfn, unsigned long nr_pages, int nid, struct vmem_altmap *altmap,