Skip to content

Commit e63075a

Browse files
committed
memblock: Introduce default allocation limit and use it to replace explicit ones
This introduce memblock.current_limit which is used to limit allocations from memblock_alloc() or memblock_alloc_base(..., MEMBLOCK_ALLOC_ACCESSIBLE). The old MEMBLOCK_ALLOC_ANYWHERE changes value from 0 to ~(u64)0 and can still be used with memblock_alloc_base() to allocate really anywhere. It is -no-longer- cropped to MEMBLOCK_REAL_LIMIT which disappears. Note to archs: I'm leaving the default limit to MEMBLOCK_ALLOC_ANYWHERE. I strongly recommend that you ensure that you set an appropriate limit during boot in order to guarantee that an memblock_alloc() at any time results in something that is accessible with a simple __va(). The reason is that a subsequent patch will introduce the ability for the array to resize itself by reallocating itself. The MEMBLOCK core will honor the current limit when performing those allocations. Signed-off-by: Benjamin Herrenschmidt <[email protected]>
1 parent 27f574c commit e63075a

File tree

14 files changed

+63
-53
lines changed

14 files changed

+63
-53
lines changed

arch/microblaze/include/asm/memblock.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
#ifndef _ASM_MICROBLAZE_MEMBLOCK_H
1010
#define _ASM_MICROBLAZE_MEMBLOCK_H
1111

12-
/* MEMBLOCK limit is OFF */
13-
#define MEMBLOCK_REAL_LIMIT 0xFFFFFFFF
14-
1512
#endif /* _ASM_MICROBLAZE_MEMBLOCK_H */
1613

1714

arch/powerpc/include/asm/memblock.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,4 @@
55

66
#define MEMBLOCK_DBG(fmt...) udbg_printf(fmt)
77

8-
#ifdef CONFIG_PPC32
9-
extern phys_addr_t lowmem_end_addr;
10-
#define MEMBLOCK_REAL_LIMIT lowmem_end_addr
11-
#else
12-
#define MEMBLOCK_REAL_LIMIT 0
13-
#endif
14-
158
#endif /* _ASM_POWERPC_MEMBLOCK_H */

arch/powerpc/kernel/prom.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static void __init move_device_tree(void)
9898

9999
if ((memory_limit && (start + size) > memory_limit) ||
100100
overlaps_crashkernel(start, size)) {
101-
p = __va(memblock_alloc_base(size, PAGE_SIZE, memblock.rmo_size));
101+
p = __va(memblock_alloc(size, PAGE_SIZE));
102102
memcpy(p, initial_boot_params, size);
103103
initial_boot_params = (struct boot_param_header *)p;
104104
DBG("Moved device tree to 0x%p\n", p);
@@ -655,6 +655,21 @@ static void __init phyp_dump_reserve_mem(void)
655655
static inline void __init phyp_dump_reserve_mem(void) {}
656656
#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */
657657

658+
static void set_boot_memory_limit(void)
659+
{
660+
#ifdef CONFIG_PPC32
661+
/* 601 can only access 16MB at the moment */
662+
if (PVR_VER(mfspr(SPRN_PVR)) == 1)
663+
memblock_set_current_limit(0x01000000);
664+
/* 8xx can only access 8MB at the moment */
665+
else if (PVR_VER(mfspr(SPRN_PVR)) == 0x50)
666+
memblock_set_current_limit(0x00800000);
667+
else
668+
memblock_set_current_limit(0x10000000);
669+
#else
670+
memblock_set_current_limit(memblock.rmo_size);
671+
#endif
672+
}
658673

659674
void __init early_init_devtree(void *params)
660675
{
@@ -683,6 +698,7 @@ void __init early_init_devtree(void *params)
683698

684699
/* Scan memory nodes and rebuild MEMBLOCKs */
685700
memblock_init();
701+
686702
of_scan_flat_dt(early_init_dt_scan_root, NULL);
687703
of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
688704

@@ -718,6 +734,8 @@ void __init early_init_devtree(void *params)
718734

719735
DBG("Phys. mem: %llx\n", memblock_phys_mem_size());
720736

737+
set_boot_memory_limit();
738+
721739
/* We may need to relocate the flat tree, do it now.
722740
* FIXME .. and the initrd too? */
723741
move_device_tree();

arch/powerpc/kernel/setup_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ static void __init irqstack_early_init(void)
246246
unsigned int i;
247247

248248
/* interrupt stacks must be in lowmem, we get that for free on ppc32
249-
* as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
249+
* as the memblock is limited to lowmem by default */
250250
for_each_possible_cpu(i) {
251251
softirq_ctx[i] = (struct thread_info *)
252252
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));

arch/powerpc/mm/40x_mmu.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <linux/init.h>
3636
#include <linux/delay.h>
3737
#include <linux/highmem.h>
38+
#include <linux/memblock.h>
3839

3940
#include <asm/pgalloc.h>
4041
#include <asm/prom.h>
@@ -47,6 +48,7 @@
4748
#include <asm/bootx.h>
4849
#include <asm/machdep.h>
4950
#include <asm/setup.h>
51+
5052
#include "mmu_decl.h"
5153

5254
extern int __map_without_ltlbs;
@@ -139,8 +141,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
139141
* coverage with normal-sized pages (or other reasons) do not
140142
* attempt to allocate outside the allowed range.
141143
*/
142-
143-
__initial_memory_limit_addr = memstart_addr + mapped;
144+
memblock_set_current_limit(memstart_addr + mapped);
144145

145146
return mapped;
146147
}

arch/powerpc/mm/fsl_booke_mmu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <linux/init.h>
4141
#include <linux/delay.h>
4242
#include <linux/highmem.h>
43+
#include <linux/memblock.h>
4344

4445
#include <asm/pgalloc.h>
4546
#include <asm/prom.h>
@@ -212,5 +213,5 @@ void __init adjust_total_lowmem(void)
212213
pr_cont("%lu Mb, residual: %dMb\n", tlbcam_sz(tlbcam_index - 1) >> 20,
213214
(unsigned int)((total_lowmem - __max_low_memory) >> 20));
214215

215-
__initial_memory_limit_addr = memstart_addr + __max_low_memory;
216+
memblock_set_current_limit(memstart_addr + __max_low_memory);
216217
}

arch/powerpc/mm/hash_utils_64.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,8 @@ static void __init htab_initialize(void)
696696
#endif /* CONFIG_U3_DART */
697697
BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
698698
prot, mmu_linear_psize, mmu_kernel_ssize));
699-
}
699+
}
700+
memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
700701

701702
/*
702703
* If we have a memory_limit and we've allocated TCEs then we need to

arch/powerpc/mm/init_32.c

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,6 @@ int __allow_ioremap_reserved;
9191
/* max amount of low RAM to map in */
9292
unsigned long __max_low_memory = MAX_LOW_MEM;
9393

94-
/*
95-
* address of the limit of what is accessible with initial MMU setup -
96-
* 256MB usually, but only 16MB on 601.
97-
*/
98-
phys_addr_t __initial_memory_limit_addr = (phys_addr_t)0x10000000;
99-
10094
/*
10195
* Check for command-line options that affect what MMU_init will do.
10296
*/
@@ -126,13 +120,6 @@ void __init MMU_init(void)
126120
if (ppc_md.progress)
127121
ppc_md.progress("MMU:enter", 0x111);
128122

129-
/* 601 can only access 16MB at the moment */
130-
if (PVR_VER(mfspr(SPRN_PVR)) == 1)
131-
__initial_memory_limit_addr = 0x01000000;
132-
/* 8xx can only access 8MB at the moment */
133-
if (PVR_VER(mfspr(SPRN_PVR)) == 0x50)
134-
__initial_memory_limit_addr = 0x00800000;
135-
136123
/* parse args from command line */
137124
MMU_setup();
138125

@@ -190,20 +177,18 @@ void __init MMU_init(void)
190177
#ifdef CONFIG_BOOTX_TEXT
191178
btext_unmap();
192179
#endif
180+
181+
/* Shortly after that, the entire linear mapping will be available */
182+
memblock_set_current_limit(lowmem_end_addr);
193183
}
194184

195185
/* This is only called until mem_init is done. */
196186
void __init *early_get_page(void)
197187
{
198-
void *p;
199-
200-
if (init_bootmem_done) {
201-
p = alloc_bootmem_pages(PAGE_SIZE);
202-
} else {
203-
p = __va(memblock_alloc_base(PAGE_SIZE, PAGE_SIZE,
204-
__initial_memory_limit_addr));
205-
}
206-
return p;
188+
if (init_bootmem_done)
189+
return alloc_bootmem_pages(PAGE_SIZE);
190+
else
191+
return __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
207192
}
208193

209194
/* Free up now-unused memory */

arch/powerpc/mm/ppc_mmu_32.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ void __init MMU_init_hw(void)
223223
* Find some memory for the hash table.
224224
*/
225225
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
226-
Hash = __va(memblock_alloc_base(Hash_size, Hash_size,
227-
__initial_memory_limit_addr));
226+
Hash = __va(memblock_alloc(Hash_size, Hash_size));
228227
cacheable_memzero(Hash, Hash_size);
229228
_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
230229

arch/powerpc/mm/tlb_nohash.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ static void __early_init_mmu(int boot_cpu)
432432
* the MMU configuration
433433
*/
434434
mb();
435+
436+
memblock_set_current_limit(linear_map_top);
435437
}
436438

437439
void __init early_init_mmu(void)

arch/sh/include/asm/memblock.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
#ifndef __ASM_SH_MEMBLOCK_H
22
#define __ASM_SH_MEMBLOCK_H
33

4-
#define MEMBLOCK_REAL_LIMIT 0
5-
64
#endif /* __ASM_SH_MEMBLOCK_H */

arch/sparc/include/asm/memblock.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,4 @@
55

66
#define MEMBLOCK_DBG(fmt...) prom_printf(fmt)
77

8-
#define MEMBLOCK_REAL_LIMIT 0
9-
108
#endif /* !(_SPARC64_MEMBLOCK_H) */

include/linux/memblock.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct memblock_type {
3434
struct memblock {
3535
unsigned long debug;
3636
u64 rmo_size;
37+
u64 current_limit;
3738
struct memblock_type memory;
3839
struct memblock_type reserved;
3940
};
@@ -46,11 +47,16 @@ extern long memblock_add(u64 base, u64 size);
4647
extern long memblock_remove(u64 base, u64 size);
4748
extern long __init memblock_free(u64 base, u64 size);
4849
extern long __init memblock_reserve(u64 base, u64 size);
50+
4951
extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid);
5052
extern u64 __init memblock_alloc(u64 size, u64 align);
53+
54+
/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */
55+
#define MEMBLOCK_ALLOC_ANYWHERE (~(u64)0)
56+
#define MEMBLOCK_ALLOC_ACCESSIBLE 0
57+
5158
extern u64 __init memblock_alloc_base(u64 size,
5259
u64, u64 max_addr);
53-
#define MEMBLOCK_ALLOC_ANYWHERE 0
5460
extern u64 __init __memblock_alloc_base(u64 size,
5561
u64 align, u64 max_addr);
5662
extern u64 __init memblock_phys_mem_size(void);
@@ -66,6 +72,14 @@ extern void memblock_dump_all(void);
6672
/* Provided by the architecture */
6773
extern u64 memblock_nid_range(u64 start, u64 end, int *nid);
6874

75+
/**
76+
* memblock_set_current_limit - Set the current allocation limit to allow
77+
* limiting allocations to what is currently
78+
* accessible during boot
79+
* @limit: New limit value (physical address)
80+
*/
81+
extern void memblock_set_current_limit(u64 limit);
82+
6983

7084
/*
7185
* pfn conversion functions

mm/memblock.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ void __init memblock_init(void)
115115
memblock.reserved.regions[0].base = 0;
116116
memblock.reserved.regions[0].size = 0;
117117
memblock.reserved.cnt = 1;
118+
119+
memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
118120
}
119121

120122
void __init memblock_analyze(void)
@@ -373,7 +375,7 @@ u64 __init memblock_alloc_nid(u64 size, u64 align, int nid)
373375

374376
u64 __init memblock_alloc(u64 size, u64 align)
375377
{
376-
return memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ANYWHERE);
378+
return memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
377379
}
378380

379381
u64 __init memblock_alloc_base(u64 size, u64 align, u64 max_addr)
@@ -399,14 +401,9 @@ u64 __init __memblock_alloc_base(u64 size, u64 align, u64 max_addr)
399401

400402
size = memblock_align_up(size, align);
401403

402-
/* On some platforms, make sure we allocate lowmem */
403-
/* Note that MEMBLOCK_REAL_LIMIT may be MEMBLOCK_ALLOC_ANYWHERE */
404-
if (max_addr == MEMBLOCK_ALLOC_ANYWHERE)
405-
max_addr = MEMBLOCK_REAL_LIMIT;
406-
407404
/* Pump up max_addr */
408-
if (max_addr == MEMBLOCK_ALLOC_ANYWHERE)
409-
max_addr = ~(u64)0;
405+
if (max_addr == MEMBLOCK_ALLOC_ACCESSIBLE)
406+
max_addr = memblock.current_limit;
410407

411408
/* We do a top-down search, this tends to limit memory
412409
* fragmentation by keeping early boot allocs near the
@@ -527,3 +524,9 @@ int memblock_is_region_reserved(u64 base, u64 size)
527524
return memblock_overlaps_region(&memblock.reserved, base, size) >= 0;
528525
}
529526

527+
528+
void __init memblock_set_current_limit(u64 limit)
529+
{
530+
memblock.current_limit = limit;
531+
}
532+

0 commit comments

Comments
 (0)