* [PATCH v2 01/13] arm: mem_init: use memblock_phys_free() to free DMA memory on SA1111
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 02/13] csky: move setup_initrd() to setup.c Mike Rapoport
` (12 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
This will help to pull out memblock_free_all() to generic code.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/arm/mm/init.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 5345d218899a..9aec1cb2386f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -277,14 +277,14 @@ void __init mem_init(void)
set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
- /* this will put all unused low memory onto the freelists */
- memblock_free_all();
-
#ifdef CONFIG_SA1111
/* now that our DMA memory is actually so designated, we can free it */
- free_reserved_area(__va(PHYS_OFFSET), swapper_pg_dir, -1, NULL);
+ memblock_phys_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
#endif
+ /* this will put all unused low memory onto the freelists */
+ memblock_free_all();
+
free_highpages();
/*
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 02/13] csky: move setup_initrd() to setup.c
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 01/13] arm: mem_init: use memblock_phys_free() to free DMA memory on SA1111 Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 03/13] hexagon: move initialization of init_mm.context init to paging_init() Mike Rapoport
` (11 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Memory used by initrd should be reserved as soon as possible before
there any memblock allocations that might overwrite that memory.
This will also help with pulling out memblock_free_all() to the generic
code and reducing code duplication in arch::mem_init().
Acked by: Guo Ren (csky) <guoren@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/csky/kernel/setup.c | 43 ++++++++++++++++++++++++++++++++++++++++
arch/csky/mm/init.c | 43 ----------------------------------------
2 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c
index fe715b707fd0..e0d6ca86ea8c 100644
--- a/arch/csky/kernel/setup.c
+++ b/arch/csky/kernel/setup.c
@@ -12,6 +12,45 @@
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+static void __init setup_initrd(void)
+{
+ unsigned long size;
+
+ if (initrd_start >= initrd_end) {
+ pr_err("initrd not found or empty");
+ goto disable;
+ }
+
+ if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
+ pr_err("initrd extends beyond end of memory");
+ goto disable;
+ }
+
+ size = initrd_end - initrd_start;
+
+ if (memblock_is_region_reserved(__pa(initrd_start), size)) {
+ pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region",
+ __pa(initrd_start), size);
+ goto disable;
+ }
+
+ memblock_reserve(__pa(initrd_start), size);
+
+ pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n",
+ (void *)(initrd_start), size);
+
+ initrd_below_start_ok = 1;
+
+ return;
+
+disable:
+ initrd_start = initrd_end = 0;
+
+ pr_err(" - disabling initrd\n");
+}
+#endif
+
static void __init csky_memblock_init(void)
{
unsigned long lowmem_size = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
@@ -40,6 +79,10 @@ static void __init csky_memblock_init(void)
max_low_pfn = min_low_pfn + sseg_size;
}
+#ifdef CONFIG_BLK_DEV_INITRD
+ setup_initrd();
+#endif
+
max_zone_pfn[ZONE_NORMAL] = max_low_pfn;
mmu_init(min_low_pfn, max_low_pfn);
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index bde7cabd23df..ab51acbc19b2 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -42,45 +42,6 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
__page_aligned_bss;
EXPORT_SYMBOL(empty_zero_page);
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init setup_initrd(void)
-{
- unsigned long size;
-
- if (initrd_start >= initrd_end) {
- pr_err("initrd not found or empty");
- goto disable;
- }
-
- if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
- pr_err("initrd extends beyond end of memory");
- goto disable;
- }
-
- size = initrd_end - initrd_start;
-
- if (memblock_is_region_reserved(__pa(initrd_start), size)) {
- pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region",
- __pa(initrd_start), size);
- goto disable;
- }
-
- memblock_reserve(__pa(initrd_start), size);
-
- pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n",
- (void *)(initrd_start), size);
-
- initrd_below_start_ok = 1;
-
- return;
-
-disable:
- initrd_start = initrd_end = 0;
-
- pr_err(" - disabling initrd\n");
-}
-#endif
-
void __init mem_init(void)
{
#ifdef CONFIG_HIGHMEM
@@ -92,10 +53,6 @@ void __init mem_init(void)
#endif
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
-#ifdef CONFIG_BLK_DEV_INITRD
- setup_initrd();
-#endif
-
memblock_free_all();
#ifdef CONFIG_HIGHMEM
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 03/13] hexagon: move initialization of init_mm.context init to paging_init()
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 01/13] arm: mem_init: use memblock_phys_free() to free DMA memory on SA1111 Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 02/13] csky: move setup_initrd() to setup.c Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 04/13] MIPS: consolidate mem_init() for NUMA machines Mike Rapoport
` (10 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
This will help with pulling out memblock_free_all() to the generic
code and reducing code duplication in arch::mem_init().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/hexagon/mm/init.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index 3458f39ca2ac..508bb6a8dcc9 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -59,14 +59,6 @@ void __init mem_init(void)
* To-Do: someone somewhere should wipe out the bootmem map
* after we're done?
*/
-
- /*
- * This can be moved to some more virtual-memory-specific
- * initialization hook at some point. Set the init_mm
- * descriptors "context" value to point to the initial
- * kernel segment table's physical address.
- */
- init_mm.context.ptbase = __pa(init_mm.pgd);
}
void sync_icache_dcache(pte_t pte)
@@ -103,6 +95,12 @@ static void __init paging_init(void)
free_area_init(max_zone_pfn); /* sets up the zonelists and mem_map */
+ /*
+ * Set the init_mm descriptors "context" value to point to the
+ * initial kernel segment table's physical address.
+ */
+ init_mm.context.ptbase = __pa(init_mm.pgd);
+
/*
* Start of high memory area. Will probably need something more
* fancy if we... get more fancy.
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 04/13] MIPS: consolidate mem_init() for NUMA machines
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (2 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 03/13] hexagon: move initialization of init_mm.context init to paging_init() Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 05/13] MIPS: make setup_zero_pages() use memblock Mike Rapoport
` (9 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Both MIPS systems that support numa (loongsoon3 and sgi-ip27) have
identical mem_init() for NUMA case.
Move that into arch/mips/mm/init.c and drop duplicate per-machine
definitions.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/mips/loongson64/numa.c | 7 -------
arch/mips/mm/init.c | 7 +++++++
arch/mips/sgi-ip27/ip27-memory.c | 9 ---------
3 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c
index 8388400d052f..95d5f553ce19 100644
--- a/arch/mips/loongson64/numa.c
+++ b/arch/mips/loongson64/numa.c
@@ -164,13 +164,6 @@ void __init paging_init(void)
free_area_init(zones_size);
}
-void __init mem_init(void)
-{
- high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
- memblock_free_all();
- setup_zero_pages(); /* This comes from node 0 */
-}
-
/* All PCI device belongs to logical Node-0 */
int pcibus_to_node(struct pci_bus *bus)
{
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 4583d1a2a73e..3db6082c611e 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -482,6 +482,13 @@ void __init mem_init(void)
0x80000000 - 4, KCORE_TEXT);
#endif
}
+#else /* CONFIG_NUMA */
+void __init mem_init(void)
+{
+ high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
+ memblock_free_all();
+ setup_zero_pages(); /* This comes from node 0 */
+}
#endif /* !CONFIG_NUMA */
void free_init_pages(const char *what, unsigned long begin, unsigned long end)
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index 1963313f55d8..2b3e46e2e607 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -406,8 +406,6 @@ void __init prom_meminit(void)
}
}
-extern void setup_zero_pages(void);
-
void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = {0, };
@@ -416,10 +414,3 @@ void __init paging_init(void)
zones_size[ZONE_NORMAL] = max_low_pfn;
free_area_init(zones_size);
}
-
-void __init mem_init(void)
-{
- high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
- memblock_free_all();
- setup_zero_pages(); /* This comes from node 0 */
-}
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 05/13] MIPS: make setup_zero_pages() use memblock
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (3 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 04/13] MIPS: consolidate mem_init() for NUMA machines Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 06/13] nios2: move pr_debug() about memory start and end to setup_arch() Mike Rapoport
` (8 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Allocating the zero pages from memblock is simpler because the memory is
already reserved.
This will also help with pulling out memblock_free_all() to the generic
code and reducing code duplication in arch::mem_init().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/mips/include/asm/mmzone.h | 2 --
arch/mips/mm/init.c | 18 +++++-------------
2 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/arch/mips/include/asm/mmzone.h b/arch/mips/include/asm/mmzone.h
index 14226ea42036..602a21aee9d4 100644
--- a/arch/mips/include/asm/mmzone.h
+++ b/arch/mips/include/asm/mmzone.h
@@ -20,6 +20,4 @@
#define nid_to_addrbase(nid) 0
#endif
-extern void setup_zero_pages(void);
-
#endif /* _ASM_MMZONE_H_ */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 3db6082c611e..820e35a59d4d 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -59,24 +59,16 @@ EXPORT_SYMBOL(zero_page_mask);
/*
* Not static inline because used by IP27 special magic initialization code
*/
-void setup_zero_pages(void)
+static void __init setup_zero_pages(void)
{
- unsigned int order, i;
- struct page *page;
+ unsigned int order;
if (cpu_has_vce)
order = 3;
else
order = 0;
- empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!empty_zero_page)
- panic("Oh boy, that early out of memory?");
-
- page = virt_to_page((void *)empty_zero_page);
- split_page(page, order);
- for (i = 0; i < (1 << order); i++, page++)
- mark_page_reserved(page);
+ empty_zero_page = (unsigned long)memblock_alloc_or_panic(PAGE_SIZE << order, PAGE_SIZE);
zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK;
}
@@ -470,9 +462,9 @@ void __init mem_init(void)
BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (PFN_PTE_SHIFT > PAGE_SHIFT));
maar_init();
- memblock_free_all();
setup_zero_pages(); /* Setup zeroed pages. */
mem_init_free_highmem();
+ memblock_free_all();
#ifdef CONFIG_64BIT
if ((unsigned long) &_text > (unsigned long) CKSEG0)
@@ -486,8 +478,8 @@ void __init mem_init(void)
void __init mem_init(void)
{
high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
- memblock_free_all();
setup_zero_pages(); /* This comes from node 0 */
+ memblock_free_all();
}
#endif /* !CONFIG_NUMA */
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 06/13] nios2: move pr_debug() about memory start and end to setup_arch()
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (4 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 05/13] MIPS: make setup_zero_pages() use memblock Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-17 12:40 ` Dinh Nguyen
2025-03-13 13:49 ` [PATCH v2 07/13] s390: make setup_zero_pages() use memblock Mike Rapoport
` (7 subsequent siblings)
13 siblings, 1 reply; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
This will help with pulling out memblock_free_all() to the generic
code and reducing code duplication in arch::mem_init().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/nios2/kernel/setup.c | 2 ++
arch/nios2/mm/init.c | 2 --
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index da122a5fa43b..a4cffbfc1399 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -149,6 +149,8 @@ void __init setup_arch(char **cmdline_p)
memory_start = memblock_start_of_DRAM();
memory_end = memblock_end_of_DRAM();
+ pr_debug("%s: start=%lx, end=%lx\n", __func__, memory_start, memory_end);
+
setup_initial_init_mm(_stext, _etext, _edata, _end);
init_task.thread.kregs = &fake_regs;
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index a2278485de19..aa692ad30044 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -65,8 +65,6 @@ void __init mem_init(void)
unsigned long end_mem = memory_end; /* this must not include
kernel stack at top */
- pr_debug("mem_init: start=%lx, end=%lx\n", memory_start, memory_end);
-
end_mem &= PAGE_MASK;
high_memory = __va(end_mem);
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 06/13] nios2: move pr_debug() about memory start and end to setup_arch()
2025-03-13 13:49 ` [PATCH v2 06/13] nios2: move pr_debug() about memory start and end to setup_arch() Mike Rapoport
@ 2025-03-17 12:40 ` Dinh Nguyen
0 siblings, 0 replies; 24+ messages in thread
From: Dinh Nguyen @ 2025-03-17 12:40 UTC (permalink / raw)
To: Mike Rapoport, Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Geert Uytterhoeven,
Gerald Schaefer, Guo Ren, Heiko Carstens, Helge Deller,
Huacai Chen, Ingo Molnar, Jiaxun Yang, Johannes Berg,
John Paul Adrian Glaubitz, Madhavan Srinivasan, Mark Brown,
Matt Turner, Max Filippov, Michael Ellerman, Michal Simek,
Palmer Dabbelt, Peter Zijlstra, Richard Weinberger, Russell King,
Stafford Horne, Thomas Bogendoerfer, Thomas Gleixner,
Vasily Gorbik, Vineet Gupta, Will Deacon, linux-alpha,
linux-kernel, linux-snps-arc, linux-arm-kernel, linux-csky,
linux-hexagon, loongarch, linux-m68k, linux-mips, linux-openrisc,
linux-parisc, linuxppc-dev, linux-riscv, linux-s390, linux-sh,
sparclinux, linux-um, linux-arch, linux-mm, x86
On 3/13/25 08:49, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> This will help with pulling out memblock_free_all() to the generic
> code and reducing code duplication in arch::mem_init().
>
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> arch/nios2/kernel/setup.c | 2 ++
> arch/nios2/mm/init.c | 2 --
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
> index da122a5fa43b..a4cffbfc1399 100644
> --- a/arch/nios2/kernel/setup.c
> +++ b/arch/nios2/kernel/setup.c
> @@ -149,6 +149,8 @@ void __init setup_arch(char **cmdline_p)
> memory_start = memblock_start_of_DRAM();
> memory_end = memblock_end_of_DRAM();
>
> + pr_debug("%s: start=%lx, end=%lx\n", __func__, memory_start, memory_end);
> +
> setup_initial_init_mm(_stext, _etext, _edata, _end);
> init_task.thread.kregs = &fake_regs;
>
> diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
> index a2278485de19..aa692ad30044 100644
> --- a/arch/nios2/mm/init.c
> +++ b/arch/nios2/mm/init.c
> @@ -65,8 +65,6 @@ void __init mem_init(void)
> unsigned long end_mem = memory_end; /* this must not include
> kernel stack at top */
>
> - pr_debug("mem_init: start=%lx, end=%lx\n", memory_start, memory_end);
> -
> end_mem &= PAGE_MASK;
> high_memory = __va(end_mem);
>
Acked-By: Dinh Nguyen <dinguyen@kernel.org>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 07/13] s390: make setup_zero_pages() use memblock
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (5 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 06/13] nios2: move pr_debug() about memory start and end to setup_arch() Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 13:49 ` [PATCH v2 08/13] xtensa: split out printing of virtual memory layout to a function Mike Rapoport
` (6 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Allocating the zero pages from memblock is simpler because the memory is
already reserved.
This will also help with pulling out memblock_free_all() to the generic
code and reducing code duplication in arch::mem_init().
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/s390/mm/init.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index f2298f7a3f21..f8333feb6a7e 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -73,8 +73,6 @@ static void __init setup_zero_pages(void)
{
unsigned long total_pages = memblock_estimated_nr_free_pages();
unsigned int order;
- struct page *page;
- int i;
/* Latest machines require a mapping granularity of 512KB */
order = 7;
@@ -83,16 +81,7 @@ static void __init setup_zero_pages(void)
while (order > 2 && (total_pages >> 10) < (1UL << order))
order--;
- empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!empty_zero_page)
- panic("Out of memory in setup_zero_pages");
-
- page = virt_to_page((void *) empty_zero_page);
- split_page(page, order);
- for (i = 1 << order; i > 0; i--) {
- mark_page_reserved(page);
- page++;
- }
+ empty_zero_page = (unsigned long)memblock_alloc_or_panic(PAGE_SIZE << order, PAGE_SIZE);
zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK;
}
@@ -176,9 +165,10 @@ void __init mem_init(void)
pv_init();
kfence_split_mapping();
+ setup_zero_pages(); /* Setup zeroed pages. */
+
/* this will put all low memory onto the freelists */
memblock_free_all();
- setup_zero_pages(); /* Setup zeroed pages. */
}
unsigned long memory_block_size_bytes(void)
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 08/13] xtensa: split out printing of virtual memory layout to a function
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (6 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 07/13] s390: make setup_zero_pages() use memblock Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-13 17:14 ` Max Filippov
2025-03-13 13:49 ` [PATCH v2 09/13] arch, mm: set max_mapnr when allocating memory map for FLATMEM Mike Rapoport
` (5 subsequent siblings)
13 siblings, 1 reply; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
This will help with pulling out memblock_free_all() to the generic
code and reducing code duplication in arch::mem_init().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/xtensa/mm/init.c | 97 ++++++++++++++++++++++---------------------
1 file changed, 50 insertions(+), 47 deletions(-)
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index b2587a1a7c46..01577d33e602 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -66,6 +66,55 @@ void __init bootmem_init(void)
memblock_dump_all();
}
+static void __init print_vm_layout(void)
+{
+ pr_info("virtual kernel memory layout:\n"
+#ifdef CONFIG_KASAN
+ " kasan : 0x%08lx - 0x%08lx (%5lu MB)\n"
+#endif
+#ifdef CONFIG_MMU
+ " vmalloc : 0x%08lx - 0x%08lx (%5lu MB)\n"
+#endif
+#ifdef CONFIG_HIGHMEM
+ " pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n"
+ " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n"
+#endif
+ " lowmem : 0x%08lx - 0x%08lx (%5lu MB)\n"
+ " .text : 0x%08lx - 0x%08lx (%5lu kB)\n"
+ " .rodata : 0x%08lx - 0x%08lx (%5lu kB)\n"
+ " .data : 0x%08lx - 0x%08lx (%5lu kB)\n"
+ " .init : 0x%08lx - 0x%08lx (%5lu kB)\n"
+ " .bss : 0x%08lx - 0x%08lx (%5lu kB)\n",
+#ifdef CONFIG_KASAN
+ KASAN_SHADOW_START, KASAN_SHADOW_START + KASAN_SHADOW_SIZE,
+ KASAN_SHADOW_SIZE >> 20,
+#endif
+#ifdef CONFIG_MMU
+ VMALLOC_START, VMALLOC_END,
+ (VMALLOC_END - VMALLOC_START) >> 20,
+#ifdef CONFIG_HIGHMEM
+ PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE,
+ (LAST_PKMAP*PAGE_SIZE) >> 10,
+ FIXADDR_START, FIXADDR_END,
+ (FIXADDR_END - FIXADDR_START) >> 10,
+#endif
+ PAGE_OFFSET, PAGE_OFFSET +
+ (max_low_pfn - min_low_pfn) * PAGE_SIZE,
+#else
+ min_low_pfn * PAGE_SIZE, max_low_pfn * PAGE_SIZE,
+#endif
+ ((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20,
+ (unsigned long)_text, (unsigned long)_etext,
+ (unsigned long)(_etext - _text) >> 10,
+ (unsigned long)__start_rodata, (unsigned long)__end_rodata,
+ (unsigned long)(__end_rodata - __start_rodata) >> 10,
+ (unsigned long)_sdata, (unsigned long)_edata,
+ (unsigned long)(_edata - _sdata) >> 10,
+ (unsigned long)__init_begin, (unsigned long)__init_end,
+ (unsigned long)(__init_end - __init_begin) >> 10,
+ (unsigned long)__bss_start, (unsigned long)__bss_stop,
+ (unsigned long)(__bss_stop - __bss_start) >> 10);
+}
void __init zones_init(void)
{
@@ -77,6 +126,7 @@ void __init zones_init(void)
#endif
};
free_area_init(max_zone_pfn);
+ print_vm_layout();
}
static void __init free_highpages(void)
@@ -118,53 +168,6 @@ void __init mem_init(void)
high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
-
- pr_info("virtual kernel memory layout:\n"
-#ifdef CONFIG_KASAN
- " kasan : 0x%08lx - 0x%08lx (%5lu MB)\n"
-#endif
-#ifdef CONFIG_MMU
- " vmalloc : 0x%08lx - 0x%08lx (%5lu MB)\n"
-#endif
-#ifdef CONFIG_HIGHMEM
- " pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n"
- " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n"
-#endif
- " lowmem : 0x%08lx - 0x%08lx (%5lu MB)\n"
- " .text : 0x%08lx - 0x%08lx (%5lu kB)\n"
- " .rodata : 0x%08lx - 0x%08lx (%5lu kB)\n"
- " .data : 0x%08lx - 0x%08lx (%5lu kB)\n"
- " .init : 0x%08lx - 0x%08lx (%5lu kB)\n"
- " .bss : 0x%08lx - 0x%08lx (%5lu kB)\n",
-#ifdef CONFIG_KASAN
- KASAN_SHADOW_START, KASAN_SHADOW_START + KASAN_SHADOW_SIZE,
- KASAN_SHADOW_SIZE >> 20,
-#endif
-#ifdef CONFIG_MMU
- VMALLOC_START, VMALLOC_END,
- (VMALLOC_END - VMALLOC_START) >> 20,
-#ifdef CONFIG_HIGHMEM
- PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE,
- (LAST_PKMAP*PAGE_SIZE) >> 10,
- FIXADDR_START, FIXADDR_END,
- (FIXADDR_END - FIXADDR_START) >> 10,
-#endif
- PAGE_OFFSET, PAGE_OFFSET +
- (max_low_pfn - min_low_pfn) * PAGE_SIZE,
-#else
- min_low_pfn * PAGE_SIZE, max_low_pfn * PAGE_SIZE,
-#endif
- ((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20,
- (unsigned long)_text, (unsigned long)_etext,
- (unsigned long)(_etext - _text) >> 10,
- (unsigned long)__start_rodata, (unsigned long)__end_rodata,
- (unsigned long)(__end_rodata - __start_rodata) >> 10,
- (unsigned long)_sdata, (unsigned long)_edata,
- (unsigned long)(_edata - _sdata) >> 10,
- (unsigned long)__init_begin, (unsigned long)__init_end,
- (unsigned long)(__init_end - __init_begin) >> 10,
- (unsigned long)__bss_start, (unsigned long)__bss_stop,
- (unsigned long)(__bss_stop - __bss_start) >> 10);
}
static void __init parse_memmap_one(char *p)
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 08/13] xtensa: split out printing of virtual memory layout to a function
2025-03-13 13:49 ` [PATCH v2 08/13] xtensa: split out printing of virtual memory layout to a function Mike Rapoport
@ 2025-03-13 17:14 ` Max Filippov
0 siblings, 0 replies; 24+ messages in thread
From: Max Filippov @ 2025-03-13 17:14 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Geert Uytterhoeven, Gerald Schaefer, Guo Ren,
Heiko Carstens, Helge Deller, Huacai Chen, Ingo Molnar,
Jiaxun Yang, Johannes Berg, John Paul Adrian Glaubitz,
Madhavan Srinivasan, Mark Brown, Matt Turner, Michael Ellerman,
Michal Simek, Palmer Dabbelt, Peter Zijlstra, Richard Weinberger,
Russell King, Stafford Horne, Thomas Bogendoerfer,
Thomas Gleixner, Vasily Gorbik, Vineet Gupta, Will Deacon,
linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-mips,
linux-openrisc, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, sparclinux, linux-um, linux-arch, linux-mm,
x86
On Thu, Mar 13, 2025 at 4:52 PM Mike Rapoport <rppt@kernel.org> wrote:
>
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> This will help with pulling out memblock_free_all() to the generic
> code and reducing code duplication in arch::mem_init().
>
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> arch/xtensa/mm/init.c | 97 ++++++++++++++++++++++---------------------
> 1 file changed, 50 insertions(+), 47 deletions(-)
Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 09/13] arch, mm: set max_mapnr when allocating memory map for FLATMEM
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (7 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 08/13] xtensa: split out printing of virtual memory layout to a function Mike Rapoport
@ 2025-03-13 13:49 ` Mike Rapoport
2025-03-14 9:25 ` Christophe Leroy
2025-03-13 13:50 ` [PATCH v2 10/13] arch, mm: set high_memory in free_area_init() Mike Rapoport
` (4 subsequent siblings)
13 siblings, 1 reply; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:49 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
max_mapnr is essentially the size of the memory map for systems that use
FLATMEM. There is no reason to calculate it in each and every architecture
when it's anyway calculated in alloc_node_mem_map().
Drop setting of max_mapnr from architecture code and set it once in
alloc_node_mem_map().
While on it, move definition of mem_map and max_mapnr to mm/mm_init.c so
there won't be two copies for MMU and !MMU variants.
Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/alpha/mm/init.c | 1 -
arch/arc/mm/init.c | 5 -----
arch/arm/mm/init.c | 2 --
arch/csky/mm/init.c | 4 ----
arch/loongarch/mm/init.c | 1 -
arch/microblaze/mm/init.c | 4 ----
arch/mips/mm/init.c | 8 --------
arch/nios2/kernel/setup.c | 1 -
arch/nios2/mm/init.c | 2 +-
arch/openrisc/mm/init.c | 1 -
arch/parisc/mm/init.c | 1 -
arch/powerpc/kernel/setup-common.c | 2 --
arch/riscv/mm/init.c | 1 -
arch/s390/mm/init.c | 1 -
arch/sh/mm/init.c | 1 -
arch/sparc/mm/init_32.c | 1 -
arch/um/include/shared/mem_user.h | 1 -
arch/um/kernel/physmem.c | 12 ------------
arch/um/kernel/um_arch.c | 1 -
arch/x86/mm/init_32.c | 3 ---
arch/xtensa/mm/init.c | 1 -
include/asm-generic/memory_model.h | 5 +++--
include/linux/mm.h | 11 -----------
mm/memory.c | 8 --------
mm/mm_init.c | 25 +++++++++++++++++--------
mm/nommu.c | 4 ----
26 files changed, 21 insertions(+), 86 deletions(-)
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 61c2198b1359..ec0eeae9c653 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -276,7 +276,6 @@ srm_paging_stop (void)
void __init
mem_init(void)
{
- set_max_mapnr(max_low_pfn);
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
memblock_free_all();
}
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 6a71b23f1383..7ef883d58dc1 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -154,11 +154,6 @@ void __init setup_arch_memory(void)
arch_pfn_offset = min(min_low_pfn, min_high_pfn);
kmap_init();
-
-#else /* CONFIG_HIGHMEM */
- /* pfn_valid() uses this when FLATMEM=y and HIGHMEM=n */
- max_mapnr = max_low_pfn - min_low_pfn;
-
#endif /* CONFIG_HIGHMEM */
free_area_init(max_zone_pfn);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 9aec1cb2386f..d4bcc745a044 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -275,8 +275,6 @@ void __init mem_init(void)
swiotlb_init(max_pfn > arm_dma_pfn_limit, SWIOTLB_VERBOSE);
#endif
- set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
-
#ifdef CONFIG_SA1111
/* now that our DMA memory is actually so designated, we can free it */
memblock_phys_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index ab51acbc19b2..ba6694d6170a 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -46,10 +46,6 @@ void __init mem_init(void)
{
#ifdef CONFIG_HIGHMEM
unsigned long tmp;
-
- set_max_mapnr(highend_pfn - ARCH_PFN_OFFSET);
-#else
- set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
#endif
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index ca5aa5f46a9f..00449df50db1 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -78,7 +78,6 @@ void __init paging_init(void)
void __init mem_init(void)
{
- max_mapnr = max_low_pfn;
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 4520c5741579..857cd2b44bcf 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -104,17 +104,13 @@ void __init setup_memory(void)
*
* min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
* max_low_pfn
- * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
*/
/* memory start is from the kernel end (aligned) to higher addr */
min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
- /* RAM is assumed contiguous */
- max_mapnr = memory_size >> PAGE_SHIFT;
max_low_pfn = ((u64)memory_start + (u64)lowmem_size) >> PAGE_SHIFT;
max_pfn = ((u64)memory_start + (u64)memory_size) >> PAGE_SHIFT;
- pr_info("%s: max_mapnr: %#lx\n", __func__, max_mapnr);
pr_info("%s: min_low_pfn: %#lx\n", __func__, min_low_pfn);
pr_info("%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
pr_info("%s: max_pfn: %#lx\n", __func__, max_pfn);
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 820e35a59d4d..eb61a73520a0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -415,15 +415,7 @@ void __init paging_init(void)
" %ldk highmem ignored\n",
(highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10));
max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
-
- max_mapnr = max_low_pfn;
- } else if (highend_pfn) {
- max_mapnr = highend_pfn;
- } else {
- max_mapnr = max_low_pfn;
}
-#else
- max_mapnr = max_low_pfn;
#endif
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index a4cffbfc1399..2a40150142c3 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -158,7 +158,6 @@ void __init setup_arch(char **cmdline_p)
*cmdline_p = boot_command_line;
find_limits(&min_low_pfn, &max_low_pfn, &max_pfn);
- max_mapnr = max_low_pfn;
memblock_reserve(__pa_symbol(_stext), _end - _stext);
#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index aa692ad30044..3cafa87ead9e 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -51,7 +51,7 @@ void __init paging_init(void)
pagetable_init();
pgd_current = swapper_pg_dir;
- max_zone_pfn[ZONE_NORMAL] = max_mapnr;
+ max_zone_pfn[ZONE_NORMAL] = max_low_pfn;
/* pass the memory from the bootmem allocator to the main allocator */
free_area_init(max_zone_pfn);
diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
index d0cb1a0126f9..9093c336e158 100644
--- a/arch/openrisc/mm/init.c
+++ b/arch/openrisc/mm/init.c
@@ -193,7 +193,6 @@ void __init mem_init(void)
{
BUG_ON(!mem_map);
- max_mapnr = max_low_pfn;
high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
/* clear the zero-page */
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 61c0a2477072..2cdfc0b1195c 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -563,7 +563,6 @@ void __init mem_init(void)
#endif
high_memory = __va((max_pfn << PAGE_SHIFT));
- set_max_mapnr(max_low_pfn);
memblock_free_all();
#ifdef CONFIG_PA11
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index a08b0ede4e64..68d47c53876c 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -957,8 +957,6 @@ void __init setup_arch(char **cmdline_p)
/* Parse memory topology */
mem_topology_setup();
- /* Set max_mapnr before paging_init() */
- set_max_mapnr(max_pfn);
high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
/*
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 15b2eda4c364..157c9ca51541 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -298,7 +298,6 @@ static void __init setup_bootmem(void)
high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
- set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
reserve_initrd_mem();
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index f8333feb6a7e..36fed6dffb38 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -159,7 +159,6 @@ void __init mem_init(void)
cpumask_set_cpu(0, &init_mm.context.cpu_attach_mask);
cpumask_set_cpu(0, mm_cpumask(&init_mm));
- set_max_mapnr(max_low_pfn);
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
pv_init();
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 289a2fecebef..72aea5cd1b85 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -290,7 +290,6 @@ void __init paging_init(void)
*/
max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
- set_max_mapnr(max_low_pfn - min_low_pfn);
nodes_clear(node_online_map);
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index d96a14ffceeb..6b58da14edc6 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -275,7 +275,6 @@ void __init mem_init(void)
taint_real_pages();
- max_mapnr = last_valid_pfn - pfn_base;
high_memory = __va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
diff --git a/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h
index adfa08062f88..d4727efcf23d 100644
--- a/arch/um/include/shared/mem_user.h
+++ b/arch/um/include/shared/mem_user.h
@@ -47,7 +47,6 @@ extern int iomem_size;
#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
extern unsigned long find_iomem(char *driver, unsigned long *len_out);
-extern void mem_total_pages(unsigned long physmem, unsigned long iomem);
extern void setup_physmem(unsigned long start, unsigned long usable,
unsigned long len);
extern void map_memory(unsigned long virt, unsigned long phys,
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index a74f17b033c4..af02b5f9911d 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -22,18 +22,6 @@ static int physmem_fd = -1;
unsigned long high_physmem;
EXPORT_SYMBOL(high_physmem);
-void __init mem_total_pages(unsigned long physmem, unsigned long iomem)
-{
- unsigned long phys_pages, iomem_pages, total_pages;
-
- phys_pages = physmem >> PAGE_SHIFT;
- iomem_pages = iomem >> PAGE_SHIFT;
-
- total_pages = phys_pages + iomem_pages;
-
- max_mapnr = total_pages;
-}
-
void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
int r, int w, int x)
{
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 79ea97d4797e..6414cbf00572 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -419,7 +419,6 @@ void __init setup_arch(char **cmdline_p)
stack_protections((unsigned long) init_task.stack);
setup_physmem(uml_physmem, uml_reserved, physmem_size);
- mem_total_pages(physmem_size, iomem_size);
uml_dtb_init();
read_initrd();
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index ac41b1e0940d..6d2f8cb9451e 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -650,9 +650,6 @@ void __init initmem_init(void)
memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
-#ifdef CONFIG_FLATMEM
- max_mapnr = IS_ENABLED(CONFIG_HIGHMEM) ? highend_pfn : max_low_pfn;
-#endif
__vmalloc_start_set = true;
printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 01577d33e602..9f1b0d5fccc7 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -164,7 +164,6 @@ void __init mem_init(void)
{
free_highpages();
- max_mapnr = max_pfn - ARCH_PFN_OFFSET;
high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
index 6d1fb6162ac1..a3b5029aebbd 100644
--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -19,11 +19,12 @@
#define __page_to_pfn(page) ((unsigned long)((page) - mem_map) + \
ARCH_PFN_OFFSET)
+/* avoid <linux/mm.h> include hell */
+extern unsigned long max_mapnr;
+
#ifndef pfn_valid
static inline int pfn_valid(unsigned long pfn)
{
- /* avoid <linux/mm.h> include hell */
- extern unsigned long max_mapnr;
unsigned long pfn_offset = ARCH_PFN_OFFSET;
return pfn >= pfn_offset && (pfn - pfn_offset) < max_mapnr;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7b1068ddcbb7..fdf20503850e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -45,17 +45,6 @@ extern int sysctl_page_lock_unfairness;
void mm_core_init(void);
void init_mm_internals(void);
-#ifndef CONFIG_NUMA /* Don't use mapnrs, do it properly */
-extern unsigned long max_mapnr;
-
-static inline void set_max_mapnr(unsigned long limit)
-{
- max_mapnr = limit;
-}
-#else
-static inline void set_max_mapnr(unsigned long limit) { }
-#endif
-
extern atomic_long_t _totalram_pages;
static inline unsigned long totalram_pages(void)
{
diff --git a/mm/memory.c b/mm/memory.c
index b4d3d4893267..126fdd3001e3 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -95,14 +95,6 @@
#warning Unfortunate NUMA and NUMA Balancing config, growing page-frame for last_cpupid.
#endif
-#ifndef CONFIG_NUMA
-unsigned long max_mapnr;
-EXPORT_SYMBOL(max_mapnr);
-
-struct page *mem_map;
-EXPORT_SYMBOL(mem_map);
-#endif
-
static vm_fault_t do_fault(struct vm_fault *vmf);
static vm_fault_t do_anonymous_page(struct vm_fault *vmf);
static bool vmf_pte_changed(struct vm_fault *vmf);
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 2630cc30147e..50a93714e1c6 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -36,6 +36,14 @@
#include <asm/setup.h>
+#ifndef CONFIG_NUMA
+unsigned long max_mapnr;
+EXPORT_SYMBOL(max_mapnr);
+
+struct page *mem_map;
+EXPORT_SYMBOL(mem_map);
+#endif
+
#ifdef CONFIG_DEBUG_MEMORY_INIT
int __meminitdata mminit_loglevel;
@@ -1617,7 +1625,7 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
offset = pgdat->node_start_pfn - start;
/*
- * The zone's endpoints aren't required to be MAX_PAGE_ORDER
+ * The zone's endpoints aren't required to be MAX_PAGE_ORDER
* aligned but the node_mem_map endpoints must be in order
* for the buddy allocator to function correctly.
*/
@@ -1633,14 +1641,15 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
pr_debug("%s: node %d, pgdat %08lx, node_mem_map %08lx\n",
__func__, pgdat->node_id, (unsigned long)pgdat,
(unsigned long)pgdat->node_mem_map);
-#ifndef CONFIG_NUMA
+
/* the global mem_map is just set as node 0's */
- if (pgdat == NODE_DATA(0)) {
- mem_map = NODE_DATA(0)->node_mem_map;
- if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
- mem_map -= offset;
- }
-#endif
+ WARN_ON(pgdat != NODE_DATA(0));
+
+ mem_map = pgdat->node_mem_map;
+ if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
+ mem_map -= offset;
+
+ max_mapnr = end - start;
}
#else
static inline void alloc_node_mem_map(struct pglist_data *pgdat) { }
diff --git a/mm/nommu.c b/mm/nommu.c
index baa79abdaf03..f0209dd26dfa 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -44,16 +44,12 @@
void *high_memory;
EXPORT_SYMBOL(high_memory);
-struct page *mem_map;
-unsigned long max_mapnr;
-EXPORT_SYMBOL(max_mapnr);
unsigned long highest_memmap_pfn;
int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
int heap_stack_gap = 0;
atomic_long_t mmap_pages_allocated;
-EXPORT_SYMBOL(mem_map);
/* list of mapped, potentially shareable regions */
static struct kmem_cache *vm_region_jar;
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 09/13] arch, mm: set max_mapnr when allocating memory map for FLATMEM
2025-03-13 13:49 ` [PATCH v2 09/13] arch, mm: set max_mapnr when allocating memory map for FLATMEM Mike Rapoport
@ 2025-03-14 9:25 ` Christophe Leroy
2025-04-08 5:48 ` Christophe Leroy
0 siblings, 1 reply; 24+ messages in thread
From: Christophe Leroy @ 2025-03-14 9:25 UTC (permalink / raw)
To: Mike Rapoport, Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Palmer Dabbelt, Peter Zijlstra, Richard Weinberger,
Russell King, Stafford Horne, Thomas Bogendoerfer,
Thomas Gleixner, Vasily Gorbik, Vineet Gupta, Will Deacon,
linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-mips,
linux-openrisc, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, sparclinux, linux-um, linux-arch, linux-mm,
x86
Le 13/03/2025 à 14:49, Mike Rapoport a écrit :
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> max_mapnr is essentially the size of the memory map for systems that use
> FLATMEM. There is no reason to calculate it in each and every architecture
> when it's anyway calculated in alloc_node_mem_map().
>
> Drop setting of max_mapnr from architecture code and set it once in
> alloc_node_mem_map().
As far as I can see alloc_node_mem_map() is called quite late.
I fear that it will regress commit daa9ada2093e ("powerpc/mm: Fix boot
crash with FLATMEM")
Can you check ?
Christophe
>
> While on it, move definition of mem_map and max_mapnr to mm/mm_init.c so
> there won't be two copies for MMU and !MMU variants.
>
> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> arch/alpha/mm/init.c | 1 -
> arch/arc/mm/init.c | 5 -----
> arch/arm/mm/init.c | 2 --
> arch/csky/mm/init.c | 4 ----
> arch/loongarch/mm/init.c | 1 -
> arch/microblaze/mm/init.c | 4 ----
> arch/mips/mm/init.c | 8 --------
> arch/nios2/kernel/setup.c | 1 -
> arch/nios2/mm/init.c | 2 +-
> arch/openrisc/mm/init.c | 1 -
> arch/parisc/mm/init.c | 1 -
> arch/powerpc/kernel/setup-common.c | 2 --
> arch/riscv/mm/init.c | 1 -
> arch/s390/mm/init.c | 1 -
> arch/sh/mm/init.c | 1 -
> arch/sparc/mm/init_32.c | 1 -
> arch/um/include/shared/mem_user.h | 1 -
> arch/um/kernel/physmem.c | 12 ------------
> arch/um/kernel/um_arch.c | 1 -
> arch/x86/mm/init_32.c | 3 ---
> arch/xtensa/mm/init.c | 1 -
> include/asm-generic/memory_model.h | 5 +++--
> include/linux/mm.h | 11 -----------
> mm/memory.c | 8 --------
> mm/mm_init.c | 25 +++++++++++++++++--------
> mm/nommu.c | 4 ----
> 26 files changed, 21 insertions(+), 86 deletions(-)
>
> diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
> index 61c2198b1359..ec0eeae9c653 100644
> --- a/arch/alpha/mm/init.c
> +++ b/arch/alpha/mm/init.c
> @@ -276,7 +276,6 @@ srm_paging_stop (void)
> void __init
> mem_init(void)
> {
> - set_max_mapnr(max_low_pfn);
> high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
> memblock_free_all();
> }
> diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
> index 6a71b23f1383..7ef883d58dc1 100644
> --- a/arch/arc/mm/init.c
> +++ b/arch/arc/mm/init.c
> @@ -154,11 +154,6 @@ void __init setup_arch_memory(void)
>
> arch_pfn_offset = min(min_low_pfn, min_high_pfn);
> kmap_init();
> -
> -#else /* CONFIG_HIGHMEM */
> - /* pfn_valid() uses this when FLATMEM=y and HIGHMEM=n */
> - max_mapnr = max_low_pfn - min_low_pfn;
> -
> #endif /* CONFIG_HIGHMEM */
>
> free_area_init(max_zone_pfn);
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 9aec1cb2386f..d4bcc745a044 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -275,8 +275,6 @@ void __init mem_init(void)
> swiotlb_init(max_pfn > arm_dma_pfn_limit, SWIOTLB_VERBOSE);
> #endif
>
> - set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
> -
> #ifdef CONFIG_SA1111
> /* now that our DMA memory is actually so designated, we can free it */
> memblock_phys_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
> diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
> index ab51acbc19b2..ba6694d6170a 100644
> --- a/arch/csky/mm/init.c
> +++ b/arch/csky/mm/init.c
> @@ -46,10 +46,6 @@ void __init mem_init(void)
> {
> #ifdef CONFIG_HIGHMEM
> unsigned long tmp;
> -
> - set_max_mapnr(highend_pfn - ARCH_PFN_OFFSET);
> -#else
> - set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
> #endif
> high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
>
> diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
> index ca5aa5f46a9f..00449df50db1 100644
> --- a/arch/loongarch/mm/init.c
> +++ b/arch/loongarch/mm/init.c
> @@ -78,7 +78,6 @@ void __init paging_init(void)
>
> void __init mem_init(void)
> {
> - max_mapnr = max_low_pfn;
> high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
>
> memblock_free_all();
> diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
> index 4520c5741579..857cd2b44bcf 100644
> --- a/arch/microblaze/mm/init.c
> +++ b/arch/microblaze/mm/init.c
> @@ -104,17 +104,13 @@ void __init setup_memory(void)
> *
> * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
> * max_low_pfn
> - * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
> */
>
> /* memory start is from the kernel end (aligned) to higher addr */
> min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
> - /* RAM is assumed contiguous */
> - max_mapnr = memory_size >> PAGE_SHIFT;
> max_low_pfn = ((u64)memory_start + (u64)lowmem_size) >> PAGE_SHIFT;
> max_pfn = ((u64)memory_start + (u64)memory_size) >> PAGE_SHIFT;
>
> - pr_info("%s: max_mapnr: %#lx\n", __func__, max_mapnr);
> pr_info("%s: min_low_pfn: %#lx\n", __func__, min_low_pfn);
> pr_info("%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
> pr_info("%s: max_pfn: %#lx\n", __func__, max_pfn);
> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
> index 820e35a59d4d..eb61a73520a0 100644
> --- a/arch/mips/mm/init.c
> +++ b/arch/mips/mm/init.c
> @@ -415,15 +415,7 @@ void __init paging_init(void)
> " %ldk highmem ignored\n",
> (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10));
> max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
> -
> - max_mapnr = max_low_pfn;
> - } else if (highend_pfn) {
> - max_mapnr = highend_pfn;
> - } else {
> - max_mapnr = max_low_pfn;
> }
> -#else
> - max_mapnr = max_low_pfn;
> #endif
> high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
>
> diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
> index a4cffbfc1399..2a40150142c3 100644
> --- a/arch/nios2/kernel/setup.c
> +++ b/arch/nios2/kernel/setup.c
> @@ -158,7 +158,6 @@ void __init setup_arch(char **cmdline_p)
> *cmdline_p = boot_command_line;
>
> find_limits(&min_low_pfn, &max_low_pfn, &max_pfn);
> - max_mapnr = max_low_pfn;
>
> memblock_reserve(__pa_symbol(_stext), _end - _stext);
> #ifdef CONFIG_BLK_DEV_INITRD
> diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
> index aa692ad30044..3cafa87ead9e 100644
> --- a/arch/nios2/mm/init.c
> +++ b/arch/nios2/mm/init.c
> @@ -51,7 +51,7 @@ void __init paging_init(void)
> pagetable_init();
> pgd_current = swapper_pg_dir;
>
> - max_zone_pfn[ZONE_NORMAL] = max_mapnr;
> + max_zone_pfn[ZONE_NORMAL] = max_low_pfn;
>
> /* pass the memory from the bootmem allocator to the main allocator */
> free_area_init(max_zone_pfn);
> diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
> index d0cb1a0126f9..9093c336e158 100644
> --- a/arch/openrisc/mm/init.c
> +++ b/arch/openrisc/mm/init.c
> @@ -193,7 +193,6 @@ void __init mem_init(void)
> {
> BUG_ON(!mem_map);
>
> - max_mapnr = max_low_pfn;
> high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
>
> /* clear the zero-page */
> diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
> index 61c0a2477072..2cdfc0b1195c 100644
> --- a/arch/parisc/mm/init.c
> +++ b/arch/parisc/mm/init.c
> @@ -563,7 +563,6 @@ void __init mem_init(void)
> #endif
>
> high_memory = __va((max_pfn << PAGE_SHIFT));
> - set_max_mapnr(max_low_pfn);
> memblock_free_all();
>
> #ifdef CONFIG_PA11
> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> index a08b0ede4e64..68d47c53876c 100644
> --- a/arch/powerpc/kernel/setup-common.c
> +++ b/arch/powerpc/kernel/setup-common.c
> @@ -957,8 +957,6 @@ void __init setup_arch(char **cmdline_p)
>
> /* Parse memory topology */
> mem_topology_setup();
> - /* Set max_mapnr before paging_init() */
> - set_max_mapnr(max_pfn);
> high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
>
> /*
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 15b2eda4c364..157c9ca51541 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -298,7 +298,6 @@ static void __init setup_bootmem(void)
> high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
>
> dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
> - set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
>
> reserve_initrd_mem();
>
> diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
> index f8333feb6a7e..36fed6dffb38 100644
> --- a/arch/s390/mm/init.c
> +++ b/arch/s390/mm/init.c
> @@ -159,7 +159,6 @@ void __init mem_init(void)
> cpumask_set_cpu(0, &init_mm.context.cpu_attach_mask);
> cpumask_set_cpu(0, mm_cpumask(&init_mm));
>
> - set_max_mapnr(max_low_pfn);
> high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
>
> pv_init();
> diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
> index 289a2fecebef..72aea5cd1b85 100644
> --- a/arch/sh/mm/init.c
> +++ b/arch/sh/mm/init.c
> @@ -290,7 +290,6 @@ void __init paging_init(void)
> */
> max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
> min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
> - set_max_mapnr(max_low_pfn - min_low_pfn);
>
> nodes_clear(node_online_map);
>
> diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
> index d96a14ffceeb..6b58da14edc6 100644
> --- a/arch/sparc/mm/init_32.c
> +++ b/arch/sparc/mm/init_32.c
> @@ -275,7 +275,6 @@ void __init mem_init(void)
>
> taint_real_pages();
>
> - max_mapnr = last_valid_pfn - pfn_base;
> high_memory = __va(max_low_pfn << PAGE_SHIFT);
> memblock_free_all();
>
> diff --git a/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h
> index adfa08062f88..d4727efcf23d 100644
> --- a/arch/um/include/shared/mem_user.h
> +++ b/arch/um/include/shared/mem_user.h
> @@ -47,7 +47,6 @@ extern int iomem_size;
> #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
>
> extern unsigned long find_iomem(char *driver, unsigned long *len_out);
> -extern void mem_total_pages(unsigned long physmem, unsigned long iomem);
> extern void setup_physmem(unsigned long start, unsigned long usable,
> unsigned long len);
> extern void map_memory(unsigned long virt, unsigned long phys,
> diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
> index a74f17b033c4..af02b5f9911d 100644
> --- a/arch/um/kernel/physmem.c
> +++ b/arch/um/kernel/physmem.c
> @@ -22,18 +22,6 @@ static int physmem_fd = -1;
> unsigned long high_physmem;
> EXPORT_SYMBOL(high_physmem);
>
> -void __init mem_total_pages(unsigned long physmem, unsigned long iomem)
> -{
> - unsigned long phys_pages, iomem_pages, total_pages;
> -
> - phys_pages = physmem >> PAGE_SHIFT;
> - iomem_pages = iomem >> PAGE_SHIFT;
> -
> - total_pages = phys_pages + iomem_pages;
> -
> - max_mapnr = total_pages;
> -}
> -
> void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
> int r, int w, int x)
> {
> diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
> index 79ea97d4797e..6414cbf00572 100644
> --- a/arch/um/kernel/um_arch.c
> +++ b/arch/um/kernel/um_arch.c
> @@ -419,7 +419,6 @@ void __init setup_arch(char **cmdline_p)
>
> stack_protections((unsigned long) init_task.stack);
> setup_physmem(uml_physmem, uml_reserved, physmem_size);
> - mem_total_pages(physmem_size, iomem_size);
> uml_dtb_init();
> read_initrd();
>
> diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
> index ac41b1e0940d..6d2f8cb9451e 100644
> --- a/arch/x86/mm/init_32.c
> +++ b/arch/x86/mm/init_32.c
> @@ -650,9 +650,6 @@ void __init initmem_init(void)
>
> memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
>
> -#ifdef CONFIG_FLATMEM
> - max_mapnr = IS_ENABLED(CONFIG_HIGHMEM) ? highend_pfn : max_low_pfn;
> -#endif
> __vmalloc_start_set = true;
>
> printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
> diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
> index 01577d33e602..9f1b0d5fccc7 100644
> --- a/arch/xtensa/mm/init.c
> +++ b/arch/xtensa/mm/init.c
> @@ -164,7 +164,6 @@ void __init mem_init(void)
> {
> free_highpages();
>
> - max_mapnr = max_pfn - ARCH_PFN_OFFSET;
> high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
>
> memblock_free_all();
> diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
> index 6d1fb6162ac1..a3b5029aebbd 100644
> --- a/include/asm-generic/memory_model.h
> +++ b/include/asm-generic/memory_model.h
> @@ -19,11 +19,12 @@
> #define __page_to_pfn(page) ((unsigned long)((page) - mem_map) + \
> ARCH_PFN_OFFSET)
>
> +/* avoid <linux/mm.h> include hell */
> +extern unsigned long max_mapnr;
> +
> #ifndef pfn_valid
> static inline int pfn_valid(unsigned long pfn)
> {
> - /* avoid <linux/mm.h> include hell */
> - extern unsigned long max_mapnr;
> unsigned long pfn_offset = ARCH_PFN_OFFSET;
>
> return pfn >= pfn_offset && (pfn - pfn_offset) < max_mapnr;
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 7b1068ddcbb7..fdf20503850e 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -45,17 +45,6 @@ extern int sysctl_page_lock_unfairness;
> void mm_core_init(void);
> void init_mm_internals(void);
>
> -#ifndef CONFIG_NUMA /* Don't use mapnrs, do it properly */
> -extern unsigned long max_mapnr;
> -
> -static inline void set_max_mapnr(unsigned long limit)
> -{
> - max_mapnr = limit;
> -}
> -#else
> -static inline void set_max_mapnr(unsigned long limit) { }
> -#endif
> -
> extern atomic_long_t _totalram_pages;
> static inline unsigned long totalram_pages(void)
> {
> diff --git a/mm/memory.c b/mm/memory.c
> index b4d3d4893267..126fdd3001e3 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -95,14 +95,6 @@
> #warning Unfortunate NUMA and NUMA Balancing config, growing page-frame for last_cpupid.
> #endif
>
> -#ifndef CONFIG_NUMA
> -unsigned long max_mapnr;
> -EXPORT_SYMBOL(max_mapnr);
> -
> -struct page *mem_map;
> -EXPORT_SYMBOL(mem_map);
> -#endif
> -
> static vm_fault_t do_fault(struct vm_fault *vmf);
> static vm_fault_t do_anonymous_page(struct vm_fault *vmf);
> static bool vmf_pte_changed(struct vm_fault *vmf);
> diff --git a/mm/mm_init.c b/mm/mm_init.c
> index 2630cc30147e..50a93714e1c6 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -36,6 +36,14 @@
>
> #include <asm/setup.h>
>
> +#ifndef CONFIG_NUMA
> +unsigned long max_mapnr;
> +EXPORT_SYMBOL(max_mapnr);
> +
> +struct page *mem_map;
> +EXPORT_SYMBOL(mem_map);
> +#endif
> +
> #ifdef CONFIG_DEBUG_MEMORY_INIT
> int __meminitdata mminit_loglevel;
>
> @@ -1617,7 +1625,7 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
> start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
> offset = pgdat->node_start_pfn - start;
> /*
> - * The zone's endpoints aren't required to be MAX_PAGE_ORDER
> + * The zone's endpoints aren't required to be MAX_PAGE_ORDER
> * aligned but the node_mem_map endpoints must be in order
> * for the buddy allocator to function correctly.
> */
> @@ -1633,14 +1641,15 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
> pr_debug("%s: node %d, pgdat %08lx, node_mem_map %08lx\n",
> __func__, pgdat->node_id, (unsigned long)pgdat,
> (unsigned long)pgdat->node_mem_map);
> -#ifndef CONFIG_NUMA
> +
> /* the global mem_map is just set as node 0's */
> - if (pgdat == NODE_DATA(0)) {
> - mem_map = NODE_DATA(0)->node_mem_map;
> - if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
> - mem_map -= offset;
> - }
> -#endif
> + WARN_ON(pgdat != NODE_DATA(0));
> +
> + mem_map = pgdat->node_mem_map;
> + if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
> + mem_map -= offset;
> +
> + max_mapnr = end - start;
> }
> #else
> static inline void alloc_node_mem_map(struct pglist_data *pgdat) { }
> diff --git a/mm/nommu.c b/mm/nommu.c
> index baa79abdaf03..f0209dd26dfa 100644
> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -44,16 +44,12 @@
>
> void *high_memory;
> EXPORT_SYMBOL(high_memory);
> -struct page *mem_map;
> -unsigned long max_mapnr;
> -EXPORT_SYMBOL(max_mapnr);
> unsigned long highest_memmap_pfn;
> int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
> int heap_stack_gap = 0;
>
> atomic_long_t mmap_pages_allocated;
>
> -EXPORT_SYMBOL(mem_map);
>
> /* list of mapped, potentially shareable regions */
> static struct kmem_cache *vm_region_jar;
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 09/13] arch, mm: set max_mapnr when allocating memory map for FLATMEM
2025-03-14 9:25 ` Christophe Leroy
@ 2025-04-08 5:48 ` Christophe Leroy
0 siblings, 0 replies; 24+ messages in thread
From: Christophe Leroy @ 2025-04-08 5:48 UTC (permalink / raw)
To: Mike Rapoport, Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Palmer Dabbelt, Peter Zijlstra, Richard Weinberger,
Russell King, Stafford Horne, Thomas Bogendoerfer,
Thomas Gleixner, Vasily Gorbik, Vineet Gupta, Will Deacon,
linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-mips,
linux-openrisc, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, sparclinux, linux-um, linux-arch, linux-mm,
x86
Hi Mike,
Le 14/03/2025 à 10:25, Christophe Leroy a écrit :
>
>
> Le 13/03/2025 à 14:49, Mike Rapoport a écrit :
>> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>>
>> max_mapnr is essentially the size of the memory map for systems that use
>> FLATMEM. There is no reason to calculate it in each and every
>> architecture
>> when it's anyway calculated in alloc_node_mem_map().
>>
>> Drop setting of max_mapnr from architecture code and set it once in
>> alloc_node_mem_map().
>
> As far as I can see alloc_node_mem_map() is called quite late.
>
> I fear that it will regress commit daa9ada2093e ("powerpc/mm: Fix boot
> crash with FLATMEM")
>
> Can you check ?
I see this patch is now merged into mainline (v6.15-rc1). Have you been
able to check and/or analyse whether it doesn't regress the fix in
commit daa9ada2093e ("powerpc/mm: Fix boot crash with FLATMEM") ?
Thanks
Christophe
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (8 preceding siblings ...)
2025-03-13 13:49 ` [PATCH v2 09/13] arch, mm: set max_mapnr when allocating memory map for FLATMEM Mike Rapoport
@ 2025-03-13 13:50 ` Mike Rapoport
2025-05-16 15:28 ` Pratyush Yadav
2025-03-13 13:50 ` [PATCH v2 11/13] arch, mm: streamline HIGHMEM freeing Mike Rapoport
` (3 subsequent siblings)
13 siblings, 1 reply; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:50 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
high_memory defines upper bound on the directly mapped memory.
This bound is defined by the beginning of ZONE_HIGHMEM when a system has
high memory and by the end of memory otherwise.
All this is known to generic memory management initialization code that
can set high_memory while initializing core mm structures.
Add a generic calculation of high_memory to free_area_init() and remove
per-architecture calculation except for the architectures that set and
use high_memory earlier than that.
Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/alpha/mm/init.c | 1 -
arch/arc/mm/init.c | 2 --
arch/arm64/mm/init.c | 2 --
arch/csky/mm/init.c | 1 -
arch/hexagon/mm/init.c | 6 ------
arch/loongarch/kernel/numa.c | 1 -
arch/loongarch/mm/init.c | 2 --
arch/microblaze/mm/init.c | 2 --
arch/mips/mm/init.c | 2 --
arch/nios2/mm/init.c | 6 ------
arch/openrisc/mm/init.c | 2 --
arch/parisc/mm/init.c | 1 -
arch/riscv/mm/init.c | 1 -
arch/s390/mm/init.c | 2 --
arch/sh/mm/init.c | 7 -------
arch/sparc/mm/init_32.c | 1 -
arch/sparc/mm/init_64.c | 2 --
arch/um/kernel/um_arch.c | 1 -
arch/x86/kernel/setup.c | 2 --
arch/x86/mm/init_32.c | 3 ---
arch/x86/mm/numa_32.c | 3 ---
arch/xtensa/mm/init.c | 2 --
mm/memory.c | 8 --------
mm/mm_init.c | 30 ++++++++++++++++++++++++++++++
mm/nommu.c | 2 --
25 files changed, 30 insertions(+), 62 deletions(-)
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index ec0eeae9c653..3ab2d2f3c917 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -276,7 +276,6 @@ srm_paging_stop (void)
void __init
mem_init(void)
{
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
memblock_free_all();
}
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 7ef883d58dc1..05025122e965 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -150,8 +150,6 @@ void __init setup_arch_memory(void)
*/
max_zone_pfn[ZONE_HIGHMEM] = max_high_pfn;
- high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
-
arch_pfn_offset = min(min_low_pfn, min_high_pfn);
kmap_init();
#endif /* CONFIG_HIGHMEM */
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 9c0b8d9558fc..a48fcccd67fa 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -314,8 +314,6 @@ void __init arm64_memblock_init(void)
}
early_init_fdt_scan_reserved_mem();
-
- high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
}
void __init bootmem_init(void)
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index ba6694d6170a..a22801aa503a 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -47,7 +47,6 @@ void __init mem_init(void)
#ifdef CONFIG_HIGHMEM
unsigned long tmp;
#endif
- high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index 508bb6a8dcc9..d412c2314509 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -100,12 +100,6 @@ static void __init paging_init(void)
* initial kernel segment table's physical address.
*/
init_mm.context.ptbase = __pa(init_mm.pgd);
-
- /*
- * Start of high memory area. Will probably need something more
- * fancy if we... get more fancy.
- */
- high_memory = (void *)((bootmem_lastpg + 1) << PAGE_SHIFT);
}
#ifndef DMA_RESERVE
diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
index 84fe7f854820..8eb489725b1a 100644
--- a/arch/loongarch/kernel/numa.c
+++ b/arch/loongarch/kernel/numa.c
@@ -389,7 +389,6 @@ void __init paging_init(void)
void __init mem_init(void)
{
- high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
}
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 00449df50db1..6affa3609188 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -78,8 +78,6 @@ void __init paging_init(void)
void __init mem_init(void)
{
- high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
-
memblock_free_all();
}
#endif /* !CONFIG_NUMA */
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 857cd2b44bcf..7e2e342e84c5 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -120,8 +120,6 @@ void __init setup_memory(void)
void __init mem_init(void)
{
- high_memory = (void *)__va(memory_start + lowmem_size - 1);
-
/* this will put all memory onto the freelists */
memblock_free_all();
#ifdef CONFIG_HIGHMEM
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index eb61a73520a0..ed9dde6a00f7 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -417,7 +417,6 @@ void __init paging_init(void)
max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
}
#endif
- high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
free_area_init(max_zone_pfns);
}
@@ -469,7 +468,6 @@ void __init mem_init(void)
#else /* CONFIG_NUMA */
void __init mem_init(void)
{
- high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
setup_zero_pages(); /* This comes from node 0 */
memblock_free_all();
}
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index 3cafa87ead9e..4ba8dfa0d238 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -62,12 +62,6 @@ void __init paging_init(void)
void __init mem_init(void)
{
- unsigned long end_mem = memory_end; /* this must not include
- kernel stack at top */
-
- end_mem &= PAGE_MASK;
- high_memory = __va(end_mem);
-
/* this will put all memory onto the freelists */
memblock_free_all();
}
diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
index 9093c336e158..72c5952607ac 100644
--- a/arch/openrisc/mm/init.c
+++ b/arch/openrisc/mm/init.c
@@ -193,8 +193,6 @@ void __init mem_init(void)
{
BUG_ON(!mem_map);
- high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
-
/* clear the zero-page */
memset((void *)empty_zero_page, 0, PAGE_SIZE);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 2cdfc0b1195c..4fbe354dc9b4 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -562,7 +562,6 @@ void __init mem_init(void)
BUILD_BUG_ON(TMPALIAS_MAP_START >= 0x80000000);
#endif
- high_memory = __va((max_pfn << PAGE_SHIFT));
memblock_free_all();
#ifdef CONFIG_PA11
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 157c9ca51541..ac6d41e86243 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -295,7 +295,6 @@ static void __init setup_bootmem(void)
phys_ram_end = memblock_end_of_DRAM();
min_low_pfn = PFN_UP(phys_ram_base);
max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end);
- high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 36fed6dffb38..0c485884d373 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -159,8 +159,6 @@ void __init mem_init(void)
cpumask_set_cpu(0, &init_mm.context.cpu_attach_mask);
cpumask_set_cpu(0, mm_cpumask(&init_mm));
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
pv_init();
kfence_split_mapping();
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 72aea5cd1b85..6d459ffba4bc 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -330,13 +330,6 @@ unsigned int mem_init_done = 0;
void __init mem_init(void)
{
- pg_data_t *pgdat;
-
- high_memory = NULL;
- for_each_online_pgdat(pgdat)
- high_memory = max_t(void *, high_memory,
- __va(pgdat_end_pfn(pgdat) << PAGE_SHIFT));
-
memblock_free_all();
/* Set this up early, so we can take care of the zero page */
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 6b58da14edc6..81a468a9c223 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -275,7 +275,6 @@ void __init mem_init(void)
taint_real_pages();
- high_memory = __va(max_low_pfn << PAGE_SHIFT);
memblock_free_all();
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 05882bca5b73..34d46adb9571 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2505,8 +2505,6 @@ static void __init register_page_bootmem_info(void)
}
void __init mem_init(void)
{
- high_memory = __va(last_valid_pfn << PAGE_SHIFT);
-
memblock_free_all();
/*
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 6414cbf00572..f24a3ce37ab7 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -385,7 +385,6 @@ int __init linux_main(int argc, char **argv, char **envp)
high_physmem = uml_physmem + physmem_size;
end_iomem = high_physmem + iomem_size;
- high_memory = (void *) end_iomem;
start_vm = VMALLOC_START;
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cebee310e200..5c9ec876915e 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -972,8 +972,6 @@ void __init setup_arch(char **cmdline_p)
max_low_pfn = e820__end_of_low_ram_pfn();
else
max_low_pfn = max_pfn;
-
- high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
#endif
/* Find and reserve MPTABLE area */
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 6d2f8cb9451e..801b659ead0c 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -643,9 +643,6 @@ void __init initmem_init(void)
highstart_pfn = max_low_pfn;
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
pages_to_mb(highend_pfn - highstart_pfn));
- high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
-#else
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
#endif
memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index 65fda406e6f2..442ef3facff0 100644
--- a/arch/x86/mm/numa_32.c
+++ b/arch/x86/mm/numa_32.c
@@ -41,9 +41,6 @@ void __init initmem_init(void)
highstart_pfn = max_low_pfn;
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
pages_to_mb(highend_pfn - highstart_pfn));
- high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
-#else
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
#endif
printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
pages_to_mb(max_low_pfn));
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 9f1b0d5fccc7..9b662477b3d4 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -164,8 +164,6 @@ void __init mem_init(void)
{
free_highpages();
- high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
-
memblock_free_all();
}
diff --git a/mm/memory.c b/mm/memory.c
index 126fdd3001e3..2351f3f6b9ed 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -113,14 +113,6 @@ static __always_inline bool vmf_orig_pte_uffd_wp(struct vm_fault *vmf)
return pte_marker_uffd_wp(vmf->orig_pte);
}
-/*
- * A number of key systems in x86 including ioremap() rely on the assumption
- * that high_memory defines the upper bound on direct map memory, then end
- * of ZONE_NORMAL.
- */
-void *high_memory;
-EXPORT_SYMBOL(high_memory);
-
/*
* Randomize the address space (stacks, mmaps, brk, etc.).
*
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 50a93714e1c6..61ac0cea711a 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -44,6 +44,13 @@ struct page *mem_map;
EXPORT_SYMBOL(mem_map);
#endif
+/*
+ * high_memory defines the upper bound on direct map memory, then end
+ * of ZONE_NORMAL.
+ */
+void *high_memory;
+EXPORT_SYMBOL(high_memory);
+
#ifdef CONFIG_DEBUG_MEMORY_INIT
int __meminitdata mminit_loglevel;
@@ -1756,6 +1763,27 @@ static bool arch_has_descending_max_zone_pfns(void)
return IS_ENABLED(CONFIG_ARC) && !IS_ENABLED(CONFIG_ARC_HAS_PAE40);
}
+static void set_high_memory(void)
+{
+ phys_addr_t highmem = memblock_end_of_DRAM();
+
+ /*
+ * Some architectures (e.g. ARM) set high_memory very early and
+ * use it in arch setup code.
+ * If an architecture already set high_memory don't overwrite it
+ */
+ if (high_memory)
+ return;
+
+#ifdef CONFIG_HIGHMEM
+ if (arch_has_descending_max_zone_pfns() ||
+ highmem > PFN_PHYS(arch_zone_lowest_possible_pfn[ZONE_HIGHMEM]))
+ highmem = PFN_PHYS(arch_zone_lowest_possible_pfn[ZONE_HIGHMEM]);
+#endif
+
+ high_memory = phys_to_virt(highmem - 1) + 1;
+}
+
/**
* free_area_init - Initialise all pg_data_t and zone data
* @max_zone_pfn: an array of max PFNs for each zone
@@ -1875,6 +1903,8 @@ void __init free_area_init(unsigned long *max_zone_pfn)
/* disable hash distribution for systems with a single node */
fixup_hashdist();
+
+ set_high_memory();
}
/**
diff --git a/mm/nommu.c b/mm/nommu.c
index f0209dd26dfa..b9783638fbd4 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -42,8 +42,6 @@
#include <asm/mmu_context.h>
#include "internal.h"
-void *high_memory;
-EXPORT_SYMBOL(high_memory);
unsigned long highest_memmap_pfn;
int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
int heap_stack_gap = 0;
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()
2025-03-13 13:50 ` [PATCH v2 10/13] arch, mm: set high_memory in free_area_init() Mike Rapoport
@ 2025-05-16 15:28 ` Pratyush Yadav
2025-05-16 17:01 ` Mike Rapoport
0 siblings, 1 reply; 24+ messages in thread
From: Pratyush Yadav @ 2025-05-16 15:28 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Geert Uytterhoeven, Gerald Schaefer, Guo Ren,
Heiko Carstens, Helge Deller, Huacai Chen, Ingo Molnar,
Jiaxun Yang, Johannes Berg, John Paul Adrian Glaubitz,
Madhavan Srinivasan, Mark Brown, Matt Turner, Max Filippov,
Michael Ellerman, Michal Simek, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, Praveen Kumar, linux-alpha, linux-kernel,
linux-snps-arc, linux-arm-kernel, linux-csky, linux-hexagon,
loongarch, linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
Hi Mike, Andrew,
On Thu, Mar 13 2025, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> high_memory defines upper bound on the directly mapped memory.
> This bound is defined by the beginning of ZONE_HIGHMEM when a system has
> high memory and by the end of memory otherwise.
>
> All this is known to generic memory management initialization code that
> can set high_memory while initializing core mm structures.
>
> Add a generic calculation of high_memory to free_area_init() and remove
> per-architecture calculation except for the architectures that set and
> use high_memory earlier than that.
>
> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> arch/alpha/mm/init.c | 1 -
> arch/arc/mm/init.c | 2 --
> arch/arm64/mm/init.c | 2 --
> arch/csky/mm/init.c | 1 -
> arch/hexagon/mm/init.c | 6 ------
> arch/loongarch/kernel/numa.c | 1 -
> arch/loongarch/mm/init.c | 2 --
> arch/microblaze/mm/init.c | 2 --
> arch/mips/mm/init.c | 2 --
> arch/nios2/mm/init.c | 6 ------
> arch/openrisc/mm/init.c | 2 --
> arch/parisc/mm/init.c | 1 -
> arch/riscv/mm/init.c | 1 -
> arch/s390/mm/init.c | 2 --
> arch/sh/mm/init.c | 7 -------
> arch/sparc/mm/init_32.c | 1 -
> arch/sparc/mm/init_64.c | 2 --
> arch/um/kernel/um_arch.c | 1 -
> arch/x86/kernel/setup.c | 2 --
> arch/x86/mm/init_32.c | 3 ---
> arch/x86/mm/numa_32.c | 3 ---
> arch/xtensa/mm/init.c | 2 --
> mm/memory.c | 8 --------
> mm/mm_init.c | 30 ++++++++++++++++++++++++++++++
> mm/nommu.c | 2 --
> 25 files changed, 30 insertions(+), 62 deletions(-)
This patch causes a BUG() when built with CONFIG_DEBUG_VIRTUAL and
passing in the cma= commandline parameter:
------------[ cut here ]------------
kernel BUG at arch/x86/mm/physaddr.c:23!
ception 0x06 IP 10:ffffffff812ebbf8 error 0 cr2 0xffff88903ffff000
CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc6+ #231 PREEMPT(undef)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014
RIP: 0010:__phys_addr+0x58/0x60
Code: 01 48 89 c2 48 d3 ea 48 85 d2 75 05 e9 91 52 cf 00 0f 0b 48 3d ff ff ff 1f 77 0f 48 8b 05 20 54 55 01 48 01 d0 e9 78 52 cf 00 <0f> 0b 90 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90
RSP: 0000:ffffffff82803dd8 EFLAGS: 00010006 ORIG_RAX: 0000000000000000
RAX: 000000007fffffff RBX: 00000000ffffffff RCX: 0000000000000000
RDX: 000000007fffffff RSI: 0000000280000000 RDI: ffffffffffffffff
RBP: ffffffff82803e68 R08: 0000000000000000 R09: 0000000000000000
R10: ffffffff83153180 R11: ffffffff82803e48 R12: ffffffff83c9aed0
R13: 0000000000000000 R14: 0000001040000000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:0000000000000000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff88903ffff000 CR3: 0000000002838000 CR4: 00000000000000b0
Call Trace:
<TASK>
? __cma_declare_contiguous_nid+0x6e/0x340
? cma_declare_contiguous_nid+0x33/0x70
? dma_contiguous_reserve_area+0x2f/0x70
? setup_arch+0x6f1/0x870
? start_kernel+0x52/0x4b0
? x86_64_start_reservations+0x29/0x30
? x86_64_start_kernel+0x7c/0x80
? common_startup_64+0x13e/0x141
The reason is that __cma_declare_contiguous_nid() does:
highmem_start = __pa(high_memory - 1) + 1;
If dma_contiguous_reserve_area() (or any other CMA declaration) is
called before free_area_init(), high_memory is uninitialized. Without
CONFIG_DEBUG_VIRTUAL, it will likely work but use the wrong value for
highmem_start.
Among the architectures this patch touches, the below call
dma_contiguous_reserve_area() _before_ free_area_init():
- x86
- s390
- mips
- riscv
- xtensa
- loongarch
- csky
The below call it _after_ free_area_init():
- arm64
And the below don't call it at all:
- sparc
- nios2
- openrisc
- hexagon
- sh
- um
- alpha
One possible fix would be to move the calls to
dma_contiguous_reserve_area() after free_area_init(). On x86, it would
look like the diff below. The obvious downside is that moving the call
later increases the chances of allocation failure. I'm not sure how much
that actually matters, but at least on x86, that means crash kernel and
hugetlb reservations go before DMA reservation. Also, adding a patch
like that at rc7 is a bit risky.
The other option would be to revert this. I tried a revert, but it isn't
trivial. It runs into merge conflicts in pretty much all of the arch
files. Maybe reverting patches 11, 12, and 13 as well would make it
easier but I didn't try that.
Which option should we take? If we want to move
dma_contiguous_reserve_area() a bit further down the line then I can
send a patch doing that on the rest of the architectures. Otherwise I
can try my hand at the revert.
--- 8< ---
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 9d2a13b37833..ca6928dde0c9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1160,7 +1160,6 @@ void __init setup_arch(char **cmdline_p)
x86_flattree_get_config();
initmem_init();
- dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
if (boot_cpu_has(X86_FEATURE_GBPAGES)) {
hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
@@ -1178,6 +1177,8 @@ void __init setup_arch(char **cmdline_p)
x86_init.paging.pagetable_init();
+ dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
+
kasan_init();
/*
--
Regards,
Pratyush Yadav
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()
2025-05-16 15:28 ` Pratyush Yadav
@ 2025-05-16 17:01 ` Mike Rapoport
2025-05-19 15:54 ` Alexandre Ghiti
0 siblings, 1 reply; 24+ messages in thread
From: Mike Rapoport @ 2025-05-16 17:01 UTC (permalink / raw)
To: Pratyush Yadav
Cc: Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Geert Uytterhoeven, Gerald Schaefer, Guo Ren,
Heiko Carstens, Helge Deller, Huacai Chen, Ingo Molnar,
Jiaxun Yang, Johannes Berg, John Paul Adrian Glaubitz,
Madhavan Srinivasan, Mark Brown, Matt Turner, Max Filippov,
Michael Ellerman, Michal Simek, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, Praveen Kumar, linux-alpha, linux-kernel,
linux-snps-arc, linux-arm-kernel, linux-csky, linux-hexagon,
loongarch, linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
Hi Pratyush,
On Fri, May 16, 2025 at 05:28:17PM +0200, Pratyush Yadav wrote:
> Hi Mike, Andrew,
>
> On Thu, Mar 13 2025, Mike Rapoport wrote:
>
> > From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
> >
> > high_memory defines upper bound on the directly mapped memory.
> > This bound is defined by the beginning of ZONE_HIGHMEM when a system has
> > high memory and by the end of memory otherwise.
> >
> > All this is known to generic memory management initialization code that
> > can set high_memory while initializing core mm structures.
> >
> > Add a generic calculation of high_memory to free_area_init() and remove
> > per-architecture calculation except for the architectures that set and
> > use high_memory earlier than that.
> >
> > Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
> > Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> > ---
> > arch/alpha/mm/init.c | 1 -
> > arch/arc/mm/init.c | 2 --
> > arch/arm64/mm/init.c | 2 --
> > arch/csky/mm/init.c | 1 -
> > arch/hexagon/mm/init.c | 6 ------
> > arch/loongarch/kernel/numa.c | 1 -
> > arch/loongarch/mm/init.c | 2 --
> > arch/microblaze/mm/init.c | 2 --
> > arch/mips/mm/init.c | 2 --
> > arch/nios2/mm/init.c | 6 ------
> > arch/openrisc/mm/init.c | 2 --
> > arch/parisc/mm/init.c | 1 -
> > arch/riscv/mm/init.c | 1 -
> > arch/s390/mm/init.c | 2 --
> > arch/sh/mm/init.c | 7 -------
> > arch/sparc/mm/init_32.c | 1 -
> > arch/sparc/mm/init_64.c | 2 --
> > arch/um/kernel/um_arch.c | 1 -
> > arch/x86/kernel/setup.c | 2 --
> > arch/x86/mm/init_32.c | 3 ---
> > arch/x86/mm/numa_32.c | 3 ---
> > arch/xtensa/mm/init.c | 2 --
> > mm/memory.c | 8 --------
> > mm/mm_init.c | 30 ++++++++++++++++++++++++++++++
> > mm/nommu.c | 2 --
> > 25 files changed, 30 insertions(+), 62 deletions(-)
>
> This patch causes a BUG() when built with CONFIG_DEBUG_VIRTUAL and
> passing in the cma= commandline parameter:
>
> ------------[ cut here ]------------
> kernel BUG at arch/x86/mm/physaddr.c:23!
> ception 0x06 IP 10:ffffffff812ebbf8 error 0 cr2 0xffff88903ffff000
> CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc6+ #231 PREEMPT(undef)
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014
> RIP: 0010:__phys_addr+0x58/0x60
> Code: 01 48 89 c2 48 d3 ea 48 85 d2 75 05 e9 91 52 cf 00 0f 0b 48 3d ff ff ff 1f 77 0f 48 8b 05 20 54 55 01 48 01 d0 e9 78 52 cf 00 <0f> 0b 90 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90
> RSP: 0000:ffffffff82803dd8 EFLAGS: 00010006 ORIG_RAX: 0000000000000000
> RAX: 000000007fffffff RBX: 00000000ffffffff RCX: 0000000000000000
> RDX: 000000007fffffff RSI: 0000000280000000 RDI: ffffffffffffffff
> RBP: ffffffff82803e68 R08: 0000000000000000 R09: 0000000000000000
> R10: ffffffff83153180 R11: ffffffff82803e48 R12: ffffffff83c9aed0
> R13: 0000000000000000 R14: 0000001040000000 R15: 0000000000000000
> FS: 0000000000000000(0000) GS:0000000000000000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: ffff88903ffff000 CR3: 0000000002838000 CR4: 00000000000000b0
> Call Trace:
> <TASK>
> ? __cma_declare_contiguous_nid+0x6e/0x340
> ? cma_declare_contiguous_nid+0x33/0x70
> ? dma_contiguous_reserve_area+0x2f/0x70
> ? setup_arch+0x6f1/0x870
> ? start_kernel+0x52/0x4b0
> ? x86_64_start_reservations+0x29/0x30
> ? x86_64_start_kernel+0x7c/0x80
> ? common_startup_64+0x13e/0x141
>
> The reason is that __cma_declare_contiguous_nid() does:
>
> highmem_start = __pa(high_memory - 1) + 1;
>
> If dma_contiguous_reserve_area() (or any other CMA declaration) is
> called before free_area_init(), high_memory is uninitialized. Without
> CONFIG_DEBUG_VIRTUAL, it will likely work but use the wrong value for
> highmem_start.
>
> Among the architectures this patch touches, the below call
> dma_contiguous_reserve_area() _before_ free_area_init():
>
> - x86
> - s390
> - mips
> - riscv
> - xtensa
> - loongarch
> - csky
For most of those this patch didn't really change anything because they
initialized high_memory in mem_init() which is a part of free_area_init().
In those cases cma just did
highmem_start = __pa(-1) + 1;
and everyone was happy :)
> The below call it _after_ free_area_init():
> - arm64
>
> And the below don't call it at all:
> - sparc
> - nios2
> - openrisc
> - hexagon
> - sh
> - um
> - alpha
>
> One possible fix would be to move the calls to
> dma_contiguous_reserve_area() after free_area_init(). On x86, it would
> look like the diff below. The obvious downside is that moving the call
> later increases the chances of allocation failure. I'm not sure how much
> that actually matters, but at least on x86, that means crash kernel and
> hugetlb reservations go before DMA reservation. Also, adding a patch
> like that at rc7 is a bit risky.
I don't think there's a risk of allocation failure, but moving things
around in setup_arch() is always risky :)
> The other option would be to revert this. I tried a revert, but it isn't
> trivial. It runs into merge conflicts in pretty much all of the arch
> files. Maybe reverting patches 11, 12, and 13 as well would make it
> easier but I didn't try that.
What I think we can do is to add this to mm/cma.c (not even compile tested)
diff --git a/mm/cma.c b/mm/cma.c
index 15632939f20a..c04be488b099 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -608,7 +608,10 @@ static int __init __cma_declare_contiguous_nid(phys_addr_t *basep,
* complain. Find the boundary by adding one to the last valid
* address.
*/
- highmem_start = __pa(high_memory - 1) + 1;
+ if (IS_ENABLED(CONFIG_HIGHMEM))
+ highmem_start = __pa(high_memory - 1) + 1;
+ else
+ highmem_start = memblock_end_of_DRAM();
pr_debug("%s(size %pa, base %pa, limit %pa alignment %pa)\n",
__func__, &size, &base, &limit, &alignment);
so that highmem_start in __cma_declare_contiguous_nid() will be always
correct for !HIGHMEM configs and then restore setting of highmem_start in
mips::paging_init() as mips is the only architecture that actually set
high_memory before free_area_init() before this patch.
(for 32 bit configs of x86 there alrady a fixup d893aca973c3 ("x86/mm: restore
early initialization of high_memory for 32-bits"))
--
Sincerely yours,
Mike.
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()
2025-05-16 17:01 ` Mike Rapoport
@ 2025-05-19 15:54 ` Alexandre Ghiti
2025-05-19 17:19 ` Mike Rapoport
0 siblings, 1 reply; 24+ messages in thread
From: Alexandre Ghiti @ 2025-05-19 15:54 UTC (permalink / raw)
To: Mike Rapoport, Pratyush Yadav
Cc: Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Geert Uytterhoeven, Gerald Schaefer, Guo Ren,
Heiko Carstens, Helge Deller, Huacai Chen, Ingo Molnar,
Jiaxun Yang, Johannes Berg, John Paul Adrian Glaubitz,
Madhavan Srinivasan, Mark Brown, Matt Turner, Max Filippov,
Michael Ellerman, Michal Simek, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, Praveen Kumar, linux-alpha, linux-kernel,
linux-snps-arc, linux-arm-kernel, linux-csky, linux-hexagon,
loongarch, linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
Hi Mike,
On 5/16/25 19:01, Mike Rapoport wrote:
> Hi Pratyush,
>
> On Fri, May 16, 2025 at 05:28:17PM +0200, Pratyush Yadav wrote:
>> Hi Mike, Andrew,
>>
>> On Thu, Mar 13 2025, Mike Rapoport wrote:
>>
>>> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>>>
>>> high_memory defines upper bound on the directly mapped memory.
>>> This bound is defined by the beginning of ZONE_HIGHMEM when a system has
>>> high memory and by the end of memory otherwise.
>>>
>>> All this is known to generic memory management initialization code that
>>> can set high_memory while initializing core mm structures.
>>>
>>> Add a generic calculation of high_memory to free_area_init() and remove
>>> per-architecture calculation except for the architectures that set and
>>> use high_memory earlier than that.
>>>
>>> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
>>> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
>>> ---
>>> arch/alpha/mm/init.c | 1 -
>>> arch/arc/mm/init.c | 2 --
>>> arch/arm64/mm/init.c | 2 --
>>> arch/csky/mm/init.c | 1 -
>>> arch/hexagon/mm/init.c | 6 ------
>>> arch/loongarch/kernel/numa.c | 1 -
>>> arch/loongarch/mm/init.c | 2 --
>>> arch/microblaze/mm/init.c | 2 --
>>> arch/mips/mm/init.c | 2 --
>>> arch/nios2/mm/init.c | 6 ------
>>> arch/openrisc/mm/init.c | 2 --
>>> arch/parisc/mm/init.c | 1 -
>>> arch/riscv/mm/init.c | 1 -
>>> arch/s390/mm/init.c | 2 --
>>> arch/sh/mm/init.c | 7 -------
>>> arch/sparc/mm/init_32.c | 1 -
>>> arch/sparc/mm/init_64.c | 2 --
>>> arch/um/kernel/um_arch.c | 1 -
>>> arch/x86/kernel/setup.c | 2 --
>>> arch/x86/mm/init_32.c | 3 ---
>>> arch/x86/mm/numa_32.c | 3 ---
>>> arch/xtensa/mm/init.c | 2 --
>>> mm/memory.c | 8 --------
>>> mm/mm_init.c | 30 ++++++++++++++++++++++++++++++
>>> mm/nommu.c | 2 --
>>> 25 files changed, 30 insertions(+), 62 deletions(-)
>> This patch causes a BUG() when built with CONFIG_DEBUG_VIRTUAL and
>> passing in the cma= commandline parameter:
>>
>> ------------[ cut here ]------------
>> kernel BUG at arch/x86/mm/physaddr.c:23!
>> ception 0x06 IP 10:ffffffff812ebbf8 error 0 cr2 0xffff88903ffff000
>> CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc6+ #231 PREEMPT(undef)
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014
>> RIP: 0010:__phys_addr+0x58/0x60
>> Code: 01 48 89 c2 48 d3 ea 48 85 d2 75 05 e9 91 52 cf 00 0f 0b 48 3d ff ff ff 1f 77 0f 48 8b 05 20 54 55 01 48 01 d0 e9 78 52 cf 00 <0f> 0b 90 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90
>> RSP: 0000:ffffffff82803dd8 EFLAGS: 00010006 ORIG_RAX: 0000000000000000
>> RAX: 000000007fffffff RBX: 00000000ffffffff RCX: 0000000000000000
>> RDX: 000000007fffffff RSI: 0000000280000000 RDI: ffffffffffffffff
>> RBP: ffffffff82803e68 R08: 0000000000000000 R09: 0000000000000000
>> R10: ffffffff83153180 R11: ffffffff82803e48 R12: ffffffff83c9aed0
>> R13: 0000000000000000 R14: 0000001040000000 R15: 0000000000000000
>> FS: 0000000000000000(0000) GS:0000000000000000(0000) knlGS:0000000000000000
>> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> CR2: ffff88903ffff000 CR3: 0000000002838000 CR4: 00000000000000b0
>> Call Trace:
>> <TASK>
>> ? __cma_declare_contiguous_nid+0x6e/0x340
>> ? cma_declare_contiguous_nid+0x33/0x70
>> ? dma_contiguous_reserve_area+0x2f/0x70
>> ? setup_arch+0x6f1/0x870
>> ? start_kernel+0x52/0x4b0
>> ? x86_64_start_reservations+0x29/0x30
>> ? x86_64_start_kernel+0x7c/0x80
>> ? common_startup_64+0x13e/0x141
>>
>> The reason is that __cma_declare_contiguous_nid() does:
>>
>> highmem_start = __pa(high_memory - 1) + 1;
>>
>> If dma_contiguous_reserve_area() (or any other CMA declaration) is
>> called before free_area_init(), high_memory is uninitialized. Without
>> CONFIG_DEBUG_VIRTUAL, it will likely work but use the wrong value for
>> highmem_start.
>>
>> Among the architectures this patch touches, the below call
>> dma_contiguous_reserve_area() _before_ free_area_init():
>>
>> - x86
>> - s390
>> - mips
>> - riscv
>> - xtensa
>> - loongarch
>> - csky
> For most of those this patch didn't really change anything because they
> initialized high_memory in mem_init() which is a part of free_area_init().
> In those cases cma just did
>
> highmem_start = __pa(-1) + 1;
>
> and everyone was happy :)
>
>> The below call it _after_ free_area_init():
>> - arm64
>>
>> And the below don't call it at all:
>> - sparc
>> - nios2
>> - openrisc
>> - hexagon
>> - sh
>> - um
>> - alpha
>>
>> One possible fix would be to move the calls to
>> dma_contiguous_reserve_area() after free_area_init(). On x86, it would
>> look like the diff below. The obvious downside is that moving the call
>> later increases the chances of allocation failure. I'm not sure how much
>> that actually matters, but at least on x86, that means crash kernel and
>> hugetlb reservations go before DMA reservation. Also, adding a patch
>> like that at rc7 is a bit risky.
> I don't think there's a risk of allocation failure, but moving things
> around in setup_arch() is always risky :)
>
>> The other option would be to revert this. I tried a revert, but it isn't
>> trivial. It runs into merge conflicts in pretty much all of the arch
>> files. Maybe reverting patches 11, 12, and 13 as well would make it
>> easier but I didn't try that.
> What I think we can do is to add this to mm/cma.c (not even compile tested)
>
> diff --git a/mm/cma.c b/mm/cma.c
> index 15632939f20a..c04be488b099 100644
> --- a/mm/cma.c
> +++ b/mm/cma.c
> @@ -608,7 +608,10 @@ static int __init __cma_declare_contiguous_nid(phys_addr_t *basep,
> * complain. Find the boundary by adding one to the last valid
> * address.
> */
> - highmem_start = __pa(high_memory - 1) + 1;
> + if (IS_ENABLED(CONFIG_HIGHMEM))
> + highmem_start = __pa(high_memory - 1) + 1;
> + else
> + highmem_start = memblock_end_of_DRAM();
> pr_debug("%s(size %pa, base %pa, limit %pa alignment %pa)\n",
> __func__, &size, &base, &limit, &alignment);
I encountered the same error as Pratyush and the above diff fixes it: do
you plan on sending this fix for 6.15?
If so, you can add:
Tested-by: Alexandre Ghiti <alexghiti@rivosinc.com>
If not, let me know how you want to proceed :)
Thanks,
Alex
>
> so that highmem_start in __cma_declare_contiguous_nid() will be always
> correct for !HIGHMEM configs and then restore setting of highmem_start in
> mips::paging_init() as mips is the only architecture that actually set
> high_memory before free_area_init() before this patch.
>
> (for 32 bit configs of x86 there alrady a fixup d893aca973c3 ("x86/mm: restore
> early initialization of high_memory for 32-bits"))
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()
2025-05-19 15:54 ` Alexandre Ghiti
@ 2025-05-19 17:19 ` Mike Rapoport
0 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-05-19 17:19 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Pratyush Yadav, Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Geert Uytterhoeven, Gerald Schaefer, Guo Ren,
Heiko Carstens, Helge Deller, Huacai Chen, Ingo Molnar,
Jiaxun Yang, Johannes Berg, John Paul Adrian Glaubitz,
Madhavan Srinivasan, Mark Brown, Matt Turner, Max Filippov,
Michael Ellerman, Michal Simek, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, Praveen Kumar, linux-alpha, linux-kernel,
linux-snps-arc, linux-arm-kernel, linux-csky, linux-hexagon,
loongarch, linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
Hi Alexandre,
On Mon, May 19, 2025 at 05:54:23PM +0200, Alexandre Ghiti wrote:
> Hi Mike,
>
> I encountered the same error as Pratyush and the above diff fixes it: do you
> plan on sending this fix for 6.15?
>
> If so, you can add:
>
> Tested-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Thanks!
Here's the patch:
https://lore.kernel.org/linux-mm/20250519171805.1288393-1-rppt@kernel.org
> Thanks,
> Alex
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 11/13] arch, mm: streamline HIGHMEM freeing
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (9 preceding siblings ...)
2025-03-13 13:50 ` [PATCH v2 10/13] arch, mm: set high_memory in free_area_init() Mike Rapoport
@ 2025-03-13 13:50 ` Mike Rapoport
2025-03-13 13:50 ` [PATCH v2 12/13] arch, mm: introduce arch_mm_preinit Mike Rapoport
` (2 subsequent siblings)
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:50 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
All architectures that support HIGHMEM have their code that frees high
memory pages to the buddy allocator while __free_memory_core() is limited
to freeing only low memory.
There is no actual reason for that. The memory map is completely ready
by the time memblock_free_all() is called and high pages can be released to
the buddy allocator along with low memory.
Remove low memory limit from __free_memory_core() and drop per-architecture
code that frees high memory pages.
Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/arc/mm/init.c | 6 +-----
arch/arm/mm/init.c | 29 -----------------------------
arch/csky/mm/init.c | 14 --------------
arch/microblaze/mm/init.c | 16 ----------------
arch/mips/mm/init.c | 20 --------------------
arch/powerpc/mm/mem.c | 14 --------------
arch/sparc/mm/init_32.c | 25 -------------------------
arch/x86/include/asm/highmem.h | 3 ---
arch/x86/include/asm/numa.h | 4 ----
arch/x86/include/asm/numa_32.h | 13 -------------
arch/x86/mm/Makefile | 2 --
arch/x86/mm/highmem_32.c | 34 ----------------------------------
arch/x86/mm/init_32.c | 28 ----------------------------
arch/xtensa/mm/init.c | 29 -----------------------------
include/linux/mm.h | 1 -
mm/memblock.c | 3 +--
16 files changed, 2 insertions(+), 239 deletions(-)
delete mode 100644 arch/x86/include/asm/numa_32.h
delete mode 100644 arch/x86/mm/highmem_32.c
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 05025122e965..11ce638731c9 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -160,11 +160,7 @@ void __init setup_arch_memory(void)
static void __init highmem_init(void)
{
#ifdef CONFIG_HIGHMEM
- unsigned long tmp;
-
memblock_phys_free(high_mem_start, high_mem_sz);
- for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++)
- free_highmem_page(pfn_to_page(tmp));
#endif
}
@@ -176,8 +172,8 @@ static void __init highmem_init(void)
*/
void __init mem_init(void)
{
- memblock_free_all();
highmem_init();
+ memblock_free_all();
BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
BUILD_BUG_ON((PTRS_PER_PUD * sizeof(pud_t)) > PAGE_SIZE);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index d4bcc745a044..7bb5ce02b9b5 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -237,33 +237,6 @@ static inline void poison_init_mem(void *s, size_t count)
*p++ = 0xe7fddef0;
}
-static void __init free_highpages(void)
-{
-#ifdef CONFIG_HIGHMEM
- unsigned long max_low = max_low_pfn;
- phys_addr_t range_start, range_end;
- u64 i;
-
- /* set highmem page free */
- for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
- &range_start, &range_end, NULL) {
- unsigned long start = PFN_UP(range_start);
- unsigned long end = PFN_DOWN(range_end);
-
- /* Ignore complete lowmem entries */
- if (end <= max_low)
- continue;
-
- /* Truncate partial highmem entries */
- if (start < max_low)
- start = max_low;
-
- for (; start < end; start++)
- free_highmem_page(pfn_to_page(start));
- }
-#endif
-}
-
/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free. This is done after various parts of the system have
@@ -283,8 +256,6 @@ void __init mem_init(void)
/* this will put all unused low memory onto the freelists */
memblock_free_all();
- free_highpages();
-
/*
* Check boundaries twice: Some fundamental inconsistencies can
* be detected at build time already.
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index a22801aa503a..3914c2b873da 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -44,21 +44,7 @@ EXPORT_SYMBOL(empty_zero_page);
void __init mem_init(void)
{
-#ifdef CONFIG_HIGHMEM
- unsigned long tmp;
-#endif
-
memblock_free_all();
-
-#ifdef CONFIG_HIGHMEM
- for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
- struct page *page = pfn_to_page(tmp);
-
- /* FIXME not sure about */
- if (!memblock_is_reserved(tmp << PAGE_SHIFT))
- free_highmem_page(page);
- }
-#endif
}
void free_initmem(void)
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 7e2e342e84c5..3e664e0efc33 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -52,19 +52,6 @@ static void __init highmem_init(void)
map_page(PKMAP_BASE, 0, 0); /* XXX gross */
pkmap_page_table = virt_to_kpte(PKMAP_BASE);
}
-
-static void __meminit highmem_setup(void)
-{
- unsigned long pfn;
-
- for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) {
- struct page *page = pfn_to_page(pfn);
-
- /* FIXME not sure about */
- if (!memblock_is_reserved(pfn << PAGE_SHIFT))
- free_highmem_page(page);
- }
-}
#endif /* CONFIG_HIGHMEM */
/*
@@ -122,9 +109,6 @@ void __init mem_init(void)
{
/* this will put all memory onto the freelists */
memblock_free_all();
-#ifdef CONFIG_HIGHMEM
- highmem_setup();
-#endif
mem_init_done = 1;
}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index ed9dde6a00f7..075177e817ac 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -425,25 +425,6 @@ void __init paging_init(void)
static struct kcore_list kcore_kseg0;
#endif
-static inline void __init mem_init_free_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
- unsigned long tmp;
-
- if (cpu_has_dc_aliases)
- return;
-
- for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
- struct page *page = pfn_to_page(tmp);
-
- if (!memblock_is_memory(PFN_PHYS(tmp)))
- SetPageReserved(page);
- else
- free_highmem_page(page);
- }
-#endif
-}
-
void __init mem_init(void)
{
/*
@@ -454,7 +435,6 @@ void __init mem_init(void)
maar_init();
setup_zero_pages(); /* Setup zeroed pages. */
- mem_init_free_highmem();
memblock_free_all();
#ifdef CONFIG_64BIT
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c7708c8fad29..1bc94bca9944 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -297,20 +297,6 @@ void __init mem_init(void)
memblock_free_all();
-#ifdef CONFIG_HIGHMEM
- {
- unsigned long pfn, highmem_mapnr;
-
- highmem_mapnr = lowmem_end_addr >> PAGE_SHIFT;
- for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
- phys_addr_t paddr = (phys_addr_t)pfn << PAGE_SHIFT;
- struct page *page = pfn_to_page(pfn);
- if (memblock_is_memory(paddr) && !memblock_is_reserved(paddr))
- free_highmem_page(page);
- }
- }
-#endif /* CONFIG_HIGHMEM */
-
#if defined(CONFIG_PPC_E500) && !defined(CONFIG_SMP)
/*
* If smp is enabled, next_tlbcam_idx is initialized in the cpu up
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 81a468a9c223..043e9b6fadd0 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -232,18 +232,6 @@ static void __init taint_real_pages(void)
}
}
-static void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
-{
- unsigned long tmp;
-
-#ifdef CONFIG_DEBUG_HIGHMEM
- printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn);
-#endif
-
- for (tmp = start_pfn; tmp < end_pfn; tmp++)
- free_highmem_page(pfn_to_page(tmp));
-}
-
void __init mem_init(void)
{
int i;
@@ -276,19 +264,6 @@ void __init mem_init(void)
taint_real_pages();
memblock_free_all();
-
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
- unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
-
- if (end_pfn <= highstart_pfn)
- continue;
-
- if (start_pfn < highstart_pfn)
- start_pfn = highstart_pfn;
-
- map_high_region(start_pfn, end_pfn);
- }
}
void sparc_flush_page_to_ram(struct page *page)
diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h
index 731ee7cc40a5..585bdadba47d 100644
--- a/arch/x86/include/asm/highmem.h
+++ b/arch/x86/include/asm/highmem.h
@@ -69,9 +69,6 @@ extern unsigned long highstart_pfn, highend_pfn;
arch_flush_lazy_mmu_mode(); \
} while (0)
-extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
- unsigned long end_pfn);
-
#endif /* __KERNEL__ */
#endif /* _ASM_X86_HIGHMEM_H */
diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h
index 5469d7a7c40f..53ba39ce010c 100644
--- a/arch/x86/include/asm/numa.h
+++ b/arch/x86/include/asm/numa.h
@@ -41,10 +41,6 @@ static inline int numa_cpu_node(int cpu)
}
#endif /* CONFIG_NUMA */
-#ifdef CONFIG_X86_32
-# include <asm/numa_32.h>
-#endif
-
#ifdef CONFIG_NUMA
extern void numa_set_node(int cpu, int node);
extern void numa_clear_node(int cpu);
diff --git a/arch/x86/include/asm/numa_32.h b/arch/x86/include/asm/numa_32.h
deleted file mode 100644
index 9c8e9e85be77..000000000000
--- a/arch/x86/include/asm/numa_32.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_NUMA_32_H
-#define _ASM_X86_NUMA_32_H
-
-#ifdef CONFIG_HIGHMEM
-extern void set_highmem_pages_init(void);
-#else
-static inline void set_highmem_pages_init(void)
-{
-}
-#endif
-
-#endif /* _ASM_X86_NUMA_32_H */
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 690fbf48e853..52fbf0a60858 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -42,8 +42,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PTDUMP_CORE) += dump_pagetables.o
obj-$(CONFIG_PTDUMP_DEBUGFS) += debug_pagetables.o
-obj-$(CONFIG_HIGHMEM) += highmem_32.o
-
KASAN_SANITIZE_kasan_init_$(BITS).o := n
obj-$(CONFIG_KASAN) += kasan_init_$(BITS).o
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
deleted file mode 100644
index d9efa35711ee..000000000000
--- a/arch/x86/mm/highmem_32.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/highmem.h>
-#include <linux/export.h>
-#include <linux/swap.h> /* for totalram_pages */
-#include <linux/memblock.h>
-#include <asm/numa.h>
-
-void __init set_highmem_pages_init(void)
-{
- struct zone *zone;
- int nid;
-
- /*
- * Explicitly reset zone->managed_pages because set_highmem_pages_init()
- * is invoked before memblock_free_all()
- */
- reset_all_zones_managed_pages();
- for_each_zone(zone) {
- unsigned long zone_start_pfn, zone_end_pfn;
-
- if (!is_highmem(zone))
- continue;
-
- zone_start_pfn = zone->zone_start_pfn;
- zone_end_pfn = zone_start_pfn + zone->spanned_pages;
-
- nid = zone_to_nid(zone);
- printk(KERN_INFO "Initializing %s for node %d (%08lx:%08lx)\n",
- zone->name, nid, zone_start_pfn, zone_end_pfn);
-
- add_highpages_with_active_regions(nid, zone_start_pfn,
- zone_end_pfn);
- }
-}
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 801b659ead0c..9ee8ec2bc5d1 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -394,23 +394,6 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
pkmap_page_table = virt_to_kpte(vaddr);
}
-
-void __init add_highpages_with_active_regions(int nid,
- unsigned long start_pfn, unsigned long end_pfn)
-{
- phys_addr_t start, end;
- u64 i;
-
- for_each_free_mem_range(i, nid, MEMBLOCK_NONE, &start, &end, NULL) {
- unsigned long pfn = clamp_t(unsigned long, PFN_UP(start),
- start_pfn, end_pfn);
- unsigned long e_pfn = clamp_t(unsigned long, PFN_DOWN(end),
- start_pfn, end_pfn);
- for ( ; pfn < e_pfn; pfn++)
- if (pfn_valid(pfn))
- free_highmem_page(pfn_to_page(pfn));
- }
-}
#else
static inline void permanent_kmaps_init(pgd_t *pgd_base)
{
@@ -715,17 +698,6 @@ void __init mem_init(void)
#ifdef CONFIG_FLATMEM
BUG_ON(!mem_map);
#endif
- /*
- * With CONFIG_DEBUG_PAGEALLOC initialization of highmem pages has to
- * be done before memblock_free_all(). Memblock use free low memory for
- * temporary data (see find_range_array()) and for this purpose can use
- * pages that was already passed to the buddy allocator, hence marked as
- * not accessible in the page tables when compiled with
- * CONFIG_DEBUG_PAGEALLOC. Otherwise order of initialization is not
- * important here.
- */
- set_highmem_pages_init();
-
/* this will put all low memory onto the freelists */
memblock_free_all();
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 9b662477b3d4..47ecbe28263e 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -129,41 +129,12 @@ void __init zones_init(void)
print_vm_layout();
}
-static void __init free_highpages(void)
-{
-#ifdef CONFIG_HIGHMEM
- unsigned long max_low = max_low_pfn;
- phys_addr_t range_start, range_end;
- u64 i;
-
- /* set highmem page free */
- for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
- &range_start, &range_end, NULL) {
- unsigned long start = PFN_UP(range_start);
- unsigned long end = PFN_DOWN(range_end);
-
- /* Ignore complete lowmem entries */
- if (end <= max_low)
- continue;
-
- /* Truncate partial highmem entries */
- if (start < max_low)
- start = max_low;
-
- for (; start < end; start++)
- free_highmem_page(pfn_to_page(start));
- }
-#endif
-}
-
/*
* Initialize memory pages.
*/
void __init mem_init(void)
{
- free_highpages();
-
memblock_free_all();
}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fdf20503850e..6fccd3b3248c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3172,7 +3172,6 @@ extern void reserve_bootmem_region(phys_addr_t start,
/* Free the reserved page into the buddy system, so it gets managed. */
void free_reserved_page(struct page *page);
-#define free_highmem_page(page) free_reserved_page(page)
static inline void mark_page_reserved(struct page *page)
{
diff --git a/mm/memblock.c b/mm/memblock.c
index 95af35fd1389..64ae678cd1d1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -2164,8 +2164,7 @@ static unsigned long __init __free_memory_core(phys_addr_t start,
phys_addr_t end)
{
unsigned long start_pfn = PFN_UP(start);
- unsigned long end_pfn = min_t(unsigned long,
- PFN_DOWN(end), max_low_pfn);
+ unsigned long end_pfn = PFN_DOWN(end);
if (start_pfn >= end_pfn)
return 0;
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 12/13] arch, mm: introduce arch_mm_preinit
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (10 preceding siblings ...)
2025-03-13 13:50 ` [PATCH v2 11/13] arch, mm: streamline HIGHMEM freeing Mike Rapoport
@ 2025-03-13 13:50 ` Mike Rapoport
2025-03-13 13:50 ` [PATCH v2 13/13] arch, mm: make releasing of memory to page allocator more explicit Mike Rapoport
2025-03-13 16:39 ` [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mark Brown
13 siblings, 0 replies; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:50 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Currently, implementation of mem_init() in every architecture consists of
one or more of the following:
* initializations that must run before page allocator is active, for
instance swiotlb_init()
* a call to memblock_free_all() to release all the memory to the buddy
allocator
* initializations that must run after page allocator is ready and there is
no arch-specific hook other than mem_init() for that, like for example
register_page_bootmem_info() in x86 and sparc64 or simple setting of
mem_init_done = 1 in several architectures
* a bunch of semi-related stuff that apparently had no better place to
live, for example a ton of BUILD_BUG_ON()s in parisc.
Introduce arch_mm_preinit() that will be the first thing called from
mm_core_init(). On architectures that have initializations that must happen
before the page allocator is ready, move those into arch_mm_preinit() along
with the code that does not depend on ordering with page allocator setup.
On several architectures this results in reduction of mem_init() to a
single call to memblock_free_all() that allows its consolidation next.
Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/arc/mm/init.c | 13 ++++++-------
arch/arm/mm/init.c | 21 ++++++++++++---------
arch/arm64/mm/init.c | 21 ++++++++++++---------
arch/mips/mm/init.c | 11 +++++++----
arch/powerpc/mm/mem.c | 9 ++++++---
arch/riscv/mm/init.c | 8 ++++++--
arch/s390/mm/init.c | 5 ++++-
arch/sparc/mm/init_32.c | 5 ++++-
arch/um/kernel/mem.c | 7 +++++--
arch/x86/mm/init_32.c | 6 +++++-
arch/x86/mm/init_64.c | 5 ++++-
include/linux/mm.h | 1 +
mm/mm_init.c | 5 +++++
13 files changed, 77 insertions(+), 40 deletions(-)
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 11ce638731c9..90715b4a0bfa 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -157,11 +157,16 @@ void __init setup_arch_memory(void)
free_area_init(max_zone_pfn);
}
-static void __init highmem_init(void)
+void __init arch_mm_preinit(void)
{
#ifdef CONFIG_HIGHMEM
memblock_phys_free(high_mem_start, high_mem_sz);
#endif
+
+ BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
+ BUILD_BUG_ON((PTRS_PER_PUD * sizeof(pud_t)) > PAGE_SIZE);
+ BUILD_BUG_ON((PTRS_PER_PMD * sizeof(pmd_t)) > PAGE_SIZE);
+ BUILD_BUG_ON((PTRS_PER_PTE * sizeof(pte_t)) > PAGE_SIZE);
}
/*
@@ -172,13 +177,7 @@ static void __init highmem_init(void)
*/
void __init mem_init(void)
{
- highmem_init();
memblock_free_all();
-
- BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
- BUILD_BUG_ON((PTRS_PER_PUD * sizeof(pud_t)) > PAGE_SIZE);
- BUILD_BUG_ON((PTRS_PER_PMD * sizeof(pmd_t)) > PAGE_SIZE);
- BUILD_BUG_ON((PTRS_PER_PTE * sizeof(pte_t)) > PAGE_SIZE);
}
#ifdef CONFIG_HIGHMEM
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7bb5ce02b9b5..7222100b0631 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -237,12 +237,7 @@ static inline void poison_init_mem(void *s, size_t count)
*p++ = 0xe7fddef0;
}
-/*
- * mem_init() marks the free areas in the mem_map and tells us how much
- * memory is free. This is done after various parts of the system have
- * claimed their memory after the kernel image.
- */
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
#ifdef CONFIG_ARM_LPAE
swiotlb_init(max_pfn > arm_dma_pfn_limit, SWIOTLB_VERBOSE);
@@ -253,9 +248,6 @@ void __init mem_init(void)
memblock_phys_free(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
#endif
- /* this will put all unused low memory onto the freelists */
- memblock_free_all();
-
/*
* Check boundaries twice: Some fundamental inconsistencies can
* be detected at build time already.
@@ -271,6 +263,17 @@ void __init mem_init(void)
#endif
}
+/*
+ * mem_init() marks the free areas in the mem_map and tells us how much
+ * memory is free. This is done after various parts of the system have
+ * claimed their memory after the kernel image.
+ */
+void __init mem_init(void)
+{
+ /* this will put all unused low memory onto the freelists */
+ memblock_free_all();
+}
+
#ifdef CONFIG_STRICT_KERNEL_RWX
struct section_perm {
const char *name;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index a48fcccd67fa..8eff6a6eb11e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -362,12 +362,7 @@ void __init bootmem_init(void)
memblock_dump_all();
}
-/*
- * mem_init() marks the free areas in the mem_map and tells us how much memory
- * is free. This is done after various parts of the system have claimed their
- * memory after the kernel image.
- */
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
unsigned int flags = SWIOTLB_VERBOSE;
bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit);
@@ -391,9 +386,6 @@ void __init mem_init(void)
swiotlb_init(swiotlb, flags);
swiotlb_update_mem_attributes();
- /* this will put all unused low memory onto the freelists */
- memblock_free_all();
-
/*
* Check boundaries twice: Some fundamental inconsistencies can be
* detected at build time already.
@@ -419,6 +411,17 @@ void __init mem_init(void)
}
}
+/*
+ * mem_init() marks the free areas in the mem_map and tells us how much memory
+ * is free. This is done after various parts of the system have claimed their
+ * memory after the kernel image.
+ */
+void __init mem_init(void)
+{
+ /* this will put all unused low memory onto the freelists */
+ memblock_free_all();
+}
+
void free_initmem(void)
{
void *lm_init_begin = lm_alias(__init_begin);
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 075177e817ac..eec38e7735dd 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -425,7 +425,7 @@ void __init paging_init(void)
static struct kcore_list kcore_kseg0;
#endif
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
/*
* When PFN_PTE_SHIFT is greater than PAGE_SHIFT we won't have enough PTE
@@ -435,7 +435,6 @@ void __init mem_init(void)
maar_init();
setup_zero_pages(); /* Setup zeroed pages. */
- memblock_free_all();
#ifdef CONFIG_64BIT
if ((unsigned long) &_text > (unsigned long) CKSEG0)
@@ -446,13 +445,17 @@ void __init mem_init(void)
#endif
}
#else /* CONFIG_NUMA */
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
setup_zero_pages(); /* This comes from node 0 */
- memblock_free_all();
}
#endif /* !CONFIG_NUMA */
+void __init mem_init(void)
+{
+ memblock_free_all();
+}
+
void free_init_pages(const char *what, unsigned long begin, unsigned long end)
{
unsigned long pfn;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 1bc94bca9944..68efdaf14e58 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -273,7 +273,7 @@ void __init paging_init(void)
mark_nonram_nosave();
}
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
/*
* book3s is limited to 16 page sizes due to encoding this in
@@ -295,8 +295,6 @@ void __init mem_init(void)
kasan_late_init();
- memblock_free_all();
-
#if defined(CONFIG_PPC_E500) && !defined(CONFIG_SMP)
/*
* If smp is enabled, next_tlbcam_idx is initialized in the cpu up
@@ -329,6 +327,11 @@ void __init mem_init(void)
#endif /* CONFIG_PPC32 */
}
+void __init mem_init(void)
+{
+ memblock_free_all();
+}
+
void free_initmem(void)
{
ppc_md.progress = ppc_printk_progress;
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index ac6d41e86243..9efadabf6be1 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -171,7 +171,7 @@ static void __init print_vm_layout(void)
static void print_vm_layout(void) { }
#endif /* CONFIG_DEBUG_VM */
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
bool swiotlb = max_pfn > PFN_DOWN(dma32_phys_limit);
#ifdef CONFIG_FLATMEM
@@ -192,11 +192,15 @@ void __init mem_init(void)
}
swiotlb_init(swiotlb, SWIOTLB_VERBOSE);
- memblock_free_all();
print_vm_layout();
}
+void __init mem_init(void)
+{
+ memblock_free_all();
+}
+
/* Limit the memory size via mem. */
static phys_addr_t memory_limit;
#ifdef CONFIG_XIP_KERNEL
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 0c485884d373..c496dfa48bdc 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -154,7 +154,7 @@ static void pv_init(void)
swiotlb_update_mem_attributes();
}
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
cpumask_set_cpu(0, &init_mm.context.cpu_attach_mask);
cpumask_set_cpu(0, mm_cpumask(&init_mm));
@@ -163,7 +163,10 @@ void __init mem_init(void)
kfence_split_mapping();
setup_zero_pages(); /* Setup zeroed pages. */
+}
+void __init mem_init(void)
+{
/* this will put all low memory onto the freelists */
memblock_free_all();
}
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 043e9b6fadd0..e16c32c5728f 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -232,7 +232,7 @@ static void __init taint_real_pages(void)
}
}
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
int i;
@@ -262,7 +262,10 @@ void __init mem_init(void)
memset(sparc_valid_addr_bitmap, 0, i << 2);
taint_real_pages();
+}
+void __init mem_init(void)
+{
memblock_free_all();
}
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index befed230aac2..cce387438e60 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -54,7 +54,7 @@ int kmalloc_ok = 0;
/* Used during early boot */
static unsigned long brk_end;
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
@@ -66,10 +66,13 @@ void __init mem_init(void)
map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
memblock_free((void *)brk_end, uml_reserved - brk_end);
uml_reserved = brk_end;
+ max_pfn = max_low_pfn;
+}
+void __init mem_init(void)
+{
/* this will put all low memory onto the freelists */
memblock_free_all();
- max_pfn = max_low_pfn;
kmalloc_ok = 1;
}
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 9ee8ec2bc5d1..16664c5464b5 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -691,13 +691,17 @@ static void __init test_wp_bit(void)
panic("Linux doesn't support CPUs with broken WP.");
}
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
pci_iommu_alloc();
#ifdef CONFIG_FLATMEM
BUG_ON(!mem_map);
#endif
+}
+
+void __init mem_init(void)
+{
/* this will put all low memory onto the freelists */
memblock_free_all();
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 01ea7c6df303..f8981e29633c 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1348,10 +1348,13 @@ static void __init preallocate_vmalloc_pages(void)
panic("Failed to pre-allocate %s pages for vmalloc area\n", lvl);
}
-void __init mem_init(void)
+void __init arch_mm_preinit(void)
{
pci_iommu_alloc();
+}
+void __init mem_init(void)
+{
/* clear_bss() already clear the empty_zero_page */
/* this will put all memory onto the freelists */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6fccd3b3248c..ae9cfb9612ea 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -42,6 +42,7 @@ struct folio_batch;
extern int sysctl_page_lock_unfairness;
+void arch_mm_preinit(void);
void mm_core_init(void);
void init_mm_internals(void);
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 61ac0cea711a..57f762c16c02 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2675,11 +2675,16 @@ static void __init mem_init_print_info(void)
);
}
+void __init __weak arch_mm_preinit(void)
+{
+}
+
/*
* Set up kernel memory allocators
*/
void __init mm_core_init(void)
{
+ arch_mm_preinit();
/* Initializations relying on SMP setup */
BUILD_BUG_ON(MAX_ZONELISTS > 2);
build_all_zonelists(NULL);
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 13/13] arch, mm: make releasing of memory to page allocator more explicit
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (11 preceding siblings ...)
2025-03-13 13:50 ` [PATCH v2 12/13] arch, mm: introduce arch_mm_preinit Mike Rapoport
@ 2025-03-13 13:50 ` Mike Rapoport
2025-03-13 15:19 ` Geert Uytterhoeven
2025-03-13 16:39 ` [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mark Brown
13 siblings, 1 reply; 24+ messages in thread
From: Mike Rapoport @ 2025-03-13 13:50 UTC (permalink / raw)
To: Andrew Morton
Cc: Alexander Gordeev, Andreas Larsson, Andy Lutomirski,
Ard Biesheuvel, Arnd Bergmann, Borislav Petkov, Brian Cain,
Catalin Marinas, Dave Hansen, David S. Miller, Dinh Nguyen,
Geert Uytterhoeven, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Mike Rapoport, Palmer Dabbelt, Peter Zijlstra,
Richard Weinberger, Russell King, Stafford Horne,
Thomas Bogendoerfer, Thomas Gleixner, Vasily Gorbik, Vineet Gupta,
Will Deacon, linux-alpha, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-csky, linux-hexagon, loongarch,
linux-m68k, linux-mips, linux-openrisc, linux-parisc,
linuxppc-dev, linux-riscv, linux-s390, linux-sh, sparclinux,
linux-um, linux-arch, linux-mm, x86
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
The point where the memory is released from memblock to the buddy allocator
is hidden inside arch-specific mem_init()s and the call to
memblock_free_all() is needlessly duplicated in every artiste cure and
after introduction of arch_mm_preinit() hook, mem_init() implementation on
many architecture only contains the call to memblock_free_all().
Pull memblock_free_all() call into mm_core_init() and drop mem_init() on
relevant architectures to make it more explicit where the free memory is
released from memblock to the buddy allocator and to reduce code
duplication in architecture specific code.
Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/alpha/mm/init.c | 6 ------
arch/arc/mm/init.c | 11 -----------
arch/arm/mm/init.c | 11 -----------
arch/arm64/mm/init.c | 11 -----------
arch/csky/mm/init.c | 5 -----
arch/hexagon/mm/init.c | 18 ------------------
arch/loongarch/kernel/numa.c | 5 -----
arch/loongarch/mm/init.c | 5 -----
arch/m68k/mm/init.c | 2 --
arch/microblaze/mm/init.c | 3 ---
arch/mips/mm/init.c | 5 -----
arch/nios2/mm/init.c | 6 ------
arch/openrisc/mm/init.c | 3 ---
arch/parisc/mm/init.c | 2 --
arch/powerpc/mm/mem.c | 5 -----
arch/riscv/mm/init.c | 5 -----
arch/s390/mm/init.c | 6 ------
arch/sh/mm/init.c | 2 --
arch/sparc/mm/init_32.c | 5 -----
arch/sparc/mm/init_64.c | 2 --
arch/um/kernel/mem.c | 2 --
arch/x86/mm/init_32.c | 3 ---
arch/x86/mm/init_64.c | 2 --
arch/xtensa/mm/init.c | 9 ---------
include/linux/memblock.h | 1 -
mm/internal.h | 3 ++-
mm/mm_init.c | 5 +++++
27 files changed, 7 insertions(+), 136 deletions(-)
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 3ab2d2f3c917..2d491b8cdab9 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -273,12 +273,6 @@ srm_paging_stop (void)
}
#endif
-void __init
-mem_init(void)
-{
- memblock_free_all();
-}
-
static const pgprot_t protection_map[16] = {
[VM_NONE] = _PAGE_P(_PAGE_FOE | _PAGE_FOW |
_PAGE_FOR),
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 90715b4a0bfa..a73cc94f806e 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -169,17 +169,6 @@ void __init arch_mm_preinit(void)
BUILD_BUG_ON((PTRS_PER_PTE * sizeof(pte_t)) > PAGE_SIZE);
}
-/*
- * mem_init - initializes memory
- *
- * Frees up bootmem
- * Calculates and displays memory available/used
- */
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
#ifdef CONFIG_HIGHMEM
int pfn_valid(unsigned long pfn)
{
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7222100b0631..54bdca025c9f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -263,17 +263,6 @@ void __init arch_mm_preinit(void)
#endif
}
-/*
- * mem_init() marks the free areas in the mem_map and tells us how much
- * memory is free. This is done after various parts of the system have
- * claimed their memory after the kernel image.
- */
-void __init mem_init(void)
-{
- /* this will put all unused low memory onto the freelists */
- memblock_free_all();
-}
-
#ifdef CONFIG_STRICT_KERNEL_RWX
struct section_perm {
const char *name;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8eff6a6eb11e..510695107233 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -411,17 +411,6 @@ void __init arch_mm_preinit(void)
}
}
-/*
- * mem_init() marks the free areas in the mem_map and tells us how much memory
- * is free. This is done after various parts of the system have claimed their
- * memory after the kernel image.
- */
-void __init mem_init(void)
-{
- /* this will put all unused low memory onto the freelists */
- memblock_free_all();
-}
-
void free_initmem(void)
{
void *lm_init_begin = lm_alias(__init_begin);
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index 3914c2b873da..573da66b2543 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -42,11 +42,6 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
__page_aligned_bss;
EXPORT_SYMBOL(empty_zero_page);
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
void free_initmem(void)
{
free_initmem_default(-1);
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index d412c2314509..34eb9d424b96 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -43,24 +43,6 @@ DEFINE_SPINLOCK(kmap_gen_lock);
/* checkpatch says don't init this to 0. */
unsigned long long kmap_generation;
-/*
- * mem_init - initializes memory
- *
- * Frees up bootmem
- * Fixes up more stuff for HIGHMEM
- * Calculates and displays memory available/used
- */
-void __init mem_init(void)
-{
- /* No idea where this is actually declared. Seems to evade LXR. */
- memblock_free_all();
-
- /*
- * To-Do: someone somewhere should wipe out the bootmem map
- * after we're done?
- */
-}
-
void sync_icache_dcache(pte_t pte)
{
unsigned long addr;
diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
index 8eb489725b1a..30a72fd528c0 100644
--- a/arch/loongarch/kernel/numa.c
+++ b/arch/loongarch/kernel/numa.c
@@ -387,11 +387,6 @@ void __init paging_init(void)
free_area_init(zones_size);
}
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
int pcibus_to_node(struct pci_bus *bus)
{
return dev_to_node(&bus->dev);
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 6affa3609188..fdb7f73ad160 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -75,11 +75,6 @@ void __init paging_init(void)
free_area_init(max_zone_pfns);
}
-
-void __init mem_init(void)
-{
- memblock_free_all();
-}
#endif /* !CONFIG_NUMA */
void __ref free_initmem(void)
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index 8b11d0d545aa..488411af1b3f 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -121,7 +121,5 @@ static inline void init_pointer_tables(void)
void __init mem_init(void)
{
- /* this will put all memory onto the freelists */
- memblock_free_all();
init_pointer_tables();
}
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 3e664e0efc33..65f0d1fb8a2a 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -107,9 +107,6 @@ void __init setup_memory(void)
void __init mem_init(void)
{
- /* this will put all memory onto the freelists */
- memblock_free_all();
-
mem_init_done = 1;
}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index eec38e7735dd..a673d3d68254 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -451,11 +451,6 @@ void __init arch_mm_preinit(void)
}
#endif /* !CONFIG_NUMA */
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
void free_init_pages(const char *what, unsigned long begin, unsigned long end)
{
unsigned long pfn;
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index 4ba8dfa0d238..94efa3de3933 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -60,12 +60,6 @@ void __init paging_init(void)
(unsigned long)empty_zero_page + PAGE_SIZE);
}
-void __init mem_init(void)
-{
- /* this will put all memory onto the freelists */
- memblock_free_all();
-}
-
void __init mmu_init(void)
{
flush_tlb_all();
diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
index 72c5952607ac..be1c2eb8bb94 100644
--- a/arch/openrisc/mm/init.c
+++ b/arch/openrisc/mm/init.c
@@ -196,9 +196,6 @@ void __init mem_init(void)
/* clear the zero-page */
memset((void *)empty_zero_page, 0, PAGE_SIZE);
- /* this will put all low memory onto the freelists */
- memblock_free_all();
-
printk("mem_init_done ...........................................\n");
mem_init_done = 1;
return;
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 4fbe354dc9b4..14270715d754 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -562,8 +562,6 @@ void __init mem_init(void)
BUILD_BUG_ON(TMPALIAS_MAP_START >= 0x80000000);
#endif
- memblock_free_all();
-
#ifdef CONFIG_PA11
if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) {
pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 68efdaf14e58..d8fe11b64259 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -327,11 +327,6 @@ void __init arch_mm_preinit(void)
#endif /* CONFIG_PPC32 */
}
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
void free_initmem(void)
{
ppc_md.progress = ppc_printk_progress;
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 9efadabf6be1..79b649f6de72 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -196,11 +196,6 @@ void __init arch_mm_preinit(void)
print_vm_layout();
}
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
/* Limit the memory size via mem. */
static phys_addr_t memory_limit;
#ifdef CONFIG_XIP_KERNEL
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index c496dfa48bdc..1999b5a94170 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -165,12 +165,6 @@ void __init arch_mm_preinit(void)
setup_zero_pages(); /* Setup zeroed pages. */
}
-void __init mem_init(void)
-{
- /* this will put all low memory onto the freelists */
- memblock_free_all();
-}
-
unsigned long memory_block_size_bytes(void)
{
/*
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 6d459ffba4bc..99e302eeeec1 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -330,8 +330,6 @@ unsigned int mem_init_done = 0;
void __init mem_init(void)
{
- memblock_free_all();
-
/* Set this up early, so we can take care of the zero page */
cpu_cache_init();
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index e16c32c5728f..fdc93dd12c3e 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -264,11 +264,6 @@ void __init arch_mm_preinit(void)
taint_real_pages();
}
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
void sparc_flush_page_to_ram(struct page *page)
{
unsigned long vaddr = (unsigned long)page_address(page);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 34d46adb9571..760818950464 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2505,8 +2505,6 @@ static void __init register_page_bootmem_info(void)
}
void __init mem_init(void)
{
- memblock_free_all();
-
/*
* Must be done after boot memory is put on freelist, because here we
* might set fields in deferred struct pages that have not yet been
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index cce387438e60..379f33a1babf 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -71,8 +71,6 @@ void __init arch_mm_preinit(void)
void __init mem_init(void)
{
- /* this will put all low memory onto the freelists */
- memblock_free_all();
kmalloc_ok = 1;
}
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 16664c5464b5..95b2758b4e4d 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -702,9 +702,6 @@ void __init arch_mm_preinit(void)
void __init mem_init(void)
{
- /* this will put all low memory onto the freelists */
- memblock_free_all();
-
after_bootmem = 1;
x86_init.hyper.init_after_bootmem();
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index f8981e29633c..451e796427d3 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1357,8 +1357,6 @@ void __init mem_init(void)
{
/* clear_bss() already clear the empty_zero_page */
- /* this will put all memory onto the freelists */
- memblock_free_all();
after_bootmem = 1;
x86_init.hyper.init_after_bootmem();
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 47ecbe28263e..cc52733a0649 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -129,15 +129,6 @@ void __init zones_init(void)
print_vm_layout();
}
-/*
- * Initialize memory pages.
- */
-
-void __init mem_init(void)
-{
- memblock_free_all();
-}
-
static void __init parse_memmap_one(char *p)
{
char *oldp;
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index e79eb6ac516f..ef5a1ecc6e59 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -133,7 +133,6 @@ int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
int memblock_reserved_mark_noinit(phys_addr_t base, phys_addr_t size);
-void memblock_free_all(void);
void memblock_free(void *ptr, size_t size);
void reset_all_zones_managed_pages(void);
diff --git a/mm/internal.h b/mm/internal.h
index 109ef30fee11..26e2e8cea495 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1407,7 +1407,8 @@ static inline bool gup_must_unshare(struct vm_area_struct *vma,
}
extern bool mirrored_kernelcore;
-extern bool memblock_has_mirror(void);
+bool memblock_has_mirror(void);
+void memblock_free_all(void);
static __always_inline void vma_set_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end,
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 57f762c16c02..c529a07fd055 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2679,6 +2679,10 @@ void __init __weak arch_mm_preinit(void)
{
}
+void __init __weak mem_init(void)
+{
+}
+
/*
* Set up kernel memory allocators
*/
@@ -2700,6 +2704,7 @@ void __init mm_core_init(void)
report_meminit();
kmsan_init_shadow();
stack_depot_early_init();
+ memblock_free_all();
mem_init();
kmem_cache_init();
/*
--
2.47.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 13/13] arch, mm: make releasing of memory to page allocator more explicit
2025-03-13 13:50 ` [PATCH v2 13/13] arch, mm: make releasing of memory to page allocator more explicit Mike Rapoport
@ 2025-03-13 15:19 ` Geert Uytterhoeven
0 siblings, 0 replies; 24+ messages in thread
From: Geert Uytterhoeven @ 2025-03-13 15:19 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Gerald Schaefer, Guo Ren, Heiko Carstens,
Helge Deller, Huacai Chen, Ingo Molnar, Jiaxun Yang,
Johannes Berg, John Paul Adrian Glaubitz, Madhavan Srinivasan,
Mark Brown, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Palmer Dabbelt, Peter Zijlstra, Richard Weinberger,
Russell King, Stafford Horne, Thomas Bogendoerfer,
Thomas Gleixner, Vasily Gorbik, Vineet Gupta, Will Deacon,
linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-mips,
linux-openrisc, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, sparclinux, linux-um, linux-arch, linux-mm,
x86
On Thu, 13 Mar 2025 at 14:53, Mike Rapoport <rppt@kernel.org> wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> The point where the memory is released from memblock to the buddy allocator
> is hidden inside arch-specific mem_init()s and the call to
> memblock_free_all() is needlessly duplicated in every artiste cure and
> after introduction of arch_mm_preinit() hook, mem_init() implementation on
> many architecture only contains the call to memblock_free_all().
>
> Pull memblock_free_all() call into mm_core_init() and drop mem_init() on
> relevant architectures to make it more explicit where the free memory is
> released from memblock to the buddy allocator and to reduce code
> duplication in architecture specific code.
>
> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> # x86
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> arch/m68k/mm/init.c | 2 --
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> # m68k
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init()
2025-03-13 13:49 [PATCH v2 00/13] arch, mm: reduce code duplication in mem_init() Mike Rapoport
` (12 preceding siblings ...)
2025-03-13 13:50 ` [PATCH v2 13/13] arch, mm: make releasing of memory to page allocator more explicit Mike Rapoport
@ 2025-03-13 16:39 ` Mark Brown
13 siblings, 0 replies; 24+ messages in thread
From: Mark Brown @ 2025-03-13 16:39 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, Alexander Gordeev, Andreas Larsson,
Andy Lutomirski, Ard Biesheuvel, Arnd Bergmann, Borislav Petkov,
Brian Cain, Catalin Marinas, Dave Hansen, David S. Miller,
Dinh Nguyen, Geert Uytterhoeven, Gerald Schaefer, Guo Ren,
Heiko Carstens, Helge Deller, Huacai Chen, Ingo Molnar,
Jiaxun Yang, Johannes Berg, John Paul Adrian Glaubitz,
Madhavan Srinivasan, Matt Turner, Max Filippov, Michael Ellerman,
Michal Simek, Palmer Dabbelt, Peter Zijlstra, Richard Weinberger,
Russell King, Stafford Horne, Thomas Bogendoerfer,
Thomas Gleixner, Vasily Gorbik, Vineet Gupta, Will Deacon,
linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-mips,
linux-openrisc, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, sparclinux, linux-um, linux-arch, linux-mm,
x86
[-- Attachment #1: Type: text/plain, Size: 574 bytes --]
On Thu, Mar 13, 2025 at 03:49:50PM +0200, Mike Rapoport wrote:
> v2 changes:
> * don't use generic version for setting high_memory on architectures
> that use that varialble earlier than free_area_init()
> * use memblock_alloc_or_panig() to allocate zero pages on MIPS and s390
> * fix alignment in allocation of zero pages on s390
> * add Acked-by
This resolves the issues for 32 bit arm, at least the v7 boards:
Tested-by: Mark Brown <broonie@kernel.org>
My v5 and v6 boards are having issues but I think that's unrelated
infrastructure (in one case definitely so).
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread