]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm, arch: consolidate hugetlb CMA reservation
authorMike Rapoport (Microsoft) <rppt@kernel.org>
Sun, 11 Jan 2026 08:21:01 +0000 (10:21 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 27 Jan 2026 04:02:19 +0000 (20:02 -0800)
Every architecture that supports hugetlb_cma command line parameter
reserves CMA areas for hugetlb during setup_arch().

This obfuscates the ordering of hugetlb CMA initialization with respect to
the rest initialization of the core MM.

Introduce arch_hugetlb_cma_order() callback to allow architectures report
the desired order-per-bit of CMA areas and provide a week implementation
of arch_hugetlb_cma_order() for architectures that don't support hugetlb
with CMA.

Use this callback in hugetlb_cma_reserve() instead if passing the order as
parameter and call hugetlb_cma_reserve() from mm_core_init_early() rather
than have it spread over architecture specific code.

Link: https://lkml.kernel.org/r/20260111082105.290734-28-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>
16 files changed:
Documentation/driver-api/cxl/linux/early-boot.rst
arch/arm64/include/asm/hugetlb.h
arch/arm64/mm/hugetlbpage.c
arch/arm64/mm/init.c
arch/powerpc/include/asm/hugetlb.h
arch/powerpc/kernel/setup-common.c
arch/powerpc/mm/hugetlbpage.c
arch/riscv/mm/hugetlbpage.c
arch/riscv/mm/init.c
arch/s390/kernel/setup.c
arch/s390/mm/hugetlbpage.c
arch/x86/kernel/setup.c
arch/x86/mm/hugetlbpage.c
include/linux/hugetlb.h
mm/hugetlb_cma.c
mm/mm_init.c

index a7fc6fc85fbef23eeb6c291568488680efcbd685..414481f33819d1b335a3016ae49bcb0b60f51d9a 100644 (file)
@@ -125,7 +125,7 @@ The contiguous memory allocator (CMA) enables reservation of contiguous memory
 regions on NUMA nodes during early boot.  However, CMA cannot reserve memory
 on NUMA nodes that are not online during early boot. ::
 
-  void __init hugetlb_cma_reserve(int order) {
+  void __init hugetlb_cma_reserve(void) {
     if (!node_online(nid))
       /* do not allow reservations */
   }
index 44c1f757bfcf8e4cf987cbb147de7c55eba25e03..e6f8ff3cc6306e98e513ab107d1ef3c6c352a934 100644 (file)
@@ -56,8 +56,6 @@ extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
 #define __HAVE_ARCH_HUGE_PTEP_GET
 extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
 
-void __init arm64_hugetlb_cma_reserve(void);
-
 #define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
 extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
                                         unsigned long addr, pte_t *ptep);
index 1d90a7e753336d86314fee0f753e8779d6a6bc12..f8dd58ab67a82d6dba1c127813d4830bd0bcb2f0 100644 (file)
  * huge pages could still be served from those areas.
  */
 #ifdef CONFIG_CMA
-void __init arm64_hugetlb_cma_reserve(void)
+unsigned int arch_hugetlb_cma_order(void)
 {
-       int order;
-
        if (pud_sect_supported())
-               order = PUD_SHIFT - PAGE_SHIFT;
-       else
-               order = CONT_PMD_SHIFT - PAGE_SHIFT;
+               return PUD_SHIFT - PAGE_SHIFT;
 
-       hugetlb_cma_reserve(order);
+       return CONT_PMD_SHIFT - PAGE_SHIFT;
 }
 #endif /* CONFIG_CMA */
 
index 9d271aff76526358ca0d68c30c465358a1a69cd5..96711b8578fd066f3aab457e102dea199cfb45ad 100644 (file)
@@ -311,15 +311,6 @@ void __init bootmem_init(void)
 
        arch_numa_init();
 
-       /*
-        * must be done after arch_numa_init() which calls numa_init() to
-        * initialize node_online_map that gets used in hugetlb_cma_reserve()
-        * while allocating required CMA size across online nodes.
-        */
-#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_CMA)
-       arm64_hugetlb_cma_reserve();
-#endif
-
        kvm_hyp_reserve();
        dma_limits_init();
 
index 86326587e58de803ef37b52ef519f50a2541a4fb..6d32a42994458eb4cabb4fe52017d2556eccab15 100644 (file)
@@ -68,7 +68,6 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
                               unsigned long addr, pte_t *ptep,
                               pte_t pte, int dirty);
 
-void gigantic_hugetlb_cma_reserve(void) __init;
 #include <asm-generic/hugetlb.h>
 
 #else /* ! CONFIG_HUGETLB_PAGE */
@@ -77,10 +76,6 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
 {
 }
 
-static inline void __init gigantic_hugetlb_cma_reserve(void)
-{
-}
-
 static inline void __init hugetlbpage_init_defaultsize(void)
 {
 }
index c8c42b419742f057b6b1e29dd078c13f471316c5..cb5b73adc2506998d8c45fe776e75cb35a2404eb 100644 (file)
@@ -1003,7 +1003,6 @@ void __init setup_arch(char **cmdline_p)
        fadump_cma_init();
        kdump_cma_reserve();
        kvm_cma_reserve();
-       gigantic_hugetlb_cma_reserve();
 
        early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
 
index d3c1b749dcfc885c1bb58114dd1df34dbef2009f..558fafb82b8ac9d9c8ffaf7ffb28a4b9e4dc879f 100644 (file)
@@ -200,18 +200,15 @@ static int __init hugetlbpage_init(void)
 
 arch_initcall(hugetlbpage_init);
 
-void __init gigantic_hugetlb_cma_reserve(void)
+unsigned int __init arch_hugetlb_cma_order(void)
 {
-       unsigned long order = 0;
-
        if (radix_enabled())
-               order = PUD_SHIFT - PAGE_SHIFT;
+               return PUD_SHIFT - PAGE_SHIFT;
        else if (!firmware_has_feature(FW_FEATURE_LPAR) && mmu_psize_defs[MMU_PAGE_16G].shift)
                /*
                 * For pseries we do use ibm,expected#pages for reserving 16G pages.
                 */
-               order = mmu_psize_to_shift(MMU_PAGE_16G) - PAGE_SHIFT;
+               return mmu_psize_to_shift(MMU_PAGE_16G) - PAGE_SHIFT;
 
-       if (order)
-               hugetlb_cma_reserve(order);
+       return 0;
 }
index 375dd96bb4a0d294682b083b5cefd7422b7a267b..a6d217112cf465bb05fee569e5716fdfd3f22208 100644 (file)
@@ -447,3 +447,11 @@ static __init int gigantic_pages_init(void)
 }
 arch_initcall(gigantic_pages_init);
 #endif
+
+unsigned int __init arch_hugetlb_cma_order(void)
+{
+       if (IS_ENABLED(CONFIG_64BIT))
+               return PUD_SHIFT - PAGE_SHIFT;
+
+       return 0;
+}
index 11ac4041afc0e8dea3a5d8850748bb02735f04eb..848efeb9e16367c9338db9266ae2e049ea5aacaf 100644 (file)
@@ -311,8 +311,6 @@ static void __init setup_bootmem(void)
                memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
 
        dma_contiguous_reserve(dma32_phys_limit);
-       if (IS_ENABLED(CONFIG_64BIT))
-               hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
 }
 
 #ifdef CONFIG_RELOCATABLE
index c1fe0b53c5ac506d216d4f0518336e6466bc275c..b60284328fe3de9c4c0f87785936b789900aa523 100644 (file)
@@ -963,8 +963,6 @@ void __init setup_arch(char **cmdline_p)
        setup_uv();
        dma_contiguous_reserve(ident_map_size);
        vmcp_cma_reserve();
-       if (cpu_has_edat2())
-               hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
 
        reserve_crashkernel();
 #ifdef CONFIG_CRASH_DUMP
index d42e61c7594eac4486835d152537696f3896faf4..d93417d1e53c36e24541a12e1dc8fdd49210c086 100644 (file)
@@ -255,3 +255,11 @@ bool __init arch_hugetlb_valid_size(unsigned long size)
        else
                return false;
 }
+
+unsigned int __init arch_hugetlb_cma_order(void)
+{
+       if (cpu_has_edat2())
+               return PUD_SHIFT - PAGE_SHIFT;
+
+       return 0;
+}
index e2318fa9b1bbdf070f49af27759ac49ea5ed9279..e1efe3975aa0896c58b06ec299ed3b0766d6bc81 100644 (file)
@@ -1189,10 +1189,6 @@ void __init setup_arch(char **cmdline_p)
        initmem_init();
        dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
 
-       if (boot_cpu_has(X86_FEATURE_GBPAGES)) {
-               hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
-       }
-
        /*
         * Reserve memory for crash kernel after SRAT is parsed so that it
         * won't consume hotpluggable memory.
index 58f7f2bd535d5931072d370c461537c2e77996ae..3b26621c912867422c5a15639ebf21f9b38a55c3 100644 (file)
@@ -42,3 +42,11 @@ static __init int gigantic_pages_init(void)
 arch_initcall(gigantic_pages_init);
 #endif
 #endif
+
+unsigned int __init arch_hugetlb_cma_order(void)
+{
+       if (boot_cpu_has(X86_FEATURE_GBPAGES))
+               return PUD_SHIFT - PAGE_SHIFT;
+
+       return 0;
+}
index 694f6e83c637bbef4ce849da2eaf312b98dbf769..00e6a73e7bba97d31686a8088fff32e5553bdf40 100644 (file)
@@ -281,6 +281,8 @@ void fixup_hugetlb_reservations(struct vm_area_struct *vma);
 void hugetlb_split(struct vm_area_struct *vma, unsigned long addr);
 int hugetlb_vma_lock_alloc(struct vm_area_struct *vma);
 
+unsigned int arch_hugetlb_cma_order(void);
+
 #else /* !CONFIG_HUGETLB_PAGE */
 
 static inline void hugetlb_dup_vma_private(struct vm_area_struct *vma)
@@ -1322,9 +1324,9 @@ static inline spinlock_t *huge_pte_lock(struct hstate *h,
 }
 
 #if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_CMA)
-extern void __init hugetlb_cma_reserve(int order);
+extern void __init hugetlb_cma_reserve(void);
 #else
-static inline __init void hugetlb_cma_reserve(int order)
+static inline __init void hugetlb_cma_reserve(void)
 {
 }
 #endif
index e8e4dc7182d5457b31091d9562e064823d2c2af7..b1eb5998282c5e9b464771812eb2f97e6c98b67a 100644 (file)
@@ -134,12 +134,24 @@ static int __init cmdline_parse_hugetlb_cma_only(char *p)
 
 early_param("hugetlb_cma_only", cmdline_parse_hugetlb_cma_only);
 
-void __init hugetlb_cma_reserve(int order)
+unsigned int __weak arch_hugetlb_cma_order(void)
 {
-       unsigned long size, reserved, per_node;
+       return 0;
+}
+
+void __init hugetlb_cma_reserve(void)
+{
+       unsigned long size, reserved, per_node, order;
        bool node_specific_cma_alloc = false;
        int nid;
 
+       if (!hugetlb_cma_size)
+               return;
+
+       order = arch_hugetlb_cma_order();
+       if (!order)
+               return;
+
        /*
         * HugeTLB CMA reservation is required for gigantic
         * huge pages which could not be allocated via the
@@ -149,9 +161,6 @@ void __init hugetlb_cma_reserve(int order)
        VM_WARN_ON(order <= MAX_PAGE_ORDER);
        cma_reserve_called = true;
 
-       if (!hugetlb_cma_size)
-               return;
-
        hugetlb_bootmem_set_nodes();
 
        for (nid = 0; nid < MAX_NUMNODES; nid++) {
index 31246fe5c3619623e90869c19b970b0a4bb3d66f..0cfbdef91d721dd4b45ab6d7158b4be67c99a0bb 100644 (file)
@@ -2677,6 +2677,7 @@ void __init __weak mem_init(void)
 
 void __init mm_core_init_early(void)
 {
+       hugetlb_cma_reserve();
        hugetlb_bootmem_alloc();
 
        free_area_init();