Skip to content

Commit 6faea34

Browse files
rpptakpm00
authored andcommitted
arch, mm: streamline HIGHMEM freeing
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. Link: https://lkml.kernel.org/r/20250313135003.836600-12-rppt@kernel.org Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> [x86] Tested-by: Mark Brown <broonie@kernel.org> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Andreas Larsson <andreas@gaisler.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Betkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: David S. Miller <davem@davemloft.net> Cc: Dinh Nguyen <dinguyen@kernel.org> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Guo Ren (csky) <guoren@kernel.org> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Helge Deller <deller@gmx.de> Cc: Huacai Chen <chenhuacai@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: Johannes Berg <johannes@sipsolutions.net> Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Matt Turner <mattst88@gmail.com> Cc: Max Filippov <jcmvbkbc@gmail.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Michal Simek <monstr@monstr.eu> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Richard Weinberger <richard@nod.at> Cc: Russel King <linux@armlinux.org.uk> Cc: Stafford Horne <shorne@gmail.com> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: Thomas Gleinxer <tglx@linutronix.de> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vineet Gupta <vgupta@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent e120d1b commit 6faea34

File tree

16 files changed

+2
-239
lines changed

16 files changed

+2
-239
lines changed

arch/arc/mm/init.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,7 @@ void __init setup_arch_memory(void)
160160
static void __init highmem_init(void)
161161
{
162162
#ifdef CONFIG_HIGHMEM
163-
unsigned long tmp;
164-
165163
memblock_phys_free(high_mem_start, high_mem_sz);
166-
for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++)
167-
free_highmem_page(pfn_to_page(tmp));
168164
#endif
169165
}
170166

@@ -176,8 +172,8 @@ static void __init highmem_init(void)
176172
*/
177173
void __init mem_init(void)
178174
{
179-
memblock_free_all();
180175
highmem_init();
176+
memblock_free_all();
181177

182178
BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
183179
BUILD_BUG_ON((PTRS_PER_PUD * sizeof(pud_t)) > PAGE_SIZE);

arch/arm/mm/init.c

-29
Original file line numberDiff line numberDiff line change
@@ -237,33 +237,6 @@ static inline void poison_init_mem(void *s, size_t count)
237237
*p++ = 0xe7fddef0;
238238
}
239239

240-
static void __init free_highpages(void)
241-
{
242-
#ifdef CONFIG_HIGHMEM
243-
unsigned long max_low = max_low_pfn;
244-
phys_addr_t range_start, range_end;
245-
u64 i;
246-
247-
/* set highmem page free */
248-
for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
249-
&range_start, &range_end, NULL) {
250-
unsigned long start = PFN_UP(range_start);
251-
unsigned long end = PFN_DOWN(range_end);
252-
253-
/* Ignore complete lowmem entries */
254-
if (end <= max_low)
255-
continue;
256-
257-
/* Truncate partial highmem entries */
258-
if (start < max_low)
259-
start = max_low;
260-
261-
for (; start < end; start++)
262-
free_highmem_page(pfn_to_page(start));
263-
}
264-
#endif
265-
}
266-
267240
/*
268241
* mem_init() marks the free areas in the mem_map and tells us how much
269242
* memory is free. This is done after various parts of the system have
@@ -283,8 +256,6 @@ void __init mem_init(void)
283256
/* this will put all unused low memory onto the freelists */
284257
memblock_free_all();
285258

286-
free_highpages();
287-
288259
/*
289260
* Check boundaries twice: Some fundamental inconsistencies can
290261
* be detected at build time already.

arch/csky/mm/init.c

-14
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,7 @@ EXPORT_SYMBOL(empty_zero_page);
4444

4545
void __init mem_init(void)
4646
{
47-
#ifdef CONFIG_HIGHMEM
48-
unsigned long tmp;
49-
#endif
50-
5147
memblock_free_all();
52-
53-
#ifdef CONFIG_HIGHMEM
54-
for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
55-
struct page *page = pfn_to_page(tmp);
56-
57-
/* FIXME not sure about */
58-
if (!memblock_is_reserved(tmp << PAGE_SHIFT))
59-
free_highmem_page(page);
60-
}
61-
#endif
6248
}
6349

6450
void free_initmem(void)

arch/microblaze/mm/init.c

-16
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,6 @@ static void __init highmem_init(void)
5252
map_page(PKMAP_BASE, 0, 0); /* XXX gross */
5353
pkmap_page_table = virt_to_kpte(PKMAP_BASE);
5454
}
55-
56-
static void __meminit highmem_setup(void)
57-
{
58-
unsigned long pfn;
59-
60-
for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) {
61-
struct page *page = pfn_to_page(pfn);
62-
63-
/* FIXME not sure about */
64-
if (!memblock_is_reserved(pfn << PAGE_SHIFT))
65-
free_highmem_page(page);
66-
}
67-
}
6855
#endif /* CONFIG_HIGHMEM */
6956

7057
/*
@@ -122,9 +109,6 @@ void __init mem_init(void)
122109
{
123110
/* this will put all memory onto the freelists */
124111
memblock_free_all();
125-
#ifdef CONFIG_HIGHMEM
126-
highmem_setup();
127-
#endif
128112

129113
mem_init_done = 1;
130114
}

arch/mips/mm/init.c

-20
Original file line numberDiff line numberDiff line change
@@ -425,25 +425,6 @@ void __init paging_init(void)
425425
static struct kcore_list kcore_kseg0;
426426
#endif
427427

428-
static inline void __init mem_init_free_highmem(void)
429-
{
430-
#ifdef CONFIG_HIGHMEM
431-
unsigned long tmp;
432-
433-
if (cpu_has_dc_aliases)
434-
return;
435-
436-
for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
437-
struct page *page = pfn_to_page(tmp);
438-
439-
if (!memblock_is_memory(PFN_PHYS(tmp)))
440-
SetPageReserved(page);
441-
else
442-
free_highmem_page(page);
443-
}
444-
#endif
445-
}
446-
447428
void __init mem_init(void)
448429
{
449430
/*
@@ -454,7 +435,6 @@ void __init mem_init(void)
454435

455436
maar_init();
456437
setup_zero_pages(); /* Setup zeroed pages. */
457-
mem_init_free_highmem();
458438
memblock_free_all();
459439

460440
#ifdef CONFIG_64BIT

arch/powerpc/mm/mem.c

-14
Original file line numberDiff line numberDiff line change
@@ -297,20 +297,6 @@ void __init mem_init(void)
297297

298298
memblock_free_all();
299299

300-
#ifdef CONFIG_HIGHMEM
301-
{
302-
unsigned long pfn, highmem_mapnr;
303-
304-
highmem_mapnr = lowmem_end_addr >> PAGE_SHIFT;
305-
for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
306-
phys_addr_t paddr = (phys_addr_t)pfn << PAGE_SHIFT;
307-
struct page *page = pfn_to_page(pfn);
308-
if (memblock_is_memory(paddr) && !memblock_is_reserved(paddr))
309-
free_highmem_page(page);
310-
}
311-
}
312-
#endif /* CONFIG_HIGHMEM */
313-
314300
#if defined(CONFIG_PPC_E500) && !defined(CONFIG_SMP)
315301
/*
316302
* If smp is enabled, next_tlbcam_idx is initialized in the cpu up

arch/sparc/mm/init_32.c

-25
Original file line numberDiff line numberDiff line change
@@ -232,18 +232,6 @@ static void __init taint_real_pages(void)
232232
}
233233
}
234234

235-
static void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
236-
{
237-
unsigned long tmp;
238-
239-
#ifdef CONFIG_DEBUG_HIGHMEM
240-
printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn);
241-
#endif
242-
243-
for (tmp = start_pfn; tmp < end_pfn; tmp++)
244-
free_highmem_page(pfn_to_page(tmp));
245-
}
246-
247235
void __init mem_init(void)
248236
{
249237
int i;
@@ -276,19 +264,6 @@ void __init mem_init(void)
276264
taint_real_pages();
277265

278266
memblock_free_all();
279-
280-
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
281-
unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
282-
unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
283-
284-
if (end_pfn <= highstart_pfn)
285-
continue;
286-
287-
if (start_pfn < highstart_pfn)
288-
start_pfn = highstart_pfn;
289-
290-
map_high_region(start_pfn, end_pfn);
291-
}
292267
}
293268

294269
void sparc_flush_page_to_ram(struct page *page)

arch/x86/include/asm/highmem.h

-3
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@ extern unsigned long highstart_pfn, highend_pfn;
6969
arch_flush_lazy_mmu_mode(); \
7070
} while (0)
7171

72-
extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
73-
unsigned long end_pfn);
74-
7572
#endif /* __KERNEL__ */
7673

7774
#endif /* _ASM_X86_HIGHMEM_H */

arch/x86/include/asm/numa.h

-4
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ static inline int numa_cpu_node(int cpu)
4141
}
4242
#endif /* CONFIG_NUMA */
4343

44-
#ifdef CONFIG_X86_32
45-
# include <asm/numa_32.h>
46-
#endif
47-
4844
#ifdef CONFIG_NUMA
4945
extern void numa_set_node(int cpu, int node);
5046
extern void numa_clear_node(int cpu);

arch/x86/include/asm/numa_32.h

-13
This file was deleted.

arch/x86/mm/Makefile

-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
4242
obj-$(CONFIG_PTDUMP) += dump_pagetables.o
4343
obj-$(CONFIG_PTDUMP_DEBUGFS) += debug_pagetables.o
4444

45-
obj-$(CONFIG_HIGHMEM) += highmem_32.o
46-
4745
KASAN_SANITIZE_kasan_init_$(BITS).o := n
4846
obj-$(CONFIG_KASAN) += kasan_init_$(BITS).o
4947

arch/x86/mm/highmem_32.c

-34
This file was deleted.

arch/x86/mm/init_32.c

-28
Original file line numberDiff line numberDiff line change
@@ -394,23 +394,6 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
394394

395395
pkmap_page_table = virt_to_kpte(vaddr);
396396
}
397-
398-
void __init add_highpages_with_active_regions(int nid,
399-
unsigned long start_pfn, unsigned long end_pfn)
400-
{
401-
phys_addr_t start, end;
402-
u64 i;
403-
404-
for_each_free_mem_range(i, nid, MEMBLOCK_NONE, &start, &end, NULL) {
405-
unsigned long pfn = clamp_t(unsigned long, PFN_UP(start),
406-
start_pfn, end_pfn);
407-
unsigned long e_pfn = clamp_t(unsigned long, PFN_DOWN(end),
408-
start_pfn, end_pfn);
409-
for ( ; pfn < e_pfn; pfn++)
410-
if (pfn_valid(pfn))
411-
free_highmem_page(pfn_to_page(pfn));
412-
}
413-
}
414397
#else
415398
static inline void permanent_kmaps_init(pgd_t *pgd_base)
416399
{
@@ -715,17 +698,6 @@ void __init mem_init(void)
715698
#ifdef CONFIG_FLATMEM
716699
BUG_ON(!mem_map);
717700
#endif
718-
/*
719-
* With CONFIG_DEBUG_PAGEALLOC initialization of highmem pages has to
720-
* be done before memblock_free_all(). Memblock use free low memory for
721-
* temporary data (see find_range_array()) and for this purpose can use
722-
* pages that was already passed to the buddy allocator, hence marked as
723-
* not accessible in the page tables when compiled with
724-
* CONFIG_DEBUG_PAGEALLOC. Otherwise order of initialization is not
725-
* important here.
726-
*/
727-
set_highmem_pages_init();
728-
729701
/* this will put all low memory onto the freelists */
730702
memblock_free_all();
731703

arch/xtensa/mm/init.c

-29
Original file line numberDiff line numberDiff line change
@@ -129,41 +129,12 @@ void __init zones_init(void)
129129
print_vm_layout();
130130
}
131131

132-
static void __init free_highpages(void)
133-
{
134-
#ifdef CONFIG_HIGHMEM
135-
unsigned long max_low = max_low_pfn;
136-
phys_addr_t range_start, range_end;
137-
u64 i;
138-
139-
/* set highmem page free */
140-
for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE,
141-
&range_start, &range_end, NULL) {
142-
unsigned long start = PFN_UP(range_start);
143-
unsigned long end = PFN_DOWN(range_end);
144-
145-
/* Ignore complete lowmem entries */
146-
if (end <= max_low)
147-
continue;
148-
149-
/* Truncate partial highmem entries */
150-
if (start < max_low)
151-
start = max_low;
152-
153-
for (; start < end; start++)
154-
free_highmem_page(pfn_to_page(start));
155-
}
156-
#endif
157-
}
158-
159132
/*
160133
* Initialize memory pages.
161134
*/
162135

163136
void __init mem_init(void)
164137
{
165-
free_highpages();
166-
167138
memblock_free_all();
168139
}
169140

include/linux/mm.h

-1
Original file line numberDiff line numberDiff line change
@@ -3275,7 +3275,6 @@ extern void reserve_bootmem_region(phys_addr_t start,
32753275

32763276
/* Free the reserved page into the buddy system, so it gets managed. */
32773277
void free_reserved_page(struct page *page);
3278-
#define free_highmem_page(page) free_reserved_page(page)
32793278

32803279
static inline void mark_page_reserved(struct page *page)
32813280
{

mm/memblock.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -2164,8 +2164,7 @@ static unsigned long __init __free_memory_core(phys_addr_t start,
21642164
phys_addr_t end)
21652165
{
21662166
unsigned long start_pfn = PFN_UP(start);
2167-
unsigned long end_pfn = min_t(unsigned long,
2168-
PFN_DOWN(end), max_low_pfn);
2167+
unsigned long end_pfn = PFN_DOWN(end);
21692168

21702169
if (start_pfn >= end_pfn)
21712170
return 0;

0 commit comments

Comments
 (0)