Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

arch, mm: consolidate initialization of SPARSE memory model

Every architecture calls sparse_init() during setup_arch() although the
data structures created by sparse_init() are not used until the
initialization of the core MM.

Beside the code duplication, calling sparse_init() from architecture
specific code causes ordering differences of vmemmap and HVO
initialization on different architectures.

Move the call to sparse_init() from architecture specific code to
free_area_init() to ensure that vmemmap and HVO initialization order is
always the same.

Link: https://lkml.kernel.org/r/20260111082105.290734-25-rppt@kernel.org
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Alex Shi <alexs@kernel.org>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: "Borislav Petkov (AMD)" <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Klara Modin <klarasmodin@gmail.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Magnus Lindholm <linmag7@gmail.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Richard Weinberger <richard@nod.at>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Stafford Horne <shorne@gmail.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vineet Gupta <vgupta@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Mike Rapoport (Microsoft) and committed by
Andrew Morton
4267739c d49004c5

+11 -59
-3
Documentation/mm/memory-model.rst
··· 97 97 `mem_section` objects and the number of rows is calculated to fit 98 98 all the memory sections. 99 99 100 - The architecture setup code should call sparse_init() to 101 - initialize the memory sections and the memory maps. 102 - 103 100 With SPARSEMEM there are two possible ways to convert a PFN to the 104 101 corresponding `struct page` - a "classic sparse" and "sparse 105 102 vmemmap". The selection is made at build time and it is determined by
-2
Documentation/translations/zh_CN/mm/memory-model.rst
··· 83 83 每一行包含价值 `PAGE_SIZE` 的 `mem_section` 对象,行数的计算是为了适应所有的 84 84 内存区。 85 85 86 - 架构设置代码应该调用sparse_init()来初始化内存区和内存映射。 87 - 88 86 通过SPARSEMEM,有两种可能的方式将PFN转换为相应的 `struct page` --"classic sparse"和 89 87 "sparse vmemmap"。选择是在构建时进行的,它由 `CONFIG_SPARSEMEM_VMEMMAP` 的 90 88 值决定。
-1
arch/alpha/kernel/setup.c
··· 607 607 /* Find our memory. */ 608 608 setup_memory(kernel_end); 609 609 memblock_set_bottom_up(true); 610 - sparse_init(); 611 610 612 611 /* First guess at cpu cache sizes. Do this before init_arch. */ 613 612 determine_cpu_caches(cpu->type);
-6
arch/arm/mm/init.c
··· 207 207 208 208 early_memtest((phys_addr_t)min_low_pfn << PAGE_SHIFT, 209 209 (phys_addr_t)max_low_pfn << PAGE_SHIFT); 210 - 211 - /* 212 - * sparse_init() tries to allocate memory from memblock, so must be 213 - * done after the fixed reservations 214 - */ 215 - sparse_init(); 216 210 } 217 211 218 212 /*
-6
arch/arm64/mm/init.c
··· 321 321 #endif 322 322 323 323 kvm_hyp_reserve(); 324 - 325 - /* 326 - * sparse_init() tries to allocate memory from memblock, so must be 327 - * done after the fixed reservations 328 - */ 329 - sparse_init(); 330 324 dma_limits_init(); 331 325 332 326 /*
-2
arch/csky/kernel/setup.c
··· 123 123 setup_smp(); 124 124 #endif 125 125 126 - sparse_init(); 127 - 128 126 fixaddr_init(); 129 127 130 128 #ifdef CONFIG_HIGHMEM
-8
arch/loongarch/kernel/setup.c
··· 402 402 403 403 check_kernel_sections_mem(); 404 404 405 - /* 406 - * In order to reduce the possibility of kernel panic when failed to 407 - * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate 408 - * low memory as small as possible before swiotlb_init(), so make 409 - * sparse_init() using top-down allocation. 410 - */ 411 - memblock_set_bottom_up(false); 412 - sparse_init(); 413 405 memblock_set_bottom_up(true); 414 406 415 407 swiotlb_init(true, SWIOTLB_VERBOSE);
-11
arch/mips/kernel/setup.c
··· 614 614 * kernel but generic memory management system is still entirely uninitialized. 615 615 * 616 616 * o bootmem_init() 617 - * o sparse_init() 618 617 * o paging_init() 619 618 * o dma_contiguous_reserve() 620 619 * ··· 663 664 664 665 mips_parse_crashkernel(); 665 666 device_tree_init(); 666 - 667 - /* 668 - * In order to reduce the possibility of kernel panic when failed to 669 - * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate 670 - * low memory as small as possible before plat_swiotlb_setup(), so 671 - * make sparse_init() using top-down allocation. 672 - */ 673 - memblock_set_bottom_up(false); 674 - sparse_init(); 675 - memblock_set_bottom_up(true); 676 667 677 668 plat_swiotlb_setup(); 678 669
-2
arch/parisc/mm/init.c
··· 706 706 fixmap_init(); 707 707 flush_cache_all_local(); /* start with known state */ 708 708 flush_tlb_all_local(NULL); 709 - 710 - sparse_init(); 711 709 } 712 710 713 711 static void alloc_btlb(unsigned long start, unsigned long end, int *slot,
+4
arch/powerpc/include/asm/setup.h
··· 20 20 21 21 void check_for_initrd(void); 22 22 void mem_topology_setup(void); 23 + #ifdef CONFIG_NUMA 23 24 void initmem_init(void); 25 + #else 26 + static inline void initmem_init(void) {} 27 + #endif 24 28 void setup_panic(void); 25 29 #define ARCH_PANIC_TIMEOUT 180 26 30
-5
arch/powerpc/mm/mem.c
··· 182 182 memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); 183 183 } 184 184 185 - void __init initmem_init(void) 186 - { 187 - sparse_init(); 188 - } 189 - 190 185 /* mark pages that don't exist as nosave */ 191 186 static int __init mark_nonram_nosave(void) 192 187 {
-2
arch/powerpc/mm/numa.c
··· 1213 1213 setup_node_data(nid, start_pfn, end_pfn); 1214 1214 } 1215 1215 1216 - sparse_init(); 1217 - 1218 1216 /* 1219 1217 * We need the numa_cpu_lookup_table to be accurate for all CPUs, 1220 1218 * even before we online them, so that we can use cpu_to_{node,mem}
-1
arch/riscv/mm/init.c
··· 1430 1430 { 1431 1431 early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); 1432 1432 arch_numa_init(); 1433 - sparse_init(); 1434 1433 #ifdef CONFIG_SPARSEMEM_VMEMMAP 1435 1434 /* The entire VMEMMAP region has been populated. Flush TLB for this region */ 1436 1435 local_flush_tlb_kernel_range(VMEMMAP_START, VMEMMAP_END);
-1
arch/s390/mm/init.c
··· 98 98 void __init paging_init(void) 99 99 { 100 100 vmem_map_init(); 101 - sparse_init(); 102 101 zone_dma_limit = DMA_BIT_MASK(31); 103 102 } 104 103
-2
arch/sh/mm/init.c
··· 227 227 node_set_online(0); 228 228 229 229 plat_mem_setup(); 230 - 231 - sparse_init(); 232 230 } 233 231 234 232 static void __init early_reserve_mem(void)
-2
arch/sparc/mm/init_64.c
··· 1615 1615 1616 1616 /* XXX cpu notifier XXX */ 1617 1617 1618 - sparse_init(); 1619 - 1620 1618 return end_pfn; 1621 1619 } 1622 1620
-1
arch/x86/mm/init_32.c
··· 654 654 * NOTE: at this point the bootmem allocator is fully available. 655 655 */ 656 656 olpc_dt_build_devicetree(); 657 - sparse_init(); 658 657 } 659 658 660 659 /*
-2
arch/x86/mm/init_64.c
··· 833 833 834 834 void __init paging_init(void) 835 835 { 836 - sparse_init(); 837 - 838 836 /* 839 837 * clear the default setting with node 0 840 838 * note: don't use nodes_clear here, that is really clearing when
-2
include/linux/mmzone.h
··· 2286 2286 #define pfn_to_nid(pfn) (0) 2287 2287 #endif 2288 2288 2289 - void sparse_init(void); 2290 2289 #else 2291 - #define sparse_init() do {} while (0) 2292 2290 #define sparse_index_init(_sec, _nid) do {} while (0) 2293 2291 #define sparse_vmemmap_init_nid_early(_nid) do {} while (0) 2294 2292 #define sparse_vmemmap_init_nid_late(_nid) do {} while (0)
+6
mm/internal.h
··· 852 852 unsigned long, enum meminit_context, struct vmem_altmap *, int, 853 853 bool); 854 854 855 + #ifdef CONFIG_SPARSEMEM 856 + void sparse_init(void); 857 + #else 858 + static inline void sparse_init(void) {} 859 + #endif /* CONFIG_SPARSEMEM */ 860 + 855 861 #if defined CONFIG_COMPACTION || defined CONFIG_CMA 856 862 857 863 /*
+1
mm/mm_init.c
··· 1825 1825 bool descending; 1826 1826 1827 1827 arch_zone_limits_init(max_zone_pfn); 1828 + sparse_init(); 1828 1829 1829 1830 start_pfn = PHYS_PFN(memblock_start_of_DRAM()); 1830 1831 descending = arch_has_descending_max_zone_pfns();