memblock updates
Subsystems (10)
Hi folks !
Here's my current branch. This time build tested on sparc(64), arm, powerpc and sh. I don't have a microblaze compiler at hand.
Not much difference from the previous one. Off the top of my head:
- Added the memblock_is_region_reserved() fix at the beginning (I'll send that to Linus separately if we decide this series shouldn't go in 2.6.36)
- Split the patch adding the new accessors into separate patches for adding the accessors, converting each arch, and removing the old accessors. This makes it clearer, easier to review, etc... I added a couple new accessors for ARM.
- Added the ARM updates based on what's upstream now (involves new memblock_is_memory() and memblock_is_memory_region() for use by ARM, nothing fancy there).
So very little changes. I haven't changed the init sections so the warnings reported by Steven are still there. I will fix them as an addon patch as I don't believe there's any actual breakage.
Now, what do you guys want to do with this now ? I can ask Linus to pull now or we can wait until the end of the merge window and put it into -next for another round...
Cheers,
Ben.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/43 memblock: Fix memblock_is_region_reserved() to return a boolean
All callers expect a boolean result which is true if the region overlaps a reserved region. However, the implementation actually returns -1 if there is no overlap, and a region index (0 based) if there is.
Make it behave as callers (and common sense) expect.
--- mm/memblock.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
mm/memblock.c +1 -1
@@ -504,7 +504,7 @@ int __init memblock_is_reserved(u64 addr)int memblock_is_region_reserved (u64 base,u64 size) { -return memblock_overlaps_region (&memblock.reserved, base, size); +return memblock_overlaps_region (&memblock.reserved, base, size) >=0 ; }/*
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/43 memblock: Rename memblock_region to memblock_type and memblock_property to memblock_region
In reply to Benjamin Herrenschmidt--- arch/arm/mm/init.c | 2 +- arch/arm/plat-omap/fb.c | 2 +- arch/microblaze/mm/init.c | 4 +- arch/powerpc/mm/hash_utils_64.c | 2 +- arch/powerpc/mm/mem.c | 26 +++--- arch/powerpc/platforms/embedded6xx/wii.c | 2 +- arch/sparc/mm/init_64.c | 6 +- drivers/video/omap2/vram.c | 2 +- include/linux/memblock.h | 24 ++-- mm/memblock.c | 168 +++++++++++++++--------------- 10 files changed, 118 insertions(+), 120 deletions(-)
arch/arm/mm/init.c +1 -1
@@ -237,7 +237,7 @@ static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,#ifndef CONFIG_SPARSEMEM int pfn_valid (unsigned long pfn) { -struct memblock_region *mem = &memblock.memory; +struct memblock_type *mem = &memblock.memory;unsigned int left =0 , right = mem->cnt; do {
arch/arm/plat-omap/fb.c +1 -1
@@ -173,7 +173,7 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,static int valid_sdram (unsigned long addr,unsigned long size) { -struct memblock_property res; +struct memblock_region res; res.base = addr; res.size = size;
arch/microblaze/mm/init.c +2 -2
@@ -77,8 +77,8 @@ void __init setup_memory(void)/* Find main memory where is the kernel */ for (i =0 ; i < memblock.memory.cnt; i++) { - memory_start = (u32 ) memblock.memory.region[i].base; - memory_end = (u32 ) memblock.memory.region[i].base + memory_start = (u32 ) memblock.memory.regions[i].base; + memory_end = (u32 ) memblock.memory.regions[i].base + (u32 ) memblock.memory.region[i].size;if ((memory_start <= (u32 )_text) && ((u32 )_text <= memory_end)) {
arch/powerpc/mm/hash_utils_64.c +1 -1
@@ -660,7 +660,7 @@ static void __init htab_initialize(void)/* create bolted the linear mapping in the hash table */ for (i=0 ; i < memblock.memory.cnt; i++) { - base = (unsigned long )__va (memblock.memory.region[i].base); + base = (unsigned long )__va (memblock.memory.regions[i].base); size = memblock.memory.region[i].size; DBG("creating mapping for region: %lx..%lx (prot: %lx)\n",
arch/powerpc/mm/mem.c +13 -13
@@ -86,10 +86,10 @@ int page_is_ram(unsigned long pfn)for (i=0 ; i < memblock.memory.cnt; i++) {unsigned long base; - base = memblock.memory.region[i].base; + base = memblock.memory.regions[i].base;if ((paddr >= base) && - (paddr < (base + memblock.memory.region[i].size))) { + (paddr < (base + memblock.memory.regions[i].size))) {return 1 ; } }
@@ -149,7 +149,7 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)) { - struct memblock_property res; + struct memblock_region res;unsigned long pfn, len;u64 end;int ret =-1 ;
@@ -206,7 +206,7 @@ void __init do_init_bootmem(void)/* Add active regions with valid PFNs */ for (i =0 ; i < memblock.memory.cnt; i++) {unsigned long start_pfn, end_pfn; - start_pfn = memblock.memory.region[i].base >>PAGE_SHIFT ; + start_pfn = memblock.memory.regions[i].base >>PAGE_SHIFT ; end_pfn = start_pfn +memblock_size_pages (&memblock.memory, i);add_active_range (0 , start_pfn, end_pfn); }
@@ -219,16 +219,16 @@ void __init do_init_bootmem(void)/* reserve the sections we're already using */ for (i =0 ; i < memblock.reserved.cnt; i++) { -unsigned long addr = memblock.reserved.region[i].base + +unsigned long addr = memblock.reserved.regions[i].base +memblock_size_bytes (&memblock.reserved, i) -1 ;if (addr < lowmem_end_addr) -reserve_bootmem (memblock.reserved.region[i].base, +reserve_bootmem (memblock.reserved.regions[i].base,memblock_size_bytes (&memblock.reserved, i),BOOTMEM_DEFAULT ); -else if (memblock.reserved.region[i].base < lowmem_end_addr) { +else if (memblock.reserved.regions[i].base < lowmem_end_addr) {unsigned long adjusted_size = lowmem_end_addr - - memblock.reserved.region[i].base; -reserve_bootmem (memblock.reserved.region[i].base, + memblock.reserved.regions[i].base; +reserve_bootmem (memblock.reserved.regions[i].base, adjusted_size,BOOTMEM_DEFAULT ); } }
@@ -237,7 +237,7 @@ void __init do_init_bootmem(void)/* reserve the sections we're already using */ for (i =0 ; i < memblock.reserved.cnt; i++) -reserve_bootmem (memblock.reserved.region[i].base, +reserve_bootmem (memblock.reserved.regions[i].base,memblock_size_bytes (&memblock.reserved, i),BOOTMEM_DEFAULT );
@@ -257,10 +257,10 @@ static int __init mark_nonram_nosave(void)for (i =0 ; i < memblock.memory.cnt -1 ; i++) { memblock_region_max_pfn = - (memblock.memory.region[i].base >>PAGE_SHIFT ) + - (memblock.memory.region[i].size >>PAGE_SHIFT ); + (memblock.memory.regions[i].base >>PAGE_SHIFT ) + + (memblock.memory.regions[i].size >>PAGE_SHIFT ); memblock_next_region_start_pfn = - memblock.memory.region[i+1 ].base >>PAGE_SHIFT ; + memblock.memory.regions[i+1 ].base >>PAGE_SHIFT ;if (memblock_region_max_pfn < memblock_next_region_start_pfn) register_nosave_region(memblock_region_max_pfn,
arch/powerpc/platforms/embedded6xx/wii.c +1 -1
@@ -65,7 +65,7 @@ static int __init page_aligned(unsigned long x)void __init wii_memory_fixups (void ) { -struct memblock_property *p = memblock.memory.region; +struct memblock_region *p = memblock.memory.region;/* * This is part of a workaround to allow the use of two
arch/sparc/mm/init_64.c +3 -3
@@ -978,7 +978,7 @@ static void __init add_node_ranges(void)unsigned long size =memblock_size_bytes (&memblock.memory, i);unsigned long start, end; - start = memblock.memory.region[i].base; + start = memblock.memory.regions[i].base; end = start + size;while (start < end) {unsigned long this_end;
@@ -1299,7 +1299,7 @@ static void __init bootmem_init_nonnuma(void)if (!size)continue ; - start_pfn = memblock.memory.region[i].base >>PAGE_SHIFT ; + start_pfn = memblock.memory.regions[i].base >>PAGE_SHIFT ; end_pfn = start_pfn +memblock_size_pages (&memblock.memory, i);add_active_range (0 , start_pfn, end_pfn); }
@@ -1339,7 +1339,7 @@ static void __init trim_reserved_in_node(int nid)numadbg (" trim_reserved_in_node(%d)\n" , nid);for (i =0 ; i < memblock.reserved.cnt; i++) { -unsigned long start = memblock.reserved.region[i].base; +unsigned long start = memblock.reserved.regions[i].base;unsigned long size =memblock_size_bytes (&memblock.reserved, i);unsigned long end = start + size;
drivers/video/omap2/vram.c +1 -1
@@ -554,7 +554,7 @@ void __init omap_vram_reserve_sdram_memblock(void) size =PAGE_ALIGN (size);if (paddr) { -struct memblock_property res; +struct memblock_region res; res.base = paddr; res.size = size;
include/linux/memblock.h +12 -12
@@ -18,22 +18,22 @@#define MAX_MEMBLOCK_REGIONS 128 -struct memblock_property { +struct memblock_region {u64 base;u64 size; }; -struct memblock_region { +struct memblock_type {unsigned long cnt;u64 size; -struct memblock_property region[MAX_MEMBLOCK_REGIONS +1 ]; +struct memblock_region regions[MAX_MEMBLOCK_REGIONS +1 ]; };struct memblock {unsigned long debug;u64 rmo_size; -struct memblock_region memory; -struct memblock_region reserved; +struct memblock_type memory; +struct memblock_type reserved; };extern struct memblock memblock;
@@ -56,27 +56,27 @@ extern u64 memblock_end_of_DRAM(void);extern void __init memblock_enforce_memory_limit (u64 memory_limit);extern int __init memblock_is_reserved (u64 addr);extern int memblock_is_region_reserved (u64 base,u64 size); -extern int memblock_find (struct memblock_property *res); +extern int memblock_find (struct memblock_region *res);extern void memblock_dump_all (void );static inline u64 -memblock_size_bytes (struct memblock_region *type,unsigned long region_nr) +memblock_size_bytes (struct memblock_type *type,unsigned long region_nr) { -return type->region[region_nr].size; +return type->regions[region_nr].size; }static inline u64 -memblock_size_pages (struct memblock_region *type,unsigned long region_nr) +memblock_size_pages (struct memblock_type *type,unsigned long region_nr) {return memblock_size_bytes (type, region_nr) >>PAGE_SHIFT ; }static inline u64 -memblock_start_pfn (struct memblock_region *type,unsigned long region_nr) +memblock_start_pfn (struct memblock_type *type,unsigned long region_nr) { -return type->region[region_nr].base >>PAGE_SHIFT ; +return type->regions[region_nr].base >>PAGE_SHIFT ; }static inline u64 -memblock_end_pfn (struct memblock_region *type,unsigned long region_nr) +memblock_end_pfn (struct memblock_type *type,unsigned long region_nr) {return memblock_start_pfn (type, region_nr) +memblock_size_pages (type, region_nr);
mm/memblock.c +83 -85
402 lines not on this page · raw message
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/43 memblock: No reason to include asm/memblock.h late
In reply to Benjamin Herrenschmidt--- include/linux/memblock.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
include/linux/memblock.h +2 -2
@@ -16,6 +16,8 @@#include <linux/init.h> #include <linux/mm.h> +#include <asm/memblock.h> +#define MAX_MEMBLOCK_REGIONS 128struct memblock_region {
@@ -82,8 +84,6 @@ memblock_end_pfn(struct memblock_type *type, unsigned long region_nr)memblock_size_pages (type, region_nr); } -#include <asm/memblock.h> -#endif /* __KERNEL__ */ #endif /* _LINUX_MEMBLOCK_H */
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/43 memblock: Implement memblock_is_memory and memblock_is_region_memory
In reply to Benjamin HerrenschmidtTo make it fast, we steal ARM's binary search for memblock_is_memory() and we use that to also the replace existing implementation of memblock_is_reserved().
--- include/linux/memblock.h | 2 ++ mm/memblock.c | 42 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-)
include/linux/memblock.h +2 -0
@@ -56,6 +56,8 @@ extern u64 __init __memblock_alloc_base(u64 size,extern u64 __init memblock_phys_mem_size (void );extern u64 memblock_end_of_DRAM (void );extern void __init memblock_enforce_memory_limit (u64 memory_limit); +extern int memblock_is_memory (u64 addr); +extern int memblock_is_region_memory (u64 base,u64 size);extern int __init memblock_is_reserved (u64 addr);extern int memblock_is_region_reserved (u64 base,u64 size);extern int memblock_find (struct memblock_region *res);
mm/memblock.c +34 -8
51 lines not on this page · raw message
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 5/43 memblock/arm: pfn_valid uses memblock_is_memory()
In reply to Benjamin HerrenschmidtThe implementation is pretty much similar. There is a -small- added overhead by having another function call and the address shift.
If that becomes a concern, I suppose we could actually have memblock itself expose a memblock_pfn_valid() which then ARM can use directly with an appropriate #define...
--- arch/arm/mm/init.c | 15 +-------------- 1 files changed, 1 insertions(+), 14 deletions(-)
arch/arm/mm/init.c +1 -14
@@ -237,20 +237,7 @@ static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,#ifndef CONFIG_SPARSEMEM int pfn_valid (unsigned long pfn) { -struct memblock_type *mem = &memblock.memory; -unsigned int left =0 , right = mem->cnt; - -do { -unsigned int mid = (right + left) /2 ; - -if (pfn <memblock_start_pfn (mem, mid)) - right = mid; -else if (pfn >=memblock_end_pfn (mem, mid)) - left = mid +1 ; -else -return 1 ; - }while (left < right); -return 0 ; +return memblock_is_memory (pfn <<PAGE_SHIFT ); }EXPORT_SYMBOL (pfn_valid);
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/43 memblock/arm: Use memblock_region_is_memory() for omap fb
In reply to Benjamin HerrenschmidtInstead of the deprecated memblock_find()
--- arch/arm/plat-omap/fb.c | 6 +----- drivers/video/omap2/vram.c | 8 ++------ 2 files changed, 3 insertions(+), 11 deletions(-)
arch/arm/plat-omap/fb.c +1 -5
@@ -173,11 +173,7 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,static int valid_sdram (unsigned long addr,unsigned long size) { -struct memblock_region res; - - res.base = addr; - res.size = size; -return !memblock_find (&res) && res.base == addr && res.size == size; +return memblock_region_is_memory (addr, size); }static int reserve_sdram (unsigned long addr,unsigned long size)
drivers/video/omap2/vram.c +2 -6
@@ -554,12 +554,8 @@ void __init omap_vram_reserve_sdram_memblock(void) size =PAGE_ALIGN (size);if (paddr) { -struct memblock_region res; - - res.base = paddr; - res.size = size; -if ((paddr & ~PAGE_MASK ) ||memblock_find (&res) || - res.base != paddr || res.size != size) { +if ((paddr & ~PAGE_MASK ) || + !memblock_region_is_memory (paddr, size)) {pr_err ("Illegal SDRAM region for VRAM\n" );return ; }
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 7/43 memblock: Introduce for_each_memblock() and new accessors
In reply to Benjamin HerrenschmidtWalk memblock's using for_each_memblock() and use memblock_region_base/end_pfn() for getting to PFNs.
--- include/linux/memblock.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+), 0 deletions(-)
include/linux/memblock.h +52 -0
@@ -64,6 +64,7 @@ extern int memblock_find(struct memblock_region *res);extern void memblock_dump_all (void ); +/* Obsolete accessors */ static inline u64 memblock_size_bytes (struct memblock_type *type,unsigned long region_nr) {
@@ -86,6 +87,57 @@ memblock_end_pfn(struct memblock_type *type, unsigned long region_nr)memblock_size_pages (type, region_nr); } +/* +* pfn conversion functions +* +* While the memory MEMBLOCKs should always be page aligned, the reserved +* MEMBLOCKs may not be. This accessor attempt to provide a very clear +* idea of what they return for such non aligned MEMBLOCKs. +*/ + +/** +* memblock_region_base_pfn - Return the lowest pfn intersecting with the region +* @reg: memblock_region structure +*/ +static inline unsigned long memblock_region_base_pfn (const struct memblock_region *reg) +{ +return reg->base >>PAGE_SHIFT ; +} + +/** +* memblock_region_last_pfn - Return the highest pfn intersecting with the region +* @reg: memblock_region structure +*/ +static inline unsigned long memblock_region_last_pfn (const struct memblock_region *reg) +{ +return (reg->base + reg->size -1 ) >>PAGE_SHIFT ; +} + +/** +* memblock_region_end_pfn - Return the pfn of the first page following the region +* but not intersecting it +* @reg: memblock_region structure +*/ +static inline unsigned long memblock_region_end_pfn (const struct memblock_region *reg) +{ +return memblock_region_last_pfn (reg) +1 ; +} + +/** +* memblock_region_pages - Return the number of pages covering a region +* @reg: memblock_region structure +*/ +static inline unsigned long memblock_region_pages (const struct memblock_region *reg) +{ +return memblock_region_end_pfn (reg) -memblock_region_end_pfn (reg); +} + +#define for_each_memblock (memblock_type, region) \ + for (region = memblock.memblock_type.regions; \ + region < (memblock.memblock_type.regions + memblock.memblock_type.cnt); \ + region++) + +#endif /* __KERNEL__ */ #endif /* _LINUX_MEMBLOCK_H */
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 8/43 memblock/microblaze: Use new accessors
In reply to Benjamin Herrenschmidt--- arch/microblaze/mm/init.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-)
arch/microblaze/mm/init.c +9 -11
@@ -70,16 +70,16 @@ static void __init paging_init(void)void __init setup_memory (void ) { -int i;unsigned long map_size; +struct memblock_region *reg; +#ifndef CONFIG_MMU u32 kernel_align_start, kernel_align_size;/* Find main memory where is the kernel */ -for (i =0 ; i < memblock.memory.cnt; i++) { - memory_start = (u32 ) memblock.memory.regions[i].base; - memory_end = (u32 ) memblock.memory.regions[i].base - + (u32 ) memblock.memory.region[i].size; +for_each_memblock (memory, reg) { + memory_start = (u32 )reg->base; + memory_end = (u32 ) reg->base + reg->size;if ((memory_start <= (u32 )_text) && ((u32 )_text <= memory_end)) { memory_size = memory_end - memory_start;
@@ -147,12 +147,10 @@ void __init setup_memory(void)free_bootmem (memory_start, memory_size);/* reserve allocate blocks */ -for (i =0 ; i < memblock.reserved.cnt; i++) { -pr_debug ("reserved %d - 0x%08x-0x%08x\n" , i, - (u32 ) memblock.reserved.region[i].base, - (u32 )memblock_size_bytes (&memblock.reserved, i)); -reserve_bootmem (memblock.reserved.region[i].base, -memblock_size_bytes (&memblock.reserved, i) -1 ,BOOTMEM_DEFAULT ); +for_each_memblock (reserved, reg) { +pr_debug ("reserved - 0x%08x-0x%08x\n" , + (u32 ) reg->base, (u32 ) reg->size); +reserve_bootmem (reg->base, reg->size,BOOTMEM_DEFAULT ); }#ifdef CONFIG_MMU init_bootmem_done =1 ;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Simek
maintainerRe: [PATCH 08/43] memblock/microblaze: Use new accessors
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>
This patch remove bug which I reported but there is another place which needs to be changed.
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
I tested your memblock branch with this fix and microblaze can boot.
Thanks,
Michal
CC arch/microblaze/mm/init.oarch/microblaze/mm/init.c: In function 'mm_cmdline_setup':arch/microblaze/mm/init.c:236: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c: In function 'mmu_init':arch/microblaze/mm/init.c:279: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c:284: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c:285: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c:286: error: 'struct memblock_type' has no member named 'region' make[1]: *** [arch/microblaze/mm/init.o] Error 1
make: *** [arch/microblaze/mm] Error 2
arch/microblaze/mm/init.c +5 -5
@@ -233,7 +233,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }
@@ -276,14 +276,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not
used */
Quoted 47 lines
--- arch/microblaze/mm/init.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-)arch/microblaze/mm/init.c +9
-11@@ -70,16 +70,16 @@ static void __init paging_init(void)void __init setup_memory (void ) { -int i;unsigned long map_size; +struct memblock_region *reg; +#ifndef CONFIG_MMU u32 kernel_align_start, kernel_align_size;/* Find main memory where is the kernel */ -for (i =0 ; i < memblock.memory.cnt; i++) { - memory_start = (u32 ) memblock.memory.regions[i].base; - memory_end = (u32 ) memblock.memory.regions[i].base - + (u32 ) memblock.memory.region[i].size; +for_each_memblock (memory, reg) { + memory_start = (u32 )reg->base; + memory_end = (u32 ) reg->base + reg->size;if ((memory_start <= (u32 )_text) && ((u32 )_text <= memory_end)) { memory_size = memory_end - memory_start;@@ -147,12 +147,10 @@ void __init setup_memory(void)free_bootmem (memory_start, memory_size);/* reserve allocate blocks */ -for (i =0 ; i < memblock.reserved.cnt; i++) { -pr_debug ("reserved %d - 0x%08x-0x%08x\n" , i, - (u32 ) memblock.reserved.region[i].base, - (u32 )memblock_size_bytes (&memblock.reserved, i)); -reserve_bootmem (memblock.reserved.region[i].base, -memblock_size_bytes (&memblock.reserved, i) -1 ,BOOTMEM_DEFAULT ); +for_each_memblock (reserved, reg) { +pr_debug ("reserved - 0x%08x-0x%08x\n" , + (u32 ) reg->base, (u32 ) reg->size); +reserve_bootmem (reg->base, reg->size,BOOTMEM_DEFAULT ); }#ifdef CONFIG_MMU init_bootmem_done =1 ;
Signature · 10 lines
Michal Simek, Ing. (M.Eng) w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/ Microblaze U-BOOT custodian -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 08/43] memblock/microblaze: Use new accessors
Quoted 11 lines · Michal Simek
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>This patch remove bug which I reported but there is another place which needs to be changed.
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
I tested your memblock branch with this fix and microblaze can boot.
Ok, that's missing in my initial rename patch. I'll fix it up. Thanks.
Cheers,
Ben.
Quoted 89 lines
Thanks,
MichalCC
arch/microblaze/mm/init.oarch/microblaze/mm/init.c: In function 'mm_cmdline_setup':arch/microblaze/mm/init.c:236: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c: In function 'mmu_init':arch/microblaze/mm/init.c:279: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:284: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:285: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:286: error: 'structmemblock_type' has no member named 'region'
make[1]: *** [arch/microblaze/mm/init.o] Error 1
make: *** [arch/microblaze/mm] Error 2arch/microblaze/mm/init.c +5
-5@@ -233,7 +233,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }@@ -276,14 +276,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not used */
Quoted 33 lines
--- arch/microblaze/mm/init.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-)arch/microblaze/mm/init.c +5
-5@@ -70,16 +70,16 @@ static void __init paging_init(void)void __init setup_memory (void ) { -int i;unsigned long map_size; +struct memblock_region *reg; +#ifndef CONFIG_MMU u32 kernel_align_start, kernel_align_size;/* Find main memory where is the kernel */ -for (i =0 ; i < memblock.memory.cnt; i++) { - memory_start = (u32 ) memblock.memory.regions[i].base; - memory_end = (u32 ) memblock.memory.regions[i].base - + (u32 ) memblock.memory.region[i].size; +for_each_memblock (memory, reg) { + memory_start = (u32 )reg->base; + memory_end = (u32 ) reg->base + reg->size;if ((memory_start <= (u32 )_text) && ((u32 )_text <= memory_end)) { memory_size = memory_end - memory_start;@@ -147,12 +147,10 @@ void __init setup_memory(void)free_bootmem (memory_start, memory_size);
Quoted 16 lines
Quoted 4 lines
arch/microblaze/mm/init.c +0
-3/* reserve allocate blocks */ -for (i =0 ; i < memblock.reserved.cnt; i++) { - pr_debug("reserved %d - 0x%08x-0x%08x\n", i, - (u32) memblock.reserved.region[i].base,arch/microblaze/mm/init.c void __init setup_memory(void) · line 156
Quoted 10 lines
arch/microblaze/mm/init.c +4
-3- (u32) memblock_size_bytes(&memblock.reserved, i)); -reserve_bootmem (memblock.reserved.region[i].base, -memblock_size_bytes (&memblock.reserved, i) -1 ,BOOTMEM_DEFAULT ); +for_each_memblock (reserved, reg) { +pr_debug ("reserved - 0x%08x-0x%08x\n" , + (u32 ) reg->base, (u32 ) reg->size); +reserve_bootmem (reg->base, reg->size,BOOTMEM_DEFAULT ); }#ifdef CONFIG_MMU init_bootmem_done =1 ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Simek
maintainerRe: [PATCH 08/43] memblock/microblaze: Use new accessors
Quoted 6 lines · Benjamin Herrenschmidt
Quoted 5 lines · Michal Simek
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>This patch remove bug which I reported but there is another place which needs to be changed.
Quoted 8 lines
Quoted 3 lines
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
I tested your memblock branch with this fix and microblaze can boot.
Ok, that's missing in my initial rename patch. I'll fix it up. Thanks.
Cheers,
Ben.
I don't know why but this unfixed old patch is in linux-next today. Not sure which tree contains it.
Thanks,
Michal
Quoted 99 lines
Quoted 97 lines
CC
arch/microblaze/mm/init.oarch/microblaze/mm/init.c: In function 'mm_cmdline_setup':arch/microblaze/mm/init.c:236: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c: In function 'mmu_init':arch/microblaze/mm/init.c:279: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:284: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:285: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:286: error: 'structmemblock_type' has no member named 'region' make[1]: *** [arch/microblaze/mm/init.o] Error 1
make: *** [arch/microblaze/mm] Error 2arch/microblaze/mm/init.c +5
-5@@ -233,7 +233,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }@@ -276,14 +276,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not used */
Quoted 47 lines
--- arch/microblaze/mm/init.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-)arch/microblaze/mm/init.c +9
-11@@ -70,16 +70,16 @@ static void __init paging_init(void)void __init setup_memory (void ) { -int i;unsigned long map_size; +struct memblock_region *reg; +#ifndef CONFIG_MMU u32 kernel_align_start, kernel_align_size;/* Find main memory where is the kernel */ -for (i =0 ; i < memblock.memory.cnt; i++) { - memory_start = (u32 ) memblock.memory.regions[i].base; - memory_end = (u32 ) memblock.memory.regions[i].base - + (u32 ) memblock.memory.region[i].size; +for_each_memblock (memory, reg) { + memory_start = (u32 )reg->base; + memory_end = (u32 ) reg->base + reg->size;if ((memory_start <= (u32 )_text) && ((u32 )_text <= memory_end)) { memory_size = memory_end - memory_start;@@ -147,12 +147,10 @@ void __init setup_memory(void)free_bootmem (memory_start, memory_size);/* reserve allocate blocks */ -for (i =0 ; i < memblock.reserved.cnt; i++) { -pr_debug ("reserved %d - 0x%08x-0x%08x\n" , i, - (u32 ) memblock.reserved.region[i].base, - (u32 )memblock_size_bytes (&memblock.reserved, i)); -reserve_bootmem (memblock.reserved.region[i].base, -memblock_size_bytes (&memblock.reserved, i) -1 ,BOOTMEM_DEFAULT ); +for_each_memblock (reserved, reg) { +pr_debug ("reserved - 0x%08x-0x%08x\n" , + (u32 ) reg->base, (u32 ) reg->size); +reserve_bootmem (reg->base, reg->size,BOOTMEM_DEFAULT ); }#ifdef CONFIG_MMU init_bootmem_done =1 ;
Signature · 10 lines
Michal Simek, Ing. (M.Eng) w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/ Microblaze U-BOOT custodian -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 08/43] memblock/microblaze: Use new accessors
Hi Michal,
Quoted 14 lines · On Thu, 09 Sep 2010 12:57:19 +0200 Michal Simek <[email protected]> wrote:
Quoted 12 lines · Benjamin Herrenschmidt
Quoted 10 lines · Michal Simek
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>This patch remove bug which I reported but there is another place which needs to be changed.
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
I tested your memblock branch with this fix and microblaze can boot.
Quoted 7 lines
Quoted 4 lines
Ok, that's missing in my initial rename patch. I'll fix it up. Thanks.
Cheers,
Ben.I don't know why but this unfixed old patch is in linux-next today. Not sure which tree contains it.
It came in via the tip tree.
Signature · 3 lines
Cheers, Stephen Rothwell [email protected] http://www.canb.auug.org.au/~sfr/
Re: [PATCH 08/43] memblock/microblaze: Use new accessors
In reply to Michal SimekQuoted 11 lines · Michal Simek
Quoted 10 lines · Benjamin Herrenschmidt
Quoted 9 lines · Michal Simek
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>This patch remove bug which I reported but there is another place which needs to be changed.
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
I tested your memblock branch with this fix and microblaze can boot.
Ok, that's missing in my initial rename patch. I'll fix it up. Thanks.
Cheers,
Ben.I don't know why but this unfixed old patch is in linux-next today.
Yep, i asked benh to have a look (see the mail below) but got no response, as i assumed it had all been taken care of.
Ben, Peter?
Ingo
----- Forwarded message from Ingo Molnar <[email protected]> -----
Date: Tue, 31 Aug 2010 09:29:47 +0200
From: Ingo Molnar <[email protected]>
To: Benjamin Herrenschmidt <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected], [email protected]
Subject: Re: [tip:core/memblock] memblock: Rename memblock_region to
memblock_type and memblock_property to memblock_region
Quoted 9 lines · Benjamin Herrenschmidt
Quoted 7 lines · tip-bot for Benjamin Herrenschmidt
Commit-ID: e3239ff92a17976ac5d26fa0fe40ef3a9daf2523 Gitweb: http://git.kernel.org/tip/e3239ff92a17976ac5d26fa0fe40ef3a9daf2523 Author: Benjamin Herrenschmidt <[email protected]> AuthorDate: Wed, 4 Aug 2010 14:06:41 +1000 Committer: Benjamin Herrenschmidt <[email protected]> CommitDate: Wed, 4 Aug 2010 14:21:49 +1000
Quoted 5 lines
Quoted 1 line
memblock: Rename
memblock_regiontomemblock_typeandmemblock_propertytomemblock_regionHe, I was just about to rebase them :-)
Do you still need me to do that ?
Btw., because this is an older base, before we can push this to linux-next i suspect we'll need fixes for those architectures that did a memblock conversion in this cycle?
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 08/43] memblock/microblaze: Use new accessors
Quoted 17 lines · Ingo Molnar
Quoted 15 lines · Michal Simek
Quoted 14 lines · Benjamin Herrenschmidt
Quoted 10 lines · Michal Simek
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>This patch remove bug which I reported but there is another place which needs to be changed.
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
I tested your memblock branch with this fix and microblaze can boot.
Ok, that's missing in my initial rename patch. I'll fix it up. Thanks.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Cheers,
Ben.I don't know why but this unfixed old patch is in linux-next today.
Yep, i asked benh to have a look (see the mail below) but got no response, as i assumed it had all been taken care of.
Sorry, I must have been confused... I had pushed out a git branch a while back with those updates and the ARM bits, at least I think I did :-) I might have FAILed there. I'll check next week, I'm about to board on a plane right now.
Cheers,
Ben.
Quoted 38 lines
Ben, Peter?
Ingo
----- Forwarded message from Ingo Molnar <[email protected]> -----
Date: Tue, 31 Aug 2010 09:29:47 +0200
From: Ingo Molnar <[email protected]>
To: Benjamin Herrenschmidt <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected], [email protected]
Subject: Re: [tip:core/memblock] memblock: Renamememblock_regionto
memblock_typeandmemblock_propertytomemblock_regionQuoted 9 lines · Benjamin Herrenschmidt
Quoted 7 lines · tip-bot for Benjamin Herrenschmidt
Commit-ID: e3239ff92a17976ac5d26fa0fe40ef3a9daf2523 Gitweb: http://git.kernel.org/tip/e3239ff92a17976ac5d26fa0fe40ef3a9daf2523 Author: Benjamin Herrenschmidt <[email protected]> AuthorDate: Wed, 4 Aug 2010 14:06:41 +1000 Committer: Benjamin Herrenschmidt <[email protected]> CommitDate: Wed, 4 Aug 2010 14:21:49 +1000Quoted 5 lines
Quoted 1 line
memblock: Rename
memblock_regiontomemblock_typeandmemblock_propertytomemblock_regionHe, I was just about to rebase them :-)
Do you still need me to do that ?
Btw., because this is an older base, before we can push this to linux-next i suspect we'll need fixes for those architectures that did a memblock conversion in this cycle?
Thanks,
Quoted 7 lines
Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 microblaze, memblock: fix compiling
From: Michal Simek <[email protected]>
CC arch/microblaze/mm/init.oarch/microblaze/mm/init.c: In function 'mm_cmdline_setup':arch/microblaze/mm/init.c:236: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c: In function 'mmu_init':arch/microblaze/mm/init.c:279: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c:284: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c:285: error: 'struct memblock_type' has no member named 'region' arch/microblaze/mm/init.c:286: error: 'struct memblock_type' has no member named 'region' make[1]: *** [arch/microblaze/mm/init.o] Error 1
make: *** [arch/microblaze/mm] Error 2
with this fix and microblaze can boot
arch/microblaze/mm/init.c +5 -5
@@ -228,7 +228,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }
@@ -271,14 +271,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not used */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 powerpc, memblock: fix will memblock reference
for wii?
arch/powerpc/platforms/embedded6xx/wii.c +1 -1
@@ -65,7 +65,7 @@ static int __init page_aligned(unsignedvoid __init wii_memory_fixups (void ) { -struct memblock_region *p = memblock.memory.region; +struct memblock_region *p = memblock.memory.regions;/* * This is part of a workaround to allow the use of two
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
[tip:core/memblock] powerpc, memblock: Fix memblock API change fallout
Commit-ID: 0d63b32c4c6692f7df7b87be3a71353948a3ab18 Gitweb: http://git.kernel.org/tip/0d63b32c4c6692f7df7b87be3a71353948a3ab18 Author: Yinghai Lu <[email protected]> AuthorDate: Sat, 11 Sep 2010 00:08:42 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sat, 11 Sep 2010 09:26:43 +0200
powerpc, memblock: Fix memblock API change fallout
Fix memblock API change fallout in the WII code.
LKML-Reference: <[email protected]>
--- arch/powerpc/platforms/embedded6xx/wii.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/powerpc/platforms/embedded6xx/wii.c +1 -1
@@ -65,7 +65,7 @@ static int __init page_aligned(unsigned long x)void __init wii_memory_fixups (void ) { -struct memblock_region *p = memblock.memory.region; +struct memblock_region *p = memblock.memory.regions;/* * This is part of a workaround to allow the use of two
[tip:core/memblock] powerpc, memblock: Fix memblock API change fallout
In reply to Yinghai LuCommit-ID: 823108a056c52a83c32ca199a57566a36fad4d19 Gitweb: http://git.kernel.org/tip/823108a056c52a83c32ca199a57566a36fad4d19 Author: Yinghai Lu <[email protected]> AuthorDate: Sat, 11 Sep 2010 00:08:42 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sat, 11 Sep 2010 10:30:28 +0200
powerpc, memblock: Fix memblock API change fallout
Fix memblock API change fallout in the WII code.
LKML-Reference: <[email protected]>
--- arch/powerpc/platforms/embedded6xx/wii.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/powerpc/platforms/embedded6xx/wii.c +1 -1
@@ -65,7 +65,7 @@ static int __init page_aligned(unsigned long x)void __init wii_memory_fixups (void ) { -struct memblock_region *p = memblock.memory.region; +struct memblock_region *p = memblock.memory.regions;/* * This is part of a workaround to allow the use of two
[tip:core/memblock] memblock, microblaze: Fix memblock API change fallout
In reply to Yinghai LuCommit-ID: 78cf195c41a69521f4b3e3fd8b8bd4ecbfcdac85 Gitweb: http://git.kernel.org/tip/78cf195c41a69521f4b3e3fd8b8bd4ecbfcdac85 Author: Yinghai Lu <[email protected]> AuthorDate: Sat, 11 Sep 2010 00:07:06 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sat, 11 Sep 2010 09:26:43 +0200
memblock, microblaze: Fix memblock API change fallout
Michal Simek reported this build failure:
CC arch/microblaze/mm/init.o
arch/microblaze/mm/init.c: In function 'mm_cmdline_setup':
arch/microblaze/mm/init.c:236: error: 'struct memblock_type' has no member named 'region'
...
Adopt Microblaze to the memblock API changes.
LKML-Reference: <[email protected]>
--- arch/microblaze/mm/init.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
arch/microblaze/mm/init.c +5 -5
@@ -228,7 +228,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }
@@ -271,14 +271,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not used */
tip-bot for Michal Simek
maintainer[tip:core/memblock] memblock, microblaze: Fix memblock API change fallout
In reply to Yinghai LuCommit-ID: da5ab11cdfdf496448e0e9cdbbc2dfe207a96c94 Gitweb: http://git.kernel.org/tip/da5ab11cdfdf496448e0e9cdbbc2dfe207a96c94 Author: Michal Simek <[email protected]> AuthorDate: Sat, 11 Sep 2010 00:07:06 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sat, 11 Sep 2010 10:30:28 +0200
memblock, microblaze: Fix memblock API change fallout
Adopt Microblaze to the memblock API changes, to fix this build failure:
CC arch/microblaze/mm/init.o
arch/microblaze/mm/init.c: In function 'mm_cmdline_setup':
arch/microblaze/mm/init.c:236: error: 'struct memblock_type' has no member named 'region'
...
LKML-Reference: <[email protected]>
--- arch/microblaze/mm/init.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
arch/microblaze/mm/init.c +5 -5
@@ -228,7 +228,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }
@@ -271,14 +271,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not used */
Re: [PATCH 08/43] memblock/microblaze: Use new accessors
In reply to Benjamin HerrenschmidtQuoted 7 lines · Benjamin Herrenschmidt
Quoted 2 lines
Yep, i asked benh to have a look (see the mail below) but got no response, as i assumed it had all been taken care of.
Sorry, I must have been confused... I had pushed out a git branch a while back with those updates and the ARM bits, at least I think I did :-) I might have FAILed there. I'll check next week, I'm about to board on a plane right now.
Note, i applied the build error fixes from Yinghai. Please double-check things once you have the time.
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 08/43] memblock/microblaze: Use new accessors
In reply to Michal SimekQuoted 13 lines · Michal Simek
Quoted 12 lines · Benjamin Herrenschmidt
Quoted 10 lines · Michal Simek
Quoted 2 lines · Benjamin Herrenschmidt
CC Michal Simek <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>This patch remove bug which I reported but there is another place which needs to be changed.
I am not sure if my patch is correct but at least point you on places which is causing compilation errors.
I tested your memblock branch with this fix and microblaze can boot.
Quoted 7 lines
Quoted 4 lines
Ok, that's missing in my initial rename patch. I'll fix it up. Thanks.
Cheers,
Ben.I don't know why but this unfixed old patch is in linux-next today. Not sure which tree contains it.
I'm pretty sure I had all that fixed up including the ARM stuff. I wonder if Ingo picked my latest stuff (or maybe I failed to push it out).
I'm still travelling, I'll be back next week at which point I can have a look.
Cheers,
Ben.
Quoted 109 lines
Thanks,
MichalQuoted 104 lines
Quoted 102 lines
CC
arch/microblaze/mm/init.oarch/microblaze/mm/init.c: In function 'mm_cmdline_setup':arch/microblaze/mm/init.c:236: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c: In function 'mmu_init':arch/microblaze/mm/init.c:279: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:284: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:285: error: 'structmemblock_type' has no member named 'region'arch/microblaze/mm/init.c:286: error: 'structmemblock_type' has no member named 'region'
make[1]: *** [arch/microblaze/mm/init.o] Error 1
make: *** [arch/microblaze/mm] Error 2arch/microblaze/mm/init.c +5
-5@@ -233,7 +233,7 @@ static void mm_cmdline_setup(void)if (maxmem && memory_size > maxmem) { memory_size = maxmem; memory_end = memory_start + memory_size; - memblock.memory.region[0 ].size = memory_size; + memblock.memory.regions[0 ].size = memory_size; } } }@@ -276,14 +276,14 @@ asmlinkage void __init mmu_init(void)machine_restart (NULL ); } -if ((u32 ) memblock.memory.region[0 ].size <0x1000000 ) { +if ((u32 ) memblock.memory.regions[0 ].size <0x1000000 ) {printk (KERN_EMERG "Memory must be greater than 16MB\n" );machine_restart (NULL ); }/* Find main memory where the kernel is */ - memory_start = (u32 ) memblock.memory.region[0 ].base; - memory_end = (u32 ) memblock.memory.region[0 ].base + - (u32 ) memblock.memory.region[0 ].size; + memory_start = (u32 ) memblock.memory.regions[0 ].base; + memory_end = (u32 ) memblock.memory.regions[0 ].base + + (u32 ) memblock.memory.regions[0 ].size; memory_size = memory_end - memory_start;mm_cmdline_setup ();/* FIXME parse args from command line - not used */
Quoted 47 lines
--- arch/microblaze/mm/init.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-)arch/microblaze/mm/init.c +9
-11@@ -70,16 +70,16 @@ static void __init paging_init(void)void __init setup_memory (void ) { -int i;unsigned long map_size; +struct memblock_region *reg; +#ifndef CONFIG_MMU u32 kernel_align_start, kernel_align_size;/* Find main memory where is the kernel */ -for (i =0 ; i < memblock.memory.cnt; i++) { - memory_start = (u32 ) memblock.memory.regions[i].base; - memory_end = (u32 ) memblock.memory.regions[i].base - + (u32 ) memblock.memory.region[i].size; +for_each_memblock (memory, reg) { + memory_start = (u32 )reg->base; + memory_end = (u32 ) reg->base + reg->size;if ((memory_start <= (u32 )_text) && ((u32 )_text <= memory_end)) { memory_size = memory_end - memory_start;@@ -147,12 +147,10 @@ void __init setup_memory(void)free_bootmem (memory_start, memory_size);/* reserve allocate blocks */ -for (i =0 ; i < memblock.reserved.cnt; i++) { -pr_debug ("reserved %d - 0x%08x-0x%08x\n" , i, - (u32 ) memblock.reserved.region[i].base, - (u32 )memblock_size_bytes (&memblock.reserved, i)); -reserve_bootmem (memblock.reserved.region[i].base, -memblock_size_bytes (&memblock.reserved, i) -1 ,BOOTMEM_DEFAULT ); +for_each_memblock (reserved, reg) { +pr_debug ("reserved - 0x%08x-0x%08x\n" , + (u32 ) reg->base, (u32 ) reg->size); +reserve_bootmem (reg->base, reg->size,BOOTMEM_DEFAULT ); }#ifdef CONFIG_MMU init_bootmem_done =1 ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 9/43 memblock/sh: Use new accessors
In reply to Benjamin Herrenschmidt--- arch/sh/mm/init.c | 17 +++++++++-------- 1 files changed, 9 insertions(+), 8 deletions(-)
arch/sh/mm/init.c +9 -8
@@ -200,7 +200,6 @@ static void __init bootmem_init_one_node(unsigned int nid)unsigned long total_pages, paddr;unsigned long end_pfn;struct pglist_data *p; -int i; p =NODE_DATA (nid);
@@ -226,11 +225,12 @@ static void __init bootmem_init_one_node(unsigned int nid)* reservations in other nodes. */ if (nid ==0 ) { +struct memblock_region *reg; +/* Reserve the sections we're already using. */ -for (i =0 ; i < memblock.reserved.cnt; i++) -reserve_bootmem (memblock.reserved.region[i].base, -memblock_size_bytes (&memblock.reserved, i), -BOOTMEM_DEFAULT ); +for_each_memblock (reserved, reg) { +reserve_bootmem (reg->base, reg->size,BOOTMEM_DEFAULT ); + } }sparse_memory_present_with_active_regions (nid);
@@ -238,13 +238,14 @@ static void __init bootmem_init_one_node(unsigned int nid)static void __init do_init_bootmem (void ) { +struct memblock_region *reg;int i;/* Add active regions with valid PFNs. */ -for (i =0 ; i < memblock.memory.cnt; i++) { +for_each_memblock (memory, reg) {unsigned long start_pfn, end_pfn; - start_pfn = memblock.memory.region[i].base >>PAGE_SHIFT ; - end_pfn = start_pfn +memblock_size_pages (&memblock.memory, i); + start_pfn =memblock_region_base_pfn (reg); + end_pfn =memblock_region_end_pfn (reg);__add_active_range (0 , start_pfn, end_pfn); }
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 10/43 memblock/sparc: Use new accessors
In reply to Benjamin Herrenschmidt--- arch/sparc/mm/init_64.c | 30 ++++++++++++------------------ 1 files changed, 12 insertions(+), 18 deletions(-)
arch/sparc/mm/init_64.c +12 -18
@@ -972,13 +972,13 @@ int of_node_to_nid(struct device_node *dp)static void __init add_node_ranges (void ) { -int i; +struct memblock_region *reg; -for (i =0 ; i < memblock.memory.cnt; i++) { -unsigned long size =memblock_size_bytes (&memblock.memory, i); +for_each_memblock (memory, reg) { +unsigned long size = reg->size;unsigned long start, end; - start = memblock.memory.regions[i].base; + start = reg->base; end = start + size;while (start < end) {unsigned long this_end;
@@ -1281,7 +1281,7 @@ static void __init bootmem_init_nonnuma(void) {unsigned long top_of_ram =memblock_end_of_DRAM ();unsigned long total_ram =memblock_phys_mem_size (); -unsigned int i; +struct memblock_region *reg;numadbg ("bootmem_init_nonnuma()\n" );
@@ -1292,15 +1292,14 @@ static void __init bootmem_init_nonnuma(void)init_node_masks_nonnuma (); -for (i =0 ; i < memblock.memory.cnt; i++) { -unsigned long size =memblock_size_bytes (&memblock.memory, i); +for_each_memblock (memory, reg) {unsigned long start_pfn, end_pfn; -if (!size) +if (!reg->size)continue ; - start_pfn = memblock.memory.regions[i].base >>PAGE_SHIFT ; - end_pfn = start_pfn +memblock_size_pages (&memblock.memory, i); + start_pfn =memblock_region_base_pfn (reg); + end_pfn =memblock_region_end_pfn (reg);add_active_range (0 , start_pfn, end_pfn); }
@@ -1334,17 +1333,12 @@ static void __init reserve_range_in_node(int nid, unsigned long start,static void __init trim_reserved_in_node (int nid) { -int i; +struct memblock_region *reg;numadbg (" trim_reserved_in_node(%d)\n" , nid); -for (i =0 ; i < memblock.reserved.cnt; i++) { -unsigned long start = memblock.reserved.regions[i].base; -unsigned long size =memblock_size_bytes (&memblock.reserved, i); -unsigned long end = start + size; - -reserve_range_in_node (nid, start, end); - } +for_each_memblock (reserved, reg) +reserve_range_in_node (nid, reg->base, reg->base + reg->size); }static void __init bootmem_init_one_node (int nid)
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 11/43 memblock/powerpc: Use new accessors
In reply to Benjamin Herrenschmidt--- arch/powerpc/mm/hash_utils_64.c | 8 ++-- arch/powerpc/mm/mem.c | 92 ++++++++++++++------------------------- arch/powerpc/mm/numa.c | 17 ++++--- 3 files changed, 46 insertions(+), 71 deletions(-)
arch/powerpc/mm/hash_utils_64.c +4 -4
@@ -588,7 +588,7 @@ static void __init htab_initialize(void)unsigned long pteg_count;unsigned long prot;unsigned long base =0 , size =0 , limit; -int i; +struct memblock_region *reg;DBG (" -> htab_initialize()\n" );
@@ -659,9 +659,9 @@ static void __init htab_initialize(void)*/ /* create bolted the linear mapping in the hash table */ -for (i=0 ; i < memblock.memory.cnt; i++) { - base = (unsigned long )__va (memblock.memory.regions[i].base); - size = memblock.memory.region[i].size; +for_each_memblock (memory, reg) { + base = (unsigned long )__va (reg->base); + size = reg->size;DBG ("creating mapping for region: %lx..%lx (prot: %lx)\n" , base, size, prot);
arch/powerpc/mm/mem.c +33 -59
144 lines not on this page · raw message
arch/powerpc/mm/numa.c +9 -8
@@ -746,16 +746,17 @@ static void __init setup_nonnuma(void)unsigned long top_of_ram =memblock_end_of_DRAM ();unsigned long total_ram =memblock_phys_mem_size ();unsigned long start_pfn, end_pfn; -unsigned int i, nid =0 ; +unsigned int nid =0 ; +struct memblock_region *reg;printk (KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n" , top_of_ram, total_ram);printk (KERN_DEBUG "Memory hole size: %ldMB\n" , (top_of_ram - total_ram) >>20 ); -for (i =0 ; i < memblock.memory.cnt; ++i) { - start_pfn = memblock.memory.region[i].base >>PAGE_SHIFT ; - end_pfn = start_pfn +memblock_size_pages (&memblock.memory, i); +for_each_memblock (memory, reg) { + start_pfn =memblock_region_base_pfn (reg); + end_pfn =memblock_region_end_pfn (reg);fake_numa_create_new_node (end_pfn, &nid);add_active_range (nid, start_pfn, end_pfn);
@@ -891,11 +892,11 @@ static struct notifier_block __cpuinitdata ppc64_numa_nb = {static void mark_reserved_regions_for_nid (int nid) {struct pglist_data *node =NODE_DATA (nid); -int i; +struct memblock_region *reg; -for (i =0 ; i < memblock.reserved.cnt; i++) { -unsigned long physbase = memblock.reserved.region[i].base; -unsigned long size = memblock.reserved.region[i].size; +for_each_memblock (reserved, reg) { +unsigned long physbase = reg->base; +unsigned long size = reg->size;unsigned long start_pfn = physbase >>PAGE_SHIFT ;unsigned long end_pfn =PFN_UP (physbase + size);struct node_active_region node_ar;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 12/43 memblock/arm: Use new accessors
In reply to Benjamin Herrenschmidt--- arch/arm/mm/init.c | 21 ++++++++++++--------- 1 files changed, 12 insertions(+), 9 deletions(-)
arch/arm/mm/init.c +12 -9
@@ -150,6 +150,7 @@ static void __init find_limits(struct meminfo *mi,static void __init arm_bootmem_init (struct meminfo *mi,unsigned long start_pfn,unsigned long end_pfn) { +struct memblock_region *reg;unsigned int boot_pages;phys_addr_t bitmap;pg_data_t *pgdat;
@@ -180,13 +181,13 @@ static void __init arm_bootmem_init(struct meminfo *mi,/* * Reserve the memblock reserved regions in bootmem. */ -for (i =0 ; i < memblock.reserved.cnt; i++) { -phys_addr_t start =memblock_start_pfn (&memblock.reserved, i); -if (start >= start_pfn && -memblock_end_pfn (&memblock.reserved, i) <= end_pfn) +for_each_memblock (reserved, reg) { +phys_addr_t start =memblock_region_base_pfn (reg); +phys_addr_t end =memblock_region_end_pfn (reg); +if (start >= start_pfn && end <= end_pfn)reserve_bootmem_node (pgdat,__pfn_to_phys (start), -memblock_size_bytes (&memblock.reserved, i), -BOOTMEM_DEFAULT ); + (end - start) <<PAGE_SHIFT , +BOOTMEM_DEFAULT ); } }
@@ -247,10 +248,12 @@ static void arm_memory_present(void)#else static void arm_memory_present (void ) { +struct memblock_region *reg;int i; -for (i =0 ; i < memblock.memory.cnt; i++) -memory_present (0 ,memblock_start_pfn (&memblock.memory, i), -memblock_end_pfn (&memblock.memory, i)); + +for_each_memblock (memory, reg) { +memory_present (0 ,memblock_region_base_pfn (reg), +memblock_region_end_pfn (reg)); }#endif
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 12/43] memblock/arm: Use new accessors
Quoted 2 lines · Benjamin Herrenschmidt
CC Russell King <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 13/43 memblock: Remove obsolete accessors
In reply to Benjamin Herrenschmidt--- include/linux/memblock.h | 23 ----------------------- 1 files changed, 0 insertions(+), 23 deletions(-)
include/linux/memblock.h +0 -23
@@ -64,29 +64,6 @@ extern int memblock_find(struct memblock_region *res);extern void memblock_dump_all (void ); -/* Obsolete accessors */ -static inline u64 -memblock_size_bytes (struct memblock_type *type,unsigned long region_nr) -{ -return type->regions[region_nr].size; -} -static inline u64 -memblock_size_pages (struct memblock_type *type,unsigned long region_nr) -{ -return memblock_size_bytes (type, region_nr) >>PAGE_SHIFT ; -} -static inline u64 -memblock_start_pfn (struct memblock_type *type,unsigned long region_nr) -{ -return type->regions[region_nr].base >>PAGE_SHIFT ; -} -static inline u64 -memblock_end_pfn (struct memblock_type *type,unsigned long region_nr) -{ -return memblock_start_pfn (type, region_nr) + -memblock_size_pages (type, region_nr); -} -/* * pfn conversion functions *
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 14/43 memblock: Remove memblock_find()
In reply to Benjamin HerrenschmidtNobody uses it anymore. It's semantics were ... weird
--- include/linux/memblock.h | 1 - mm/memblock.c | 32 -------------------------------- 2 files changed, 0 insertions(+), 33 deletions(-)
include/linux/memblock.h +0 -1
@@ -60,7 +60,6 @@ extern int memblock_is_memory(u64 addr);extern int memblock_is_region_memory (u64 base,u64 size);extern int __init memblock_is_reserved (u64 addr);extern int memblock_is_region_reserved (u64 base,u64 size); -extern int memblock_find (struct memblock_region *res);extern void memblock_dump_all (void );
mm/memblock.c +0 -32
@@ -531,35 +531,3 @@ int memblock_is_region_reserved(u64 base, u64 size)return memblock_overlaps_region (&memblock.reserved, base, size) >=0 ; } -/* -* Given a <base, len>, find which memory regions belong to this range. -* Adjust the request and return a contiguous chunk. -*/ -int memblock_find (struct memblock_region *res) -{ -int i; -u64 rstart, rend; - - rstart = res->base; - rend = rstart + res->size -1 ; - -for (i =0 ; i < memblock.memory.cnt; i++) { -u64 start = memblock.memory.regions[i].base; -u64 end = start + memblock.memory.regions[i].size -1 ; - -if (start > rend) -return -1 ; - -if ((end >= rstart) && (start < rend)) { -/* adjust the request */ -if (rstart < start) - rstart = start; -if (rend > end) - rend = end; - res->base = rstart; - res->size = rend - rstart +1 ; -return 0 ; - } - } -return -1 ; -}
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 15/43 memblock: Remove nid_range argument, arch provides memblock_nid_range() instead
In reply to Benjamin Herrenschmidt--- arch/sparc/mm/init_64.c | 16 ++++++---------- include/linux/memblock.h | 7 +++++-- mm/memblock.c | 13 ++++++++----- 3 files changed, 19 insertions(+), 17 deletions(-)
arch/sparc/mm/init_64.c +6 -10
@@ -785,8 +785,7 @@ static int find_node(unsigned long addr)return -1 ; } -static unsigned long long nid_range (unsigned long long start, -unsigned long long end,int *nid) +u64 memblock_nid_range (u64 start,u64 end,int *nid) { *nid =find_node (start); start +=PAGE_SIZE ;
@@ -804,8 +803,7 @@ static unsigned long long nid_range(unsigned long long start, return start; }#else -static unsigned long long nid_range (unsigned long long start, -unsigned long long end,int *nid) +u64 memblock_nid_range (u64 start,u64 end,int *nid) { *nid =0 ;return end;
@@ -822,8 +820,7 @@ static void __init allocate_node_data(int nid)struct pglist_data *p;#ifdef CONFIG_NEED_MULTIPLE_NODES - paddr =memblock_alloc_nid (sizeof (struct pglist_data ), -SMP_CACHE_BYTES , nid, nid_range); + paddr =memblock_alloc_nid (sizeof (struct pglist_data ),SMP_CACHE_BYTES , nid);if (!paddr) {prom_printf ("Cannot allocate pglist_data for nid[%d]\n" , nid);prom_halt ();
@@ -843,8 +840,7 @@ static void __init allocate_node_data(int nid)if (p->node_spanned_pages) { num_pages =bootmem_bootmap_pages (p->node_spanned_pages); - paddr =memblock_alloc_nid (num_pages <<PAGE_SHIFT ,PAGE_SIZE , nid, - nid_range); + paddr =memblock_alloc_nid (num_pages <<PAGE_SHIFT ,PAGE_SIZE , nid);if (!paddr) {prom_printf ("Cannot allocate bootmap for nid[%d]\n" , nid);
@@ -984,7 +980,7 @@ static void __init add_node_ranges(void)unsigned long this_end;int nid; - this_end =nid_range (start, end, &nid); + this_end =memblock_nid_range (start, end, &nid); numadbg("Adding active range nid[%d] " "start[%lx] end[%lx]\n",
@@ -1317,7 +1313,7 @@ static void __init reserve_range_in_node(int nid, unsigned long start,unsigned long this_end;int n; - this_end =nid_range (start, end, &n); + this_end =memblock_nid_range (start, end, &n);if (n == nid) {numadbg (" MATCH reserving range [%lx:%lx]\n" , start, this_end);
include/linux/memblock.h +5 -2
@@ -46,8 +46,7 @@ extern long memblock_add(u64 base, u64 size);extern long memblock_remove (u64 base,u64 size);extern long __init memblock_free (u64 base,u64 size);extern long __init memblock_reserve (u64 base,u64 size); -extern u64 __init memblock_alloc_nid (u64 size,u64 align,int nid, -u64 (*nid_range)(u64 ,u64 ,int *)); +extern u64 __init memblock_alloc_nid (u64 size,u64 align,int nid);extern u64 __init memblock_alloc (u64 size,u64 align);extern u64 __init memblock_alloc_base (u64 size,u64 ,u64 max_addr);
@@ -63,6 +62,10 @@ extern int memblock_is_region_reserved(u64 base, u64 size);extern void memblock_dump_all (void ); +/* Provided by the architecture */ +extern u64 memblock_nid_range (u64 start,u64 end,int *nid); + +/* * pfn conversion functions *
mm/memblock.c +8 -5
@@ -319,7 +319,6 @@ static u64 __init memblock_alloc_nid_unreserved(u64 start, u64 end, }static u64 __init memblock_alloc_nid_region (struct memblock_region *mp, -u64 (*nid_range)(u64 ,u64 ,int *),u64 size,u64 align,int nid) {u64 start, end;
@@ -332,7 +331,7 @@ static u64 __init memblock_alloc_nid_region(struct memblock_region *mp,u64 this_end;int this_nid; - this_end =nid_range (start, end, &this_nid); + this_end =memblock_nid_range (start, end, &this_nid);if (this_nid == nid) {u64 ret =memblock_alloc_nid_unreserved (start, this_end, size, align);
@@ -345,8 +344,7 @@ static u64 __init memblock_alloc_nid_region(struct memblock_region *mp,return ~(u64 )0 ; } -u64 __init memblock_alloc_nid (u64 size,u64 align,int nid, -u64 (*nid_range)(u64 start,u64 end,int *nid)) +u64 __init memblock_alloc_nid (u64 size,u64 align,int nid) {struct memblock_type *mem = &memblock.memory;int i;
@@ -357,7 +355,6 @@ u64 __init memblock_alloc_nid(u64 size, u64 align, int nid,for (i =0 ; i < mem->cnt; i++) {u64 ret =memblock_alloc_nid_region (&mem->regions[i], - nid_range, size, align, nid);if (ret != ~(u64 )0 )return ret;
@@ -531,3 +528,9 @@ int memblock_is_region_reserved(u64 base, u64 size)return memblock_overlaps_region (&memblock.reserved, base, size) >=0 ; } +u64 __weak memblock_nid_range (u64 start,u64 end,int *nid) +{ + *nid =0 ; + +return end; +}
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 16/43 memblock: Factor the lowest level alloc function
In reply to Benjamin Herrenschmidt--- mm/memblock.c | 59 ++++++++++++++++++++++++++------------------------------ 1 files changed, 27 insertions(+), 32 deletions(-)
mm/memblock.c +27 -32
@@ -294,8 +294,8 @@ static u64 memblock_align_up(u64 addr, u64 size)return (addr + (size -1 )) & ~(size -1 ); } -static u64 __init memblock_alloc_nid_unreserved (u64 start,u64 end, -u64 size,u64 align) +static u64 __init memblock_alloc_region (u64 start,u64 end, +u64 size,u64 align) {u64 base, res_base;long j;
@@ -318,6 +318,13 @@ static u64 __init memblock_alloc_nid_unreserved(u64 start, u64 end,return ~(u64 )0 ; } +u64 __weak __init memblock_nid_range (u64 start,u64 end,int *nid) +{ + *nid =0 ; + +return end; +} +static u64 __init memblock_alloc_nid_region (struct memblock_region *mp,u64 size,u64 align,int nid) {
@@ -333,8 +340,7 @@ static u64 __init memblock_alloc_nid_region(struct memblock_region *mp, this_end =memblock_nid_range (start, end, &this_nid);if (this_nid == nid) { -u64 ret =memblock_alloc_nid_unreserved (start, this_end, - size, align); +u64 ret =memblock_alloc_region (start, this_end, size, align);if (ret != ~(u64 )0 )return ret; }
@@ -351,6 +357,10 @@ u64 __init memblock_alloc_nid(u64 size, u64 align, int nid)BUG_ON (0 == size); +/* We do a bottom-up search for a region with the right +* nid since that's easier considering how memblock_nid_range() +* works +*/ size =memblock_align_up (size, align);for (i =0 ; i < mem->cnt; i++) {
@@ -383,7 +393,7 @@ u64 __init memblock_alloc_base(u64 size, u64 align, u64 max_addr)u64 __init __memblock_alloc_base (u64 size,u64 align,u64 max_addr) { -long i, j; +long i;u64 base =0 ;u64 res_base;
@@ -396,33 +406,24 @@ u64 __init __memblock_alloc_base(u64 size, u64 align, u64 max_addr)if (max_addr ==MEMBLOCK_ALLOC_ANYWHERE ) max_addr =MEMBLOCK_REAL_LIMIT ; +/* Pump up max_addr */ +if (max_addr ==MEMBLOCK_ALLOC_ANYWHERE ) + max_addr = ~(u64 )0 ; + +/* We do a top-down search, this tends to limit memory +* fragmentation by keeping early boot allocs near the +* top of memory +*/ for (i = memblock.memory.cnt -1 ; i >=0 ; i--) {u64 memblockbase = memblock.memory.regions[i].base;u64 memblocksize = memblock.memory.regions[i].size;if (memblocksize < size)continue ; -if (max_addr ==MEMBLOCK_ALLOC_ANYWHERE ) - base =memblock_align_down (memblockbase + memblocksize - size, align); -else if (memblockbase < max_addr) { - base =min (memblockbase + memblocksize, max_addr); - base =memblock_align_down (base - size, align); - }else -continue ; - -while (base && memblockbase <= base) { - j =memblock_overlaps_region (&memblock.reserved, base, size); -if (j <0 ) { -/* this area isn't reserved, take it */ -if (memblock_add_region (&memblock.reserved, base, size) <0 ) -return 0 ; -return base; - } - res_base = memblock.reserved.regions[j].base; -if (res_base < size) -break ; - base =memblock_align_down (res_base - size, align); - } + base =min (memblockbase + memblocksize, max_addr); + res_base =memblock_alloc_region (memblockbase, base, size, align); +if (res_base != ~(u64 )0 ) +return res_base; }return 0 ; }
@@ -528,9 +529,3 @@ int memblock_is_region_reserved(u64 base, u64 size)return memblock_overlaps_region (&memblock.reserved, base, size) >=0 ; } -u64 __weak memblock_nid_range (u64 start,u64 end,int *nid) -{ - *nid =0 ; - -return end; -}
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 17/43 memblock: Expose MEMBLOCK_ALLOC_ANYWHERE
In reply to Benjamin Herrenschmidt--- arch/powerpc/mm/hash_utils_64.c | 2 +- include/linux/memblock.h | 1 + mm/memblock.c | 2 -- 3 files changed, 2 insertions(+), 3 deletions(-)
arch/powerpc/mm/hash_utils_64.c +1 -1
@@ -625,7 +625,7 @@ static void __init htab_initialize(void)if (machine_is (cell)) limit =0x80000000 ;else - limit =0 ; + limit =MEMBLOCK_ALLOC_ANYWHERE ; table =memblock_alloc_base (htab_size_bytes, htab_size_bytes, limit);
include/linux/memblock.h +1 -0
@@ -50,6 +50,7 @@ extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid);extern u64 __init memblock_alloc (u64 size,u64 align);extern u64 __init memblock_alloc_base (u64 size,u64 ,u64 max_addr); +#define MEMBLOCK_ALLOC_ANYWHERE 0extern u64 __init __memblock_alloc_base (u64 size,u64 align,u64 max_addr);extern u64 __init memblock_phys_mem_size (void );
mm/memblock.c +0 -2
@@ -15,8 +15,6 @@#include <linux/bitops.h> #include <linux/memblock.h> -#define MEMBLOCK_ALLOC_ANYWHERE 0 -struct memblock memblock;static int memblock_debug;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 18/43 memblock: Introduce default allocation limit and use it to replace explicit ones
In reply to Benjamin HerrenschmidtThis 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.
--- arch/microblaze/include/asm/memblock.h | 3 --- arch/powerpc/include/asm/memblock.h | 7 ------- arch/powerpc/kernel/prom.c | 20 +++++++++++++++++++- arch/powerpc/kernel/setup_32.c | 2 +- arch/powerpc/mm/40x_mmu.c | 5 +++-- arch/powerpc/mm/fsl_booke_mmu.c | 3 ++- arch/powerpc/mm/hash_utils_64.c | 3 ++- arch/powerpc/mm/init_32.c | 29 +++++++---------------------- arch/powerpc/mm/ppc_mmu_32.c | 3 +-- arch/powerpc/mm/tlb_nohash.c | 2 ++ arch/sh/include/asm/memblock.h | 2 -- arch/sparc/include/asm/memblock.h | 2 -- include/linux/memblock.h | 16 +++++++++++++++- mm/memblock.c | 19 +++++++++++-------- 14 files changed, 63 insertions(+), 53 deletions(-)
arch/microblaze/include/asm/memblock.h +0 -3
@@ -9,9 +9,6 @@#ifndef _ASM_MICROBLAZE_MEMBLOCK_H#define _ASM_MICROBLAZE_MEMBLOCK_H -/* MEMBLOCK limit is OFF */ -#define MEMBLOCK_REAL_LIMIT 0xFFFFFFFF -#endif /* _ASM_MICROBLAZE_MEMBLOCK_H */
arch/powerpc/include/asm/memblock.h +0 -7
@@ -5,11 +5,4 @@ #define MEMBLOCK_DBG(fmt...) udbg_printf(fmt) -#ifdef CONFIG_PPC32 -extern phys_addr_t lowmem_end_addr; -#define MEMBLOCK_REAL_LIMIT lowmem_end_addr -#else -#define MEMBLOCK_REAL_LIMIT 0 -#endif -#endif /* _ASM_POWERPC_MEMBLOCK_H */
arch/powerpc/kernel/prom.c +19 -1
@@ -98,7 +98,7 @@ static void __init move_device_tree(void)if ((memory_limit && (start + size) > memory_limit) ||overlaps_crashkernel (start, size)) { - p =__va (memblock_alloc_base (size,PAGE_SIZE , memblock.rmo_size)); + p =__va (memblock_alloc (size,PAGE_SIZE ));memcpy (p, initial_boot_params, size); initial_boot_params = (struct boot_param_header *)p;DBG ("Moved device tree to 0x%p\n" , p);
@@ -655,6 +655,21 @@ static void __init phyp_dump_reserve_mem(void)static inline void __init phyp_dump_reserve_mem (void ) {}#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */ +static void set_boot_memory_limit (void ) +{ +#ifdef CONFIG_PPC32 +/* 601 can only access 16MB at the moment */ +if (PVR_VER (mfspr (SPRN_PVR )) ==1 ) +memblock_set_current_limit (0x01000000 ); +/* 8xx can only access 8MB at the moment */ +else if (PVR_VER (mfspr (SPRN_PVR )) ==0x50 ) +memblock_set_current_limit (0x00800000 ); +else +memblock_set_current_limit (0x10000000 ); +#else +memblock_set_current_limit (memblock.rmo_size); +#endif +}void __init early_init_devtree (void *params) {
@@ -683,6 +698,7 @@ void __init early_init_devtree(void *params)/* Scan memory nodes and rebuild MEMBLOCKs */ memblock_init (); +of_scan_flat_dt (early_init_dt_scan_root,NULL );of_scan_flat_dt (early_init_dt_scan_memory_ppc,NULL );
@@ -718,6 +734,8 @@ void __init early_init_devtree(void *params)DBG ("Phys. mem: %llx\n" ,memblock_phys_mem_size ()); +set_boot_memory_limit (); +/* We may need to relocate the flat tree, do it now. * FIXME .. and the initrd too? */ move_device_tree ();
arch/powerpc/kernel/setup_32.c +1 -1
@@ -246,7 +246,7 @@ static void __init irqstack_early_init(void)unsigned int i;/* interrupt stacks must be in lowmem, we get that for free on ppc32 -* as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ +* as the memblock is limited to lowmem by default */ for_each_possible_cpu (i) { softirq_ctx[i] = (struct thread_info *)__va (memblock_alloc (THREAD_SIZE ,THREAD_SIZE ));
arch/powerpc/mm/40x_mmu.c +3 -2
@@ -35,6 +35,7 @@#include <linux/init.h> #include <linux/delay.h> #include <linux/highmem.h> +#include <linux/memblock.h> #include <asm/pgalloc.h> #include <asm/prom.h>
@@ -47,6 +48,7 @@#include <asm/bootx.h> #include <asm/machdep.h> #include <asm/setup.h> +#include "mmu_decl.h" extern int __map_without_ltlbs;
@@ -139,8 +141,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top)* coverage with normal-sized pages (or other reasons) do not * attempt to allocate outside the allowed range. */ - - __initial_memory_limit_addr = memstart_addr + mapped; +memblock_set_current_limit (memstart_addr + mapped);return mapped; }
arch/powerpc/mm/fsl_booke_mmu.c +2 -1
@@ -40,6 +40,7 @@#include <linux/init.h> #include <linux/delay.h> #include <linux/highmem.h> +#include <linux/memblock.h> #include <asm/pgalloc.h> #include <asm/prom.h>
@@ -212,5 +213,5 @@ void __init adjust_total_lowmem(void)pr_cont ("%lu Mb, residual: %dMb\n" ,tlbcam_sz (tlbcam_index -1 ) >>20 , (unsigned int )((total_lowmem - __max_low_memory) >>20 )); - __initial_memory_limit_addr = memstart_addr + __max_low_memory; +memblock_set_current_limit (memstart_addr + __max_low_memory); }
arch/powerpc/mm/hash_utils_64.c +2 -1
@@ -696,7 +696,8 @@ static void __init htab_initialize(void)#endif /* CONFIG_U3_DART */ BUG_ON (htab_bolt_mapping (base, base + size,__pa (base), prot, mmu_linear_psize, mmu_kernel_ssize)); - } + } +memblock_set_current_limit (MEMBLOCK_ALLOC_ANYWHERE );/* * If we have a memory_limit and we've allocated TCEs then we need to
arch/powerpc/mm/init_32.c +7 -22
@@ -92,12 +92,6 @@ int __allow_ioremap_reserved;unsigned long __max_low_memory =MAX_LOW_MEM ;/* -* address of the limit of what is accessible with initial MMU setup - -* 256MB usually, but only 16MB on 601. -*/ -phys_addr_t __initial_memory_limit_addr = (phys_addr_t )0x10000000 ; - -/* * Check for command-line options that affect what MMU_init will do. */ void MMU_setup (void )
@@ -126,13 +120,6 @@ void __init MMU_init(void)if (ppc_md.progress) ppc_md.progress ("MMU:enter" ,0x111 ); -/* 601 can only access 16MB at the moment */ -if (PVR_VER (mfspr (SPRN_PVR )) ==1 ) - __initial_memory_limit_addr =0x01000000 ; -/* 8xx can only access 8MB at the moment */ -if (PVR_VER (mfspr (SPRN_PVR )) ==0x50 ) - __initial_memory_limit_addr =0x00800000 ; -/* parse args from command line */ MMU_setup ();
@@ -190,20 +177,18 @@ void __init MMU_init(void)#ifdef CONFIG_BOOTX_TEXT btext_unmap ();#endif + +/* Shortly after that, the entire linear mapping will be available */ +memblock_set_current_limit (lowmem_end_addr); }/* This is only called until mem_init is done. */ void __init *early_get_page (void ) { -void *p; - -if (init_bootmem_done) { - p =alloc_bootmem_pages (PAGE_SIZE ); - }else { - p =__va (memblock_alloc_base (PAGE_SIZE ,PAGE_SIZE , - __initial_memory_limit_addr)); - } -return p; +if (init_bootmem_done) +return alloc_bootmem_pages (PAGE_SIZE ); +else +return __va (memblock_alloc (PAGE_SIZE ,PAGE_SIZE )); }/* Free up now-unused memory */
arch/powerpc/mm/ppc_mmu_32.c +1 -2
@@ -223,8 +223,7 @@ void __init MMU_init_hw(void)* Find some memory for the hash table. */ if ( ppc_md.progress ) ppc_md.progress ("hash:find piece" ,0x322 ); - Hash =__va (memblock_alloc_base (Hash_size, Hash_size, - __initial_memory_limit_addr)); + Hash =__va (memblock_alloc (Hash_size, Hash_size));cacheable_memzero (Hash, Hash_size); _SDR1 =__pa (Hash) |SDR1_LOW_BITS ;
arch/powerpc/mm/tlb_nohash.c +2 -0
@@ -432,6 +432,8 @@ static void __early_init_mmu(int boot_cpu)* the MMU configuration */ mb (); + +memblock_set_current_limit (linear_map_top); }void __init early_init_mmu (void )
arch/sh/include/asm/memblock.h +0 -2
@@ -1,6 +1,4 @@#ifndef __ASM_SH_MEMBLOCK_H#define __ASM_SH_MEMBLOCK_H -#define MEMBLOCK_REAL_LIMIT 0 -#endif /* __ASM_SH_MEMBLOCK_H */
arch/sparc/include/asm/memblock.h +0 -2
@@ -5,6 +5,4 @@ #define MEMBLOCK_DBG(fmt...) prom_printf(fmt) -#define MEMBLOCK_REAL_LIMIT 0 -#endif /* !(_SPARC64_MEMBLOCK_H) */
include/linux/memblock.h +15 -1
@@ -34,6 +34,7 @@ struct memblock_type {struct memblock {unsigned long debug;u64 rmo_size; +u64 current_limit;struct memblock_type memory;struct memblock_type reserved; };
@@ -46,11 +47,16 @@ extern long memblock_add(u64 base, u64 size);extern long memblock_remove (u64 base,u64 size);extern long __init memblock_free (u64 base,u64 size);extern long __init memblock_reserve (u64 base,u64 size); +extern u64 __init memblock_alloc_nid (u64 size,u64 align,int nid);extern u64 __init memblock_alloc (u64 size,u64 align); + +/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ +#define MEMBLOCK_ALLOC_ANYWHERE (~(u64)0) +#define MEMBLOCK_ALLOC_ACCESSIBLE 0 +extern u64 __init memblock_alloc_base (u64 size,u64 ,u64 max_addr); -#define MEMBLOCK_ALLOC_ANYWHERE 0extern u64 __init __memblock_alloc_base (u64 size,u64 align,u64 max_addr);extern u64 __init memblock_phys_mem_size (void );
@@ -66,6 +72,14 @@ extern void memblock_dump_all(void);/* Provided by the architecture */ extern u64 memblock_nid_range (u64 start,u64 end,int *nid); +/** +* memblock_set_current_limit - Set the current allocation limit to allow +* limiting allocations to what is currently +* accessible during boot +* @limit: New limit value (physical address) +*/ +extern void memblock_set_current_limit (u64 limit); +/* * pfn conversion functions
mm/memblock.c +11 -8
@@ -115,6 +115,8 @@ void __init memblock_init(void) memblock.reserved.regions[0 ].base =0 ; memblock.reserved.regions[0 ].size =0 ; memblock.reserved.cnt =1 ; + + memblock.current_limit =MEMBLOCK_ALLOC_ANYWHERE ; }void __init memblock_analyze (void )
@@ -373,7 +375,7 @@ u64 __init memblock_alloc_nid(u64 size, u64 align, int nid)u64 __init memblock_alloc (u64 size,u64 align) { -return memblock_alloc_base (size, align,MEMBLOCK_ALLOC_ANYWHERE ); +return memblock_alloc_base (size, align,MEMBLOCK_ALLOC_ACCESSIBLE ); }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) size =memblock_align_up (size, align); -/* On some platforms, make sure we allocate lowmem */ -/* Note that MEMBLOCK_REAL_LIMIT may be MEMBLOCK_ALLOC_ANYWHERE */ -if (max_addr ==MEMBLOCK_ALLOC_ANYWHERE ) - max_addr =MEMBLOCK_REAL_LIMIT ; -/* Pump up max_addr */ -if (max_addr ==MEMBLOCK_ALLOC_ANYWHERE ) - max_addr = ~(u64 )0 ; +if (max_addr ==MEMBLOCK_ALLOC_ACCESSIBLE ) + max_addr = memblock.current_limit;/* We do a top-down search, this tends to limit memory * fragmentation by keeping early boot allocs near the
@@ -527,3 +524,9 @@ int memblock_is_region_reserved(u64 base, u64 size)return memblock_overlaps_region (&memblock.reserved, base, size) >=0 ; } + +void __init memblock_set_current_limit (u64 limit) +{ + memblock.current_limit = limit; +} +
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 19/43 memblock: Remove rmo_size, burry it in arch/powerpc where it belongs
In reply to Benjamin HerrenschmidtThe RMA (RMO is a misnomer) is a concept specific to ppc64 (in fact server ppc64 though I hijack it on embedded ppc64 for similar purposes) and represents the area of memory that can be accessed in real mode (aka with MMU off), or on embedded, from the exception vectors (which is bolted in the TLB) which pretty much boils down to the same thing.
We take that out of the generic MEMBLOCK data structure and move it into arch/powerpc where it belongs, renaming it to "RMA" while at it.
--- arch/powerpc/include/asm/mmu.h | 12 ++++++++++++ arch/powerpc/kernel/head_40x.S | 6 +----- arch/powerpc/kernel/paca.c | 2 +- arch/powerpc/kernel/prom.c | 29 ++++++++--------------------- arch/powerpc/kernel/rtas.c | 2 +- arch/powerpc/kernel/setup_64.c | 2 +- arch/powerpc/mm/40x_mmu.c | 14 +++++++++++++- arch/powerpc/mm/44x_mmu.c | 14 ++++++++++++++ arch/powerpc/mm/fsl_booke_mmu.c | 9 +++++++++ arch/powerpc/mm/hash_utils_64.c | 22 +++++++++++++++++++++- arch/powerpc/mm/init_32.c | 14 ++++++++++++++ arch/powerpc/mm/init_64.c | 1 + arch/powerpc/mm/ppc_mmu_32.c | 15 +++++++++++++++ arch/powerpc/mm/tlb_nohash.c | 14 ++++++++++++++ include/linux/memblock.h | 1 - mm/memblock.c | 8 -------- 16 files changed, 125 insertions(+), 40 deletions(-)
arch/powerpc/include/asm/mmu.h +12 -0
@@ -2,6 +2,8 @@#define _ASM_POWERPC_MMU_H_#ifdef __KERNEL__ +#include <linux/types.h> +#include <asm/asm-compat.h> #include <asm/feature-fixups.h>
@@ -82,6 +84,16 @@ extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;extern void early_init_mmu (void );extern void early_init_mmu_secondary (void ); +extern void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size); + +#ifdef CONFIG_PPC64 +/* This is our real memory area size on ppc64 server, on embedded, we +* make it match the size our of bolted TLB area +*/ +extern u64 ppc64_rma_size; +#endif /* CONFIG_PPC64 */ +#endif /* !__ASSEMBLY__ */ /* The kernel use the constants below to index in the page sizes array.
arch/powerpc/kernel/head_40x.S +1 -5
@@ -923,11 +923,7 @@ initial_mmu: mtspr SPRN_PID,r0 sync - /* Configure and load two entries into TLB slots 62 and 63. - * In case we are pinning TLBs, these are reserved in by the - * other TLB functions. If not reserving, then it doesn't - * matter where they are loaded. - */ + /* Configure and load one entry into TLB slots 63 */ clrrwi r4,r4,10 /* Mask off the real page number */ ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
arch/powerpc/kernel/paca.c +1 -1
@@ -117,7 +117,7 @@ void __init allocate_pacas(void)* the first segment. On iSeries they must be within the area mapped * by the HV, which is HvPagesToMap * HVPAGESIZE bytes. */ - limit =min (0x10000000ULL , memblock.rmo_size); + limit =min (0x10000000ULL , ppc64_rma_size);if (firmware_has_feature (FW_FEATURE_ISERIES )) limit =min (limit, HvPagesToMap *HVPAGESIZE );
arch/powerpc/kernel/prom.c +8 -21
@@ -66,6 +66,7 @@int __initdata iommu_is_off;int __initdata iommu_force_on;unsigned long tce_alloc_start, tce_alloc_end; +u64 ppc64_rma_size;#endif static int __init early_parse_mem (char *p)
@@ -492,7 +493,7 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node,void __init early_init_dt_add_memory_arch (u64 base,u64 size) { -#if defined(CONFIG_PPC64 ) +#ifdef CONFIG_PPC64 if (iommu_is_off) {if (base >=0x80000000ul )return ;
@@ -501,9 +502,13 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) }#endif -memblock_add (base, size); - +/* First MEMBLOCK added, do some special initializations */ +if (memstart_addr == ~(phys_addr_t )0 ) +setup_initial_memory_limit (base, size); memstart_addr =min ((u64 )memstart_addr, base); + +/* Add the chunk to the MEMBLOCK list */ +memblock_add (base, size); }u64 __init early_init_dt_alloc_memory_arch (u64 size,u64 align)
@@ -655,22 +660,6 @@ static void __init phyp_dump_reserve_mem(void)static inline void __init phyp_dump_reserve_mem (void ) {}#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */ -static void set_boot_memory_limit (void ) -{ -#ifdef CONFIG_PPC32 -/* 601 can only access 16MB at the moment */ -if (PVR_VER (mfspr (SPRN_PVR )) ==1 ) -memblock_set_current_limit (0x01000000 ); -/* 8xx can only access 8MB at the moment */ -else if (PVR_VER (mfspr (SPRN_PVR )) ==0x50 ) -memblock_set_current_limit (0x00800000 ); -else -memblock_set_current_limit (0x10000000 ); -#else -memblock_set_current_limit (memblock.rmo_size); -#endif -} -void __init early_init_devtree (void *params) {phys_addr_t limit;
@@ -734,8 +723,6 @@ void __init early_init_devtree(void *params)DBG ("Phys. mem: %llx\n" ,memblock_phys_mem_size ()); -set_boot_memory_limit (); -/* We may need to relocate the flat tree, do it now. * FIXME .. and the initrd too? */ move_device_tree ();
arch/powerpc/kernel/rtas.c +1 -1
@@ -934,7 +934,7 @@ void __init rtas_initialize(void)*/ #ifdef CONFIG_PPC64 if (machine_is (pseries) &&firmware_has_feature (FW_FEATURE_LPAR )) { - rtas_region =min (memblock.rmo_size,RTAS_INSTANTIATE_MAX ); + rtas_region =min (ppc64_rma_size,RTAS_INSTANTIATE_MAX ); ibm_suspend_me_token =rtas_token ("ibm,suspend-me" ); }#endif
arch/powerpc/kernel/setup_64.c +1 -1
@@ -487,7 +487,7 @@ static void __init emergency_stack_init(void)* bringup, we need to get at them in real mode. This means they * must also be within the RMO region. */ - limit =min (slb0_limit (), memblock.rmo_size); + limit =min (slb0_limit (), ppc64_rma_size);for_each_possible_cpu (i) {unsigned long sp;
arch/powerpc/mm/40x_mmu.c +13 -1
@@ -141,7 +141,19 @@ unsigned long __init mmu_mapin_ram(unsigned long top)* coverage with normal-sized pages (or other reasons) do not * attempt to allocate outside the allowed range. */ -memblock_set_current_limit (memstart_addr + mapped); +memblock_set_current_limit (mapped);return mapped; } + +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +/* We don't currently support the first MEMBLOCK not mapping 0 +* physical on those processors +*/ +BUG_ON (first_memblock_base !=0 ); + +/* 40x can only access 16MB at the moment (see head_40x.S) */ +memblock_set_current_limit (min_t (u64, first_memblock_size,0x00800000 )); +}
arch/powerpc/mm/44x_mmu.c +14 -0
@@ -24,6 +24,8 @@*/ #include <linux/init.h> +#include <linux/memblock.h> +#include <asm/mmu.h> #include <asm/system.h> #include <asm/page.h>
@@ -213,6 +215,18 @@ unsigned long __init mmu_mapin_ram(unsigned long top)return total_lowmem; } +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +/* We don't currently support the first MEMBLOCK not mapping 0 +* physical on those processors +*/ +BUG_ON (first_memblock_base !=0 ); + +/* 44x has a 256M TLB entry pinned at boot */ +memblock_set_current_limit (min_t (u64, first_memblock_size,PPC_PIN_SIZE )); +} +#ifdef CONFIG_SMP void __cpuinit mmu_init_secondary (int cpu) {
arch/powerpc/mm/fsl_booke_mmu.c +9 -0
@@ -215,3 +215,12 @@ void __init adjust_total_lowmem(void)memblock_set_current_limit (memstart_addr + __max_low_memory); } + +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +phys_addr_t limit = first_memblock_base + first_memblock_size; + +/* 64M mapped initially according to head_fsl_booke.S */ +memblock_set_current_limit (min_t (u64, limit,0x04000000 )); +}
arch/powerpc/mm/hash_utils_64.c +21 -1
@@ -649,7 +649,7 @@ static void __init htab_initialize(void)#ifdef CONFIG_DEBUG_PAGEALLOC linear_map_hash_count =memblock_end_of_DRAM () >>PAGE_SHIFT ; linear_map_hash_slots =__va (memblock_alloc_base (linear_map_hash_count, -1 , memblock.rmo_size)); +1 , ppc64_rma_size));memset (linear_map_hash_slots,0 , linear_map_hash_count);#endif /* CONFIG_DEBUG_PAGEALLOC */
@@ -1248,3 +1248,23 @@ void kernel_map_pages(struct page *page, int numpages, int enable) local_irq_restore(flags); }#endif /* CONFIG_DEBUG_PAGEALLOC */ + +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +/* We don't currently support the first MEMBLOCK not mapping 0 +* physical on those processors +*/ +BUG_ON (first_memblock_base !=0 ); + +/* On LPAR systems, the first entry is our RMA region, +* non-LPAR 64-bit hash MMU systems don't have a limitation +* on real mode access, but using the first entry works well +* enough. We also clamp it to 1G to avoid some funky things +* such as RTAS bugs etc... +*/ + ppc64_rma_size =min_t (u64, first_memblock_size,0x40000000 ); + +/* Finally limit subsequent allocations */ +memblock_set_current_limit (ppc64_rma_size); +}
arch/powerpc/mm/init_32.c +14 -0
@@ -237,3 +237,17 @@ void free_initrd_mem(unsigned long start, unsigned long end) }#endif + +#ifdef CONFIG_8xx/* No 8xx specific .c file to put that in ... */ +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +/* We don't currently support the first MEMBLOCK not mapping 0 +* physical on those processors +*/ +BUG_ON (first_memblock_base !=0 ); + +/* 8xx can only access 8MB at the moment */ +memblock_set_current_limit (min_t (u64, first_memblock_size,0x00800000 )); +} +#endif /* CONFIG_8xx */
arch/powerpc/mm/init_64.c +1 -0
@@ -328,3 +328,4 @@ int __meminit vmemmap_populate(struct page *start_page, return 0; }#endif /* CONFIG_SPARSEMEM_VMEMMAP */ +
arch/powerpc/mm/ppc_mmu_32.c +15 -0
@@ -271,3 +271,18 @@ void __init MMU_init_hw(void)if ( ppc_md.progress ) ppc_md.progress ("hash:done" ,0x205 ); } + +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +/* We don't currently support the first MEMBLOCK not mapping 0 +* physical on those processors +*/ +BUG_ON (first_memblock_base !=0 ); + +/* 601 can only access 16MB at the moment */ +if (PVR_VER (mfspr (SPRN_PVR )) ==1 ) +memblock_set_current_limit (min_t (u64, first_memblock_size,0x01000000 )); +else /* Anything else has 256M mapped */ +memblock_set_current_limit (min_t (u64, first_memblock_size,0x10000000 )); +}
arch/powerpc/mm/tlb_nohash.c +14 -0
@@ -446,4 +446,18 @@ void __cpuinit early_init_mmu_secondary(void) __early_init_mmu(0); } +void setup_initial_memory_limit (phys_addr_t first_memblock_base, +phys_addr_t first_memblock_size) +{ +/* On Embedded 64-bit, we adjust the RMA size to match +* the bolted TLB entry. We know for now that only 1G +* entries are supported though that may eventually +* change. We crop it to the size of the first MEMBLOCK to +* avoid going over total available memory just in case... +*/ + ppc64_rma_size =min_t (u64, first_memblock_size,0x40000000 ); + +/* Finally limit subsequent allocations */ +memblock_set_current_limit (ppc64_memblock_base + ppc64_rma_size); +}#endif /* CONFIG_PPC64 */
include/linux/memblock.h +0 -1
@@ -33,7 +33,6 @@ struct memblock_type {struct memblock {unsigned long debug; -u64 rmo_size;u64 current_limit;struct memblock_type memory;struct memblock_type reserved;
mm/memblock.c +0 -8
@@ -49,7 +49,6 @@ void memblock_dump_all(void)return ;pr_info ("MEMBLOCK configuration:\n" ); -pr_info (" rmo_size = 0x%llx\n" , (unsigned long long )memblock.rmo_size);pr_info (" memory.size = 0x%llx\n" , (unsigned long long )memblock.memory.size);memblock_dump (&memblock.memory,"memory" );
@@ -195,10 +194,6 @@ static long memblock_add_region(struct memblock_type *type, u64 base, u64 size)long memblock_add (u64 base,u64 size) { -/* On pSeries LPAR systems, the first MEMBLOCK is our RMO region. */ -if (base ==0 ) - memblock.rmo_size = size; -return memblock_add_region (&memblock.memory, base, size); }
@@ -459,9 +454,6 @@ void __init memblock_enforce_memory_limit(u64 memory_limit)break ; } -if (memblock.memory.regions[0 ].size < memblock.rmo_size) - memblock.rmo_size = memblock.memory.regions[0 ].size; - memory_limit =memblock_end_of_DRAM ();/* And truncate any reserves above the limit also. */
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 20/43 memblock: Change u64 to phys_addr_t
In reply to Benjamin HerrenschmidtLet's not waste space and cycles on archs that don't support >32-bit physical address space.
--- include/linux/memblock.h | 48 +++++++++--------- mm/memblock.c | 118 +++++++++++++++++++++++---------------------- 2 files changed, 84 insertions(+), 82 deletions(-)
include/linux/memblock.h +24 -24
@@ -21,19 +21,19 @@#define MAX_MEMBLOCK_REGIONS 128struct memblock_region { -u64 base; -u64 size; +phys_addr_t base; +phys_addr_t size; };struct memblock_type {unsigned long cnt; -u64 size; +phys_addr_t size;struct memblock_region regions[MAX_MEMBLOCK_REGIONS +1 ]; };struct memblock {unsigned long debug; -u64 current_limit; +phys_addr_t current_limit;struct memblock_type memory;struct memblock_type reserved; };
@@ -42,34 +42,34 @@ extern struct memblock memblock;extern void __init memblock_init (void );extern void __init memblock_analyze (void ); -extern long memblock_add (u64 base,u64 size); -extern long memblock_remove (u64 base,u64 size); -extern long __init memblock_free (u64 base,u64 size); -extern long __init memblock_reserve (u64 base,u64 size); +extern long memblock_add (phys_addr_t base,phys_addr_t size); +extern long memblock_remove (phys_addr_t base,phys_addr_t size); +extern long __init memblock_free (phys_addr_t base,phys_addr_t size); +extern long __init memblock_reserve (phys_addr_t base,phys_addr_t size); -extern u64 __init memblock_alloc_nid (u64 size,u64 align,int nid); -extern u64 __init memblock_alloc (u64 size,u64 align); +extern phys_addr_t __init memblock_alloc_nid (phys_addr_t size,phys_addr_t align,int nid); +extern phys_addr_t __init memblock_alloc (phys_addr_t size,phys_addr_t align);/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ -#define MEMBLOCK_ALLOC_ANYWHERE (~(u64)0) +#define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0)#define MEMBLOCK_ALLOC_ACCESSIBLE 0 -extern u64 __init memblock_alloc_base (u64 size, -u64 ,u64 max_addr); -extern u64 __init __memblock_alloc_base (u64 size, -u64 align,u64 max_addr); -extern u64 __init memblock_phys_mem_size (void ); -extern u64 memblock_end_of_DRAM (void ); -extern void __init memblock_enforce_memory_limit (u64 memory_limit); -extern int memblock_is_memory (u64 addr); -extern int memblock_is_region_memory (u64 base,u64 size); -extern int __init memblock_is_reserved (u64 addr); -extern int memblock_is_region_reserved (u64 base,u64 size); +extern phys_addr_t __init memblock_alloc_base (phys_addr_t size, +phys_addr_t ,phys_addr_t max_addr); +extern phys_addr_t __init __memblock_alloc_base (phys_addr_t size, +phys_addr_t align,phys_addr_t max_addr); +extern phys_addr_t __init memblock_phys_mem_size (void ); +extern phys_addr_t memblock_end_of_DRAM (void ); +extern void __init memblock_enforce_memory_limit (phys_addr_t memory_limit); +extern int memblock_is_memory (phys_addr_t addr); +extern int memblock_is_region_memory (phys_addr_t base,phys_addr_t size); +extern int __init memblock_is_reserved (phys_addr_t addr); +extern int memblock_is_region_reserved (phys_addr_t base,phys_addr_t size);extern void memblock_dump_all (void );/* Provided by the architecture */ -extern u64 memblock_nid_range (u64 start,u64 end,int *nid); +extern phys_addr_t memblock_nid_range (phys_addr_t start,phys_addr_t end,int *nid);/** * memblock_set_current_limit - Set the current allocation limit to allow
@@ -77,7 +77,7 @@ extern u64 memblock_nid_range(u64 start, u64 end, int *nid);* accessible during boot * @limit: New limit value (physical address) */ -extern void memblock_set_current_limit (u64 limit); +extern void memblock_set_current_limit (phys_addr_t limit);/*
mm/memblock.c +60 -58
322 lines not on this page · raw message
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 21/43 memblock: Remove unused memblock.debug struct member
In reply to Benjamin Herrenschmidt--- include/linux/memblock.h | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
include/linux/memblock.h +4 -3
@@ -32,7 +32,6 @@ struct memblock_type { };struct memblock { -unsigned long debug;phys_addr_t current_limit;struct memblock_type memory;struct memblock_type reserved;
@@ -55,9 +54,11 @@ extern phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align);#define MEMBLOCK_ALLOC_ACCESSIBLE 0extern phys_addr_t __init memblock_alloc_base (phys_addr_t size, -phys_addr_t ,phys_addr_t max_addr); +phys_addr_t align, +phys_addr_t max_addr);extern phys_addr_t __init __memblock_alloc_base (phys_addr_t size, -phys_addr_t align,phys_addr_t max_addr); +phys_addr_t align, +phys_addr_t max_addr);extern phys_addr_t __init memblock_phys_mem_size (void );extern phys_addr_t memblock_end_of_DRAM (void );extern void __init memblock_enforce_memory_limit (phys_addr_t memory_limit);
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 22/43 memblock: Remove memblock_type.size and add memblock.memory_size instead
In reply to Benjamin HerrenschmidtRight now, both the "memory" and "reserved" memblock_type structures have a "size" member. It represents the calculated memory size in the former case and is unused in the latter.
This moves it out to the main memblock structure instead
--- arch/powerpc/mm/mem.c | 2 +- include/linux/memblock.h | 2 +- mm/memblock.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-)
arch/powerpc/mm/mem.c +1 -1
@@ -301,7 +301,7 @@ void __init mem_init(void)swiotlb_init (1 );#endif - num_physpages = memblock.memory.size >>PAGE_SHIFT ; + num_physpages =memblock_phys_mem_size () >>PAGE_SHIFT ; high_memory = (void *)__va (max_low_pfn *PAGE_SIZE );#ifdef CONFIG_NEED_MULTIPLE_NODES
include/linux/memblock.h +1 -1
@@ -27,12 +27,12 @@ struct memblock_region {struct memblock_type {unsigned long cnt; -phys_addr_t size;struct memblock_region regions[MAX_MEMBLOCK_REGIONS +1 ]; };struct memblock {phys_addr_t current_limit; +phys_addr_t memory_size;/* Updated by memblock_analyze() */ struct memblock_type memory;struct memblock_type reserved; };
mm/memblock.c +4 -4
@@ -49,7 +49,7 @@ void memblock_dump_all(void)return ;pr_info ("MEMBLOCK configuration:\n" ); -pr_info (" memory.size = 0x%llx\n" , (unsigned long long )memblock.memory.size); +pr_info (" memory size = 0x%llx\n" , (unsigned long long )memblock.memory_size);memblock_dump (&memblock.memory,"memory" );memblock_dump (&memblock.reserved,"reserved" );
@@ -123,10 +123,10 @@ void __init memblock_analyze(void) {int i; - memblock.memory.size =0 ; + memblock.memory_size =0 ;for (i =0 ; i < memblock.memory.cnt; i++) - memblock.memory.size += memblock.memory.regions[i].size; + memblock.memory_size += memblock.memory.regions[i].size; }static long memblock_add_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size)
@@ -423,7 +423,7 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, ph/* You must call memblock_analyze() before this. */ phys_addr_t __init memblock_phys_mem_size (void ) { -return memblock.memory.size; +return memblock.memory_size; }phys_addr_t memblock_end_of_DRAM (void )
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 23/43 memblock: Move memblock arrays to static storage in memblock.c and make their size a variable
In reply to Benjamin HerrenschmidtThis is in preparation for having resizable arrays.
Note that we still allocate one more than needed, this is unchanged from the previous implementation.
--- include/linux/memblock.h | 7 ++++--- mm/memblock.c | 10 +++++++++- 2 files changed, 13 insertions(+), 4 deletions(-)
include/linux/memblock.h +4 -3
@@ -18,7 +18,7 @@#include <asm/memblock.h> -#define MAX_MEMBLOCK_REGIONS 128 +#define INIT_MEMBLOCK_REGIONS 128struct memblock_region {phys_addr_t base;
@@ -26,8 +26,9 @@ struct memblock_region { };struct memblock_type { -unsigned long cnt; -struct memblock_region regions[MAX_MEMBLOCK_REGIONS +1 ]; +unsigned long cnt;/* number of regions */ +unsigned long max;/* size of the allocated array */ +struct memblock_region *regions; };struct memblock {
mm/memblock.c +9 -1
@@ -18,6 +18,8 @@struct memblock memblock;static int memblock_debug; +static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS +1 ]; +static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS +1 ];static int __init early_memblock (char *p) {
@@ -104,6 +106,12 @@ static void memblock_coalesce_regions(struct memblock_type *type,void __init memblock_init (void ) { +/* Hookup the initial arrays */ + memblock.memory.regions = memblock_memory_init_regions; + memblock.memory.max =INIT_MEMBLOCK_REGIONS ; + memblock.reserved.regions = memblock_reserved_init_regions; + memblock.reserved.max =INIT_MEMBLOCK_REGIONS ; +/* Create a dummy zero size MEMBLOCK which will get coalesced away later. * This simplifies the memblock_add() code below... */
@@ -169,7 +177,7 @@ static long memblock_add_region(struct memblock_type *type, phys_addr_t base, phif (coalesced)return coalesced; -if (type->cnt >=MAX_MEMBLOCK_REGIONS ) +if (type->cnt >= type->max)return -1 ;/* Couldn't coalesce the MEMBLOCK, so add it to the sorted table. */
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 24/43 memblock: Add debug markers at the end of the array
In reply to Benjamin HerrenschmidtSince we allocate one more than needed, why not do a bit of sanity checking here to ensure we don't walk past the end of the array ?
--- mm/memblock.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
mm/memblock.c +11 -0
@@ -13,6 +13,7 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/bitops.h> +#include <linux/poison.h> #include <linux/memblock.h> struct memblock memblock;
@@ -112,6 +113,10 @@ void __init memblock_init(void) memblock.reserved.regions = memblock_reserved_init_regions; memblock.reserved.max =INIT_MEMBLOCK_REGIONS ; +/* Write a marker in the unused last array entry */ + memblock.memory.regions[INIT_MEMBLOCK_REGIONS ].base = (phys_addr_t )RED_INACTIVE ; + memblock.reserved.regions[INIT_MEMBLOCK_REGIONS ].base = (phys_addr_t )RED_INACTIVE ; +/* Create a dummy zero size MEMBLOCK which will get coalesced away later. * This simplifies the memblock_add() code below... */
@@ -131,6 +136,12 @@ void __init memblock_analyze(void) {int i; +/* Check marker in the unused last array entry */ +WARN_ON (memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS ].base + != (phys_addr_t )RED_INACTIVE ); +WARN_ON (memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS ].base + != (phys_addr_t )RED_INACTIVE ); + memblock.memory_size =0 ;for (i =0 ; i < memblock.memory.cnt; i++)
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 25/43 memblock: Make memblock_find_region() out of memblock_alloc_region()
In reply to Benjamin HerrenschmidtThis function will be used to locate a free area to put the new memblock arrays when attempting to resize them. memblock_alloc_region() is gone, the two callsites now call memblock_add_region().
---
v2. Fix membase_alloc_nid_region() conversion
--- mm/memblock.c | 20 +++++++++----------- 1 files changed, 9 insertions(+), 11 deletions(-)
mm/memblock.c +9 -11
@@ -309,8 +309,8 @@ static phys_addr_t memblock_align_up(phys_addr_t addr, phys_addr_t size)return (addr + (size -1 )) & ~(size -1 ); } -static phys_addr_t __init memblock_alloc_region (phys_addr_t start,phys_addr_t end, -phys_addr_t size,phys_addr_t align) +static phys_addr_t __init memblock_find_region (phys_addr_t start,phys_addr_t end, +phys_addr_t size,phys_addr_t align) {phys_addr_t base, res_base;long j;
@@ -318,12 +318,8 @@ static phys_addr_t __init memblock_alloc_region(phys_addr_t start, phys_addr_t e base =memblock_align_down ((end - size), align);while (start <= base) { j =memblock_overlaps_region (&memblock.reserved, base, size); -if (j <0 ) { -/* this area isn't reserved, take it */ -if (memblock_add_region (&memblock.reserved, base, size) <0 ) - base = ~(phys_addr_t )0 ; +if (j <0 )return base; - } res_base = memblock.reserved.regions[j].base;if (res_base < size)break ;
@@ -356,8 +352,9 @@ static phys_addr_t __init memblock_alloc_nid_region(struct memblock_region *mp, this_end =memblock_nid_range (start, end, &this_nid);if (this_nid == nid) { -phys_addr_t ret =memblock_alloc_region (start, this_end, size, align); -if (ret != ~(phys_addr_t )0 ) +phys_addr_t ret =memblock_find_region (start, this_end, size, align); +if (ret != ~(phys_addr_t )0 && +memblock_add_region (&memblock.reserved, ret, size) >=0 )return ret; } start = this_end;
@@ -432,8 +429,9 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, phif (memblocksize < size)continue ; base =min (memblockbase + memblocksize, max_addr); - res_base =memblock_alloc_region (memblockbase, base, size, align); -if (res_base != ~(phys_addr_t )0 ) + res_base =memblock_find_region (memblockbase, base, size, align); +if (res_base != ~(phys_addr_t )0 && +memblock_add_region (&memblock.reserved, res_base, size) >=0 )return res_base; }return 0 ;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 26/43 memblock: Define MEMBLOCK_ERROR internally instead of using ~(phys_addr_t)0
In reply to Benjamin Herrenschmidt--- mm/memblock.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-)
mm/memblock.c +7 -5
@@ -22,6 +22,8 @@ static int memblock_debug;static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS +1 ];static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS +1 ]; +#define MEMBLOCK_ERROR (~(phys_addr_t)0) +static int __init early_memblock (char *p) {if (p &&strstr (p,"debug" ))
@@ -326,7 +328,7 @@ static phys_addr_t __init memblock_find_region(phys_addr_t start, phys_addr_t en base =memblock_align_down (res_base - size, align); } -return ~(phys_addr_t )0 ; +return MEMBLOCK_ERROR ; }phys_addr_t __weak __init memblock_nid_range (phys_addr_t start,phys_addr_t end,int *nid)
@@ -353,14 +355,14 @@ static phys_addr_t __init memblock_alloc_nid_region(struct memblock_region *mp, this_end =memblock_nid_range (start, end, &this_nid);if (this_nid == nid) {phys_addr_t ret =memblock_find_region (start, this_end, size, align); -if (ret != ~(phys_addr_t )0 && +if (ret !=MEMBLOCK_ERROR &&memblock_add_region (&memblock.reserved, ret, size) >=0 )return ret; } start = this_end; } -return ~(phys_addr_t )0 ; +return MEMBLOCK_ERROR ; }phys_addr_t __init memblock_alloc_nid (phys_addr_t size,phys_addr_t align,int nid)
@@ -379,7 +381,7 @@ phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nfor (i =0 ; i < mem->cnt; i++) {phys_addr_t ret =memblock_alloc_nid_region (&mem->regions[i], size, align, nid); -if (ret != ~(phys_addr_t )0 ) +if (ret !=MEMBLOCK_ERROR )return ret; }
@@ -430,7 +432,7 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, phcontinue ; base =min (memblockbase + memblocksize, max_addr); res_base =memblock_find_region (memblockbase, base, size, align); -if (res_base != ~(phys_addr_t )0 && +if (res_base !=MEMBLOCK_ERROR &&memblock_add_region (&memblock.reserved, res_base, size) >=0 )return res_base; }
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 27/43 memblock: Move memblock_init() to the bottom of the file
In reply to Benjamin HerrenschmidtIt's a real PITA to have to search for it in the middle
--- mm/memblock.c | 54 +++++++++++++++++++++++++++--------------------------- 1 files changed, 27 insertions(+), 27 deletions(-)
mm/memblock.c +27 -27
@@ -107,33 +107,6 @@ static void memblock_coalesce_regions(struct memblock_type *type,memblock_remove_region (type, r2); } -void __init memblock_init (void ) -{ -/* Hookup the initial arrays */ - memblock.memory.regions = memblock_memory_init_regions; - memblock.memory.max =INIT_MEMBLOCK_REGIONS ; - memblock.reserved.regions = memblock_reserved_init_regions; - memblock.reserved.max =INIT_MEMBLOCK_REGIONS ; - -/* Write a marker in the unused last array entry */ - memblock.memory.regions[INIT_MEMBLOCK_REGIONS ].base = (phys_addr_t )RED_INACTIVE ; - memblock.reserved.regions[INIT_MEMBLOCK_REGIONS ].base = (phys_addr_t )RED_INACTIVE ; - -/* Create a dummy zero size MEMBLOCK which will get coalesced away later. -* This simplifies the memblock_add() code below... -*/ - memblock.memory.regions[0 ].base =0 ; - memblock.memory.regions[0 ].size =0 ; - memblock.memory.cnt =1 ; - -/* Ditto. */ - memblock.reserved.regions[0 ].base =0 ; - memblock.reserved.regions[0 ].size =0 ; - memblock.reserved.cnt =1 ; - - memblock.current_limit =MEMBLOCK_ALLOC_ANYWHERE ; -} -void __init memblock_analyze (void ) {int i;
@@ -543,3 +516,30 @@ void __init memblock_set_current_limit(phys_addr_t limit) memblock.current_limit = limit; } +void __init memblock_init (void ) +{ +/* Hookup the initial arrays */ + memblock.memory.regions = memblock_memory_init_regions; + memblock.memory.max =INIT_MEMBLOCK_REGIONS ; + memblock.reserved.regions = memblock_reserved_init_regions; + memblock.reserved.max =INIT_MEMBLOCK_REGIONS ; + +/* Write a marker in the unused last array entry */ + memblock.memory.regions[INIT_MEMBLOCK_REGIONS ].base = (phys_addr_t )RED_INACTIVE ; + memblock.reserved.regions[INIT_MEMBLOCK_REGIONS ].base = (phys_addr_t )RED_INACTIVE ; + +/* Create a dummy zero size MEMBLOCK which will get coalesced away later. +* This simplifies the memblock_add() code below... +*/ + memblock.memory.regions[0 ].base =0 ; + memblock.memory.regions[0 ].size =0 ; + memblock.memory.cnt =1 ; + +/* Ditto. */ + memblock.reserved.regions[0 ].base =0 ; + memblock.reserved.regions[0 ].size =0 ; + memblock.reserved.cnt =1 ; + + memblock.current_limit =MEMBLOCK_ALLOC_ANYWHERE ; +} +
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 28/43 memblock: split memblock_find_base() out of __memblock_alloc_base()
In reply to Benjamin HerrenschmidtThis will be used by the array resize code and might prove useful to some arch code as well at which point it can be made non-static.
Also add comment as to why aligning size is important
---
v2. Fix loss of size alignment
v3. Fix result code
--- mm/memblock.c | 58 +++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 38 insertions(+), 20 deletions(-)
mm/memblock.c +38 -20
@@ -345,12 +345,15 @@ phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nBUG_ON (0 == size); +/* We align the size to limit fragmentation. Without this, a lot of +* small allocs quickly eat up the whole reserve array on sparc +*/ + size =memblock_align_up (size, align); +/* We do a bottom-up search for a region with the right * nid since that's easier considering how memblock_nid_range() * works */ - size =memblock_align_up (size, align); -for (i =0 ; i < mem->cnt; i++) {phys_addr_t ret =memblock_alloc_nid_region (&mem->regions[i], size, align, nid);
@@ -366,20 +369,7 @@ phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align)return memblock_alloc_base (size, align,MEMBLOCK_ALLOC_ACCESSIBLE ); } -phys_addr_t __init memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) -{ -phys_addr_t alloc; - - alloc =__memblock_alloc_base (size, align, max_addr); - -if (alloc ==0 ) -panic ("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n" , - (unsigned long long ) size, (unsigned long long ) max_addr); - -return alloc; -} - -phys_addr_t __init __memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) +static phys_addr_t __init memblock_find_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) {long i;phys_addr_t base =0 ;
@@ -387,8 +377,6 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, phBUG_ON (0 == size); - size =memblock_align_up (size, align); -/* Pump up max_addr */ if (max_addr ==MEMBLOCK_ALLOC_ACCESSIBLE ) max_addr = memblock.current_limit;
@@ -405,13 +393,43 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, phcontinue ; base =min (memblockbase + memblocksize, max_addr); res_base =memblock_find_region (memblockbase, base, size, align); -if (res_base !=MEMBLOCK_ERROR && -memblock_add_region (&memblock.reserved, res_base, size) >=0 ) +if (res_base !=MEMBLOCK_ERROR )return res_base; } +return MEMBLOCK_ERROR ; +} + +phys_addr_t __init __memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) +{ +phys_addr_t found; + +/* We align the size to limit fragmentation. Without this, a lot of +* small allocs quickly eat up the whole reserve array on sparc +*/ + size =memblock_align_up (size, align); + + found =memblock_find_base (size, align, max_addr); +if (found !=MEMBLOCK_ERROR && +memblock_add_region (&memblock.reserved, found, size) >=0 ) +return found; +return 0 ; } +phys_addr_t __init memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) +{ +phys_addr_t alloc; + + alloc =__memblock_alloc_base (size, align, max_addr); + +if (alloc ==0 ) +panic ("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n" , + (unsigned long long ) size, (unsigned long long ) max_addr); + +return alloc; +} + +/* You must call memblock_analyze() before this. */ phys_addr_t __init memblock_phys_mem_size (void ) {
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 29/43 memblock: Move functions around into a more sensible order
In reply to Benjamin HerrenschmidtSome shuffling is needed for doing array resize so we may as well put some sense into the ordering of the functions in the whole memblock.c file. No code change. Added some comments.
--- mm/memblock.c | 301 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 159 insertions(+), 142 deletions(-)
mm/memblock.c +159 -142
@@ -24,40 +24,18 @@ static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIO#define MEMBLOCK_ERROR (~(phys_addr_t)0) -static int __init early_memblock (char *p) -{ -if (p &&strstr (p,"debug" )) - memblock_debug =1 ; -return 0 ; -} -early_param ("memblock" , early_memblock); +/* +* Address comparison utilities +*/ -static void memblock_dump (struct memblock_type *region,char *name) +static phys_addr_t memblock_align_down (phys_addr_t addr,phys_addr_t size) { -unsigned long long base, size; -int i; - -pr_info (" %s.cnt = 0x%lx\n" , name, region->cnt); - -for (i =0 ; i < region->cnt; i++) { - base = region->regions[i].base; - size = region->regions[i].size; - -pr_info (" %s[0x%x]\t0x%016llx - 0x%016llx, 0x%llx bytes\n" , - name, i, base, base + size -1 , size); - } +return addr & ~(size -1 ); } -void memblock_dump_all (void ) +static phys_addr_t memblock_align_up (phys_addr_t addr,phys_addr_t size) { -if (!memblock_debug) -return ; - -pr_info ("MEMBLOCK configuration:\n" ); -pr_info (" memory size = 0x%llx\n" , (unsigned long long )memblock.memory_size); - -memblock_dump (&memblock.memory,"memory" ); -memblock_dump (&memblock.reserved,"reserved" ); +return (addr + (size -1 )) & ~(size -1 ); } static unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1,
@@ -88,6 +66,77 @@ static long memblock_regions_adjacent(struct memblock_type *type,return memblock_addrs_adjacent (base1, size1, base2, size2); } +long memblock_overlaps_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size) +{ +unsigned long i; + +for (i =0 ; i < type->cnt; i++) { +phys_addr_t rgnbase = type->regions[i].base; +phys_addr_t rgnsize = type->regions[i].size; +if (memblock_addrs_overlap (base, size, rgnbase, rgnsize)) +break ; + } + +return (i < type->cnt) ? i :-1 ; +} + +/* +* Find, allocate, deallocate or reserve unreserved regions. All allocations +* are top-down. +*/ + +static phys_addr_t __init memblock_find_region (phys_addr_t start,phys_addr_t end, +phys_addr_t size,phys_addr_t align) +{ +phys_addr_t base, res_base; +long j; + + base =memblock_align_down ((end - size), align); +while (start <= base) { + j =memblock_overlaps_region (&memblock.reserved, base, size); +if (j <0 ) +return base; + res_base = memblock.reserved.regions[j].base; +if (res_base < size) +break ; + base =memblock_align_down (res_base - size, align); + } + +return MEMBLOCK_ERROR ; +} + +static phys_addr_t __init memblock_find_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) +{ +long i; +phys_addr_t base =0 ; +phys_addr_t res_base; + +BUG_ON (0 == size); + + size =memblock_align_up (size, align); + +/* Pump up max_addr */ +if (max_addr ==MEMBLOCK_ALLOC_ACCESSIBLE ) + max_addr = memblock.current_limit; + +/* We do a top-down search, this tends to limit memory +* fragmentation by keeping early boot allocs near the +* top of memory +*/ +for (i = memblock.memory.cnt -1 ; i >=0 ; i--) { +phys_addr_t memblockbase = memblock.memory.regions[i].base; +phys_addr_t memblocksize = memblock.memory.regions[i].size; + +if (memblocksize < size) +continue ; + base =min (memblockbase + memblocksize, max_addr); + res_base =memblock_find_region (memblockbase, base, size, align); +if (res_base !=MEMBLOCK_ERROR ) +return res_base; + } +return MEMBLOCK_ERROR ; +} +static void memblock_remove_region (struct memblock_type *type,unsigned long r) {unsigned long i;
@@ -107,22 +156,6 @@ static void memblock_coalesce_regions(struct memblock_type *type,memblock_remove_region (type, r2); } -void __init memblock_analyze (void ) -{ -int i; - -/* Check marker in the unused last array entry */ -WARN_ON (memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS ].base - != (phys_addr_t )RED_INACTIVE ); -WARN_ON (memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS ].base - != (phys_addr_t )RED_INACTIVE ); - - memblock.memory_size =0 ; - -for (i =0 ; i < memblock.memory.cnt; i++) - memblock.memory_size += memblock.memory.regions[i].size; -} -static long memblock_add_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size) {unsigned long coalesced =0 ;
@@ -260,49 +293,47 @@ long __init memblock_reserve(phys_addr_t base, phys_addr_t size)return memblock_add_region (_rgn, base, size); } -long memblock_overlaps_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size) +phys_addr_t __init __memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) { -unsigned long i; +phys_addr_t found; -for (i =0 ; i < type->cnt; i++) { -phys_addr_t rgnbase = type->regions[i].base; -phys_addr_t rgnsize = type->regions[i].size; -if (memblock_addrs_overlap (base, size, rgnbase, rgnsize)) -break ; - } +/* We align the size to limit fragmentation. Without this, a lot of +* small allocs quickly eat up the whole reserve array on sparc +*/ + size =memblock_align_up (size, align); -return (i < type->cnt) ? i :-1 ; -} + found =memblock_find_base (size, align, max_addr); +if (found !=MEMBLOCK_ERROR && +memblock_add_region (&memblock.reserved, found, size) >=0 ) +return found; -static phys_addr_t memblock_align_down (phys_addr_t addr,phys_addr_t size) -{ -return addr & ~(size -1 ); +return 0 ; } -static phys_addr_t memblock_align_up (phys_addr_t addr,phys_addr_t size) +phys_addr_t __init memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) { -return (addr + (size -1 )) & ~(size -1 ); +phys_addr_t alloc; + + alloc =__memblock_alloc_base (size, align, max_addr); + +if (alloc ==0 ) +panic ("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n" , + (unsigned long long ) size, (unsigned long long ) max_addr); + +return alloc; } -static phys_addr_t __init memblock_find_region (phys_addr_t start,phys_addr_t end, -phys_addr_t size,phys_addr_t align) +phys_addr_t __init memblock_alloc (phys_addr_t size,phys_addr_t align) { -phys_addr_t base, res_base; -long j; +return memblock_alloc_base (size, align,MEMBLOCK_ALLOC_ACCESSIBLE ); +} - base =memblock_align_down ((end - size), align); -while (start <= base) { - j =memblock_overlaps_region (&memblock.reserved, base, size); -if (j <0 ) -return base; - res_base = memblock.reserved.regions[j].base; -if (res_base < size) -break ; - base =memblock_align_down (res_base - size, align); - } -return MEMBLOCK_ERROR ; -} +/* +* Additional node-local allocators. Search for node memory is bottom up +* and walks memblock regions within that node bottom-up as well, but allocation +* within an memblock region is top-down. +*/ phys_addr_t __weak __init memblock_nid_range (phys_addr_t start,phys_addr_t end,int *nid) {
@@ -364,72 +395,6 @@ phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nreturn memblock_alloc (size, align); } -phys_addr_t __init memblock_alloc (phys_addr_t size,phys_addr_t align) -{ -return memblock_alloc_base (size, align,MEMBLOCK_ALLOC_ACCESSIBLE ); -} - -static phys_addr_t __init memblock_find_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) -{ -long i; -phys_addr_t base =0 ; -phys_addr_t res_base; - -BUG_ON (0 == size); - -/* Pump up max_addr */ -if (max_addr ==MEMBLOCK_ALLOC_ACCESSIBLE ) - max_addr = memblock.current_limit; - -/* We do a top-down search, this tends to limit memory -* fragmentation by keeping early boot allocs near the -* top of memory -*/ -for (i = memblock.memory.cnt -1 ; i >=0 ; i--) { -phys_addr_t memblockbase = memblock.memory.regions[i].base; -phys_addr_t memblocksize = memblock.memory.regions[i].size; - -if (memblocksize < size) -continue ; - base =min (memblockbase + memblocksize, max_addr); - res_base =memblock_find_region (memblockbase, base, size, align); -if (res_base !=MEMBLOCK_ERROR ) -return res_base; - } -return MEMBLOCK_ERROR ; -} - -phys_addr_t __init __memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) -{ -phys_addr_t found; - -/* We align the size to limit fragmentation. Without this, a lot of -* small allocs quickly eat up the whole reserve array on sparc -*/ - size =memblock_align_up (size, align); - - found =memblock_find_base (size, align, max_addr); -if (found !=MEMBLOCK_ERROR && -memblock_add_region (&memblock.reserved, found, size) >=0 ) -return found; - -return 0 ; -} - -phys_addr_t __init memblock_alloc_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) -{ -phys_addr_t alloc; - - alloc =__memblock_alloc_base (size, align, max_addr); - -if (alloc ==0 ) -panic ("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n" , - (unsigned long long ) size, (unsigned long long ) max_addr); - -return alloc; -} - -/* You must call memblock_analyze() before this. */ phys_addr_t __init memblock_phys_mem_size (void ) {
@@ -534,6 +499,50 @@ void __init memblock_set_current_limit(phys_addr_t limit) memblock.current_limit = limit; } +static void memblock_dump (struct memblock_type *region,char *name) +{ +unsigned long long base, size; +int i; + +pr_info (" %s.cnt = 0x%lx\n" , name, region->cnt); + +for (i =0 ; i < region->cnt; i++) { + base = region->regions[i].base; + size = region->regions[i].size; + +pr_info (" %s[0x%x]\t0x%016llx - 0x%016llx, 0x%llx bytes\n" , + name, i, base, base + size -1 , size); + } +} + +void memblock_dump_all (void ) +{ +if (!memblock_debug) +return ; + +pr_info ("MEMBLOCK configuration:\n" ); +pr_info (" memory size = 0x%llx\n" , (unsigned long long )memblock.memory_size); + +memblock_dump (&memblock.memory,"memory" ); +memblock_dump (&memblock.reserved,"reserved" ); +} + +void __init memblock_analyze (void ) +{ +int i; + +/* Check marker in the unused last array entry */ +WARN_ON (memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS ].base + != (phys_addr_t )RED_INACTIVE ); +WARN_ON (memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS ].base + != (phys_addr_t )RED_INACTIVE ); + + memblock.memory_size =0 ; + +for (i =0 ; i < memblock.memory.cnt; i++) + memblock.memory_size += memblock.memory.regions[i].size; +} +void __init memblock_init (void ) {/* Hookup the initial arrays */
@@ -561,3 +570,11 @@ void __init memblock_init(void) memblock.current_limit =MEMBLOCK_ALLOC_ANYWHERE ; } +static int __init early_memblock (char *p) +{ +if (p &&strstr (p,"debug" )) + memblock_debug =1 ; +return 0 ; +} +early_param ("memblock" , early_memblock); +
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 30/43 memblock: Add array resizing support
In reply to Benjamin HerrenschmidtWhen one of the array gets full, we resize it. After much thinking and a few iterations of that code, I went back to on-demand resizing using the (new) internal memblock_find_base() function, which is pretty much what Yinghai initially proposed, though there some differences in the details.
To work this relies on the default alloc limit being set sensibly by the architecture.
--- mm/memblock.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 102 insertions(+), 2 deletions(-)
mm/memblock.c +102 -2
@@ -11,6 +11,7 @@*/ #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/bitops.h> #include <linux/poison.h>
@@ -18,12 +19,23 @@struct memblock memblock; -static int memblock_debug; +static int memblock_debug, memblock_can_resize;static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS +1 ];static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS +1 ];#define MEMBLOCK_ERROR (~(phys_addr_t)0) +/* inline so we don't get a warning when pr_debug is compiled out */ +static inline const char *memblock_type_name (struct memblock_type *type) +{ +if (type == &memblock.memory) +return "memory" ; +else if (type == &memblock.reserved) +return "reserved" ; +else +return "unknown" ; +} +/* * Address comparison utilities */
@@ -156,6 +168,79 @@ static void memblock_coalesce_regions(struct memblock_type *type,memblock_remove_region (type, r2); } +/* Defined below but needed now */ +static long memblock_add_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size); + +static int memblock_double_array (struct memblock_type *type) +{ +struct memblock_region *new_array, *old_array; +phys_addr_t old_size, new_size, addr; +int use_slab =slab_is_available (); + +/* We don't allow resizing until we know about the reserved regions +* of memory that aren't suitable for allocation +*/ +if (!memblock_can_resize) +return -1 ; + +pr_debug ("memblock: %s array full, doubling..." ,memblock_type_name (type)); + +/* Calculate new doubled size */ + old_size = type->max *sizeof (struct memblock_region ); + new_size = old_size <<1 ; + +/* Try to find some space for it. +* +* WARNING: We assume that either slab_is_available() and we use it or +* we use MEMBLOCK for allocations. That means that this is unsafe to use +* when bootmem is currently active (unless bootmem itself is implemented +* on top of MEMBLOCK which isn't the case yet) +* +* This should however not be an issue for now, as we currently only +* call into MEMBLOCK while it's still active, or much later when slab is +* active for memory hotplug operations +*/ +if (use_slab) { + new_array =kmalloc (new_size,GFP_KERNEL ); + addr = new_array ==NULL ?MEMBLOCK_ERROR :__pa (new_array); + }else + addr =memblock_find_base (new_size,sizeof (phys_addr_t),MEMBLOCK_ALLOC_ACCESSIBLE ); +if (addr ==MEMBLOCK_ERROR ) { +pr_err ("memblock: Failed to double %s array from %ld to %ld entries !\n" , +memblock_type_name (type), type->max, type->max *2 ); +return -1 ; + } + new_array =__va (addr); + +/* Found space, we now need to move the array over before +* we add the reserved region since it may be our reserved +* array itself that is full. +*/ +memcpy (new_array, type->regions, old_size); +memset (new_array + type->max,0 , old_size); + old_array = type->regions; + type->regions = new_array; + type->max <<=1 ; + +/* If we use SLAB that's it, we are done */ +if (use_slab) +return 0 ; + +/* Add the new reserved region now. Should not fail ! */ +BUG_ON (memblock_add_region (&memblock.reserved, addr, new_size) <0 ); + +/* If the array wasn't our static init one, then free it. We only do +* that before SLAB is available as later on, we don't know whether +* to use kfree or free_bootmem_pages(). Shouldn't be a big deal +* anyways +*/ +if (old_array != memblock_memory_init_regions && + old_array != memblock_reserved_init_regions) +memblock_free (__pa (old_array), old_size); + +return 0 ; +} +static long memblock_add_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size) {unsigned long coalesced =0 ;
@@ -196,7 +281,11 @@ static long memblock_add_region(struct memblock_type *type, phys_addr_t base, phif (coalesced)return coalesced; -if (type->cnt >= type->max) + +/* If we are out of space, we fail. It's too late to resize the array +* but then this shouldn't have happened in the first place. +*/ +if (WARN_ON (type->cnt >= type->max))return -1 ;/* Couldn't coalesce the MEMBLOCK, so add it to the sorted table. */
@@ -217,6 +306,14 @@ static long memblock_add_region(struct memblock_type *type, phys_addr_t base, ph } type->cnt++; +/* The array is full ? Try to resize it. If that fails, we undo +* our allocation and return an error +*/ +if (type->cnt == type->max &&memblock_double_array (type)) { + type->cnt--; +return -1 ; + } +return 0 ; }
@@ -541,6 +638,9 @@ void __init memblock_analyze(void)for (i =0 ; i < memblock.memory.cnt; i++) memblock.memory_size += memblock.memory.regions[i].size; + +/* We allow resizing from there */ + memblock_can_resize =1 ; }void __init memblock_init (void )
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 31/43 memblock: Add arch function to control coalescing of memblock memory regions
In reply to Benjamin HerrenschmidtSome archs such as ARM want to avoid coalescing accross things such as the lowmem/highmem boundary or similar. This provides the option to control it via an arch callback for which a weak default is provided which always allows coalescing.
--- include/linux/memblock.h | 2 ++ mm/memblock.c | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletions(-)
include/linux/memblock.h +2 -0
@@ -72,6 +72,8 @@ extern void memblock_dump_all(void);/* Provided by the architecture */ extern phys_addr_t memblock_nid_range (phys_addr_t start,phys_addr_t end,int *nid); +extern int memblock_memory_can_coalesce (phys_addr_t addr1,phys_addr_t size1, +phys_addr_t addr2,phys_addr_t size2);/** * memblock_set_current_limit - Set the current allocation limit to allow
mm/memblock.c +18 -1
@@ -241,6 +241,12 @@ static int memblock_double_array(struct memblock_type *type)return 0 ; } +extern int __weak memblock_memory_can_coalesce (phys_addr_t addr1,phys_addr_t size1, +phys_addr_t addr2,phys_addr_t size2) +{ +return 1 ; +} +static long memblock_add_region (struct memblock_type *type,phys_addr_t base,phys_addr_t size) {unsigned long coalesced =0 ;
@@ -262,6 +268,10 @@ static long memblock_add_region(struct memblock_type *type, phys_addr_t base, phreturn 0 ; adjacent =memblock_addrs_adjacent (base, size, rgnbase, rgnsize); +/* Check if arch allows coalescing */ +if (adjacent !=0 && type == &memblock.memory && + !memblock_memory_can_coalesce (base, size, rgnbase, rgnsize)) +break ;if (adjacent >0 ) { type->regions[i].base -= size; type->regions[i].size += size;
@@ -274,7 +284,14 @@ static long memblock_add_region(struct memblock_type *type, phys_addr_t base, ph } } -if ((i < type->cnt -1 ) &&memblock_regions_adjacent (type, i, i+1 )) { +/* If we plugged a hole, we may want to also coalesce with the +* next region +*/ +if ((i < type->cnt -1 ) &&memblock_regions_adjacent (type, i, i+1 ) && + ((type != &memblock.memory ||memblock_memory_can_coalesce (type->regions[i].base, + type->regions[i].size, + type->regions[i+1 ].base, + type->regions[i+1 ].size)))) {memblock_coalesce_regions (type, i, i+1 ); coalesced++; }
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 32/43 memblock: Add "start" argument to memblock_find_base()
In reply to Benjamin HerrenschmidtTo constraint the search of a region between two boundaries, which will be used by the new NUMA aware allocator among others.
--- mm/memblock.c | 27 ++++++++++++++++----------- 1 files changed, 16 insertions(+), 11 deletions(-)
mm/memblock.c +16 -11
@@ -117,19 +117,18 @@ static phys_addr_t __init memblock_find_region(phys_addr_t start, phys_addr_t enreturn MEMBLOCK_ERROR ; } -static phys_addr_t __init memblock_find_base (phys_addr_t size,phys_addr_t align,phys_addr_t max_addr) +static phys_addr_t __init memblock_find_base (phys_addr_t size,phys_addr_t align, +phys_addr_t start,phys_addr_t end) {long i; -phys_addr_t base =0 ; -phys_addr_t res_base;BUG_ON (0 == size); size =memblock_align_up (size, align);/* Pump up max_addr */ -if (max_addr ==MEMBLOCK_ALLOC_ACCESSIBLE ) - max_addr = memblock.current_limit; +if (end ==MEMBLOCK_ALLOC_ACCESSIBLE ) + end = memblock.current_limit;/* We do a top-down search, this tends to limit memory * fragmentation by keeping early boot allocs near the
@@ -138,13 +137,19 @@ static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t alignfor (i = memblock.memory.cnt -1 ; i >=0 ; i--) {phys_addr_t memblockbase = memblock.memory.regions[i].base;phys_addr_t memblocksize = memblock.memory.regions[i].size; +phys_addr_t bottom, top, found;if (memblocksize < size)continue ; - base =min (memblockbase + memblocksize, max_addr); - res_base =memblock_find_region (memblockbase, base, size, align); -if (res_base !=MEMBLOCK_ERROR ) -return res_base; +if ((memblockbase + memblocksize) <= start) +break ; + bottom =max (memblockbase, start); + top =min (memblockbase + memblocksize, end); +if (bottom >= top) +continue ; + found =memblock_find_region (bottom, top, size, align); +if (found !=MEMBLOCK_ERROR ) +return found; }return MEMBLOCK_ERROR ; }
@@ -204,7 +209,7 @@ static int memblock_double_array(struct memblock_type *type) new_array =kmalloc (new_size,GFP_KERNEL ); addr = new_array ==NULL ?MEMBLOCK_ERROR :__pa (new_array); }else - addr =memblock_find_base (new_size,sizeof (phys_addr_t),MEMBLOCK_ALLOC_ACCESSIBLE ); + addr =memblock_find_base (new_size,sizeof (phys_addr_t),0 ,MEMBLOCK_ALLOC_ACCESSIBLE );if (addr ==MEMBLOCK_ERROR ) {pr_err ("memblock: Failed to double %s array from %ld to %ld entries !\n" ,memblock_type_name (type), type->max, type->max *2 );
@@ -416,7 +421,7 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, ph*/ size =memblock_align_up (size, align); - found =memblock_find_base (size, align, max_addr); + found =memblock_find_base (size, align,0 , max_addr);if (found !=MEMBLOCK_ERROR &&memblock_add_region (&memblock.reserved, found, size) >=0 )return found;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 33/43 memblock: NUMA allocate can now use early_pfn_map
In reply to Benjamin HerrenschmidtWe now provide a default (weak) implementation of memblock_nid_range() which uses the early_pfn_map[] if CONFIG_ARCH_POPULATES_NODE_MAP is set. Sparc still needs to use its own method due to the way the pages can be scattered between nodes.
This implementation is inefficient due to our main algorithm and callback construct wanting to work on an ascending addresses bases while early_pfn_map[] would rather work with nid's (it's unsorted at that stage). But it should work and we can look into improving it subsequently, possibly using arch compile options to chose a different algorithm alltogether.
--- include/linux/memblock.h | 3 +++ mm/memblock.c | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletions(-)
include/linux/memblock.h +3 -0
@@ -47,6 +47,9 @@ extern long memblock_remove(phys_addr_t base, phys_addr_t size);extern long __init memblock_free (phys_addr_t base,phys_addr_t size);extern long __init memblock_reserve (phys_addr_t base,phys_addr_t size); +/* The numa aware allocator is only available if +* CONFIG_ARCH_POPULATES_NODE_MAP is set +*/ extern phys_addr_t __init memblock_alloc_nid (phys_addr_t size,phys_addr_t align,int nid);extern phys_addr_t __init memblock_alloc (phys_addr_t size,phys_addr_t align);
mm/memblock.c +27 -1
@@ -15,6 +15,7 @@#include <linux/init.h> #include <linux/bitops.h> #include <linux/poison.h> +#include <linux/pfn.h> #include <linux/memblock.h> struct memblock memblock;
@@ -451,11 +452,36 @@ phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align)/* * Additional node-local allocators. Search for node memory is bottom up * and walks memblock regions within that node bottom-up as well, but allocation -* within an memblock region is top-down. +* within an memblock region is top-down. XXX I plan to fix that at some stage +* +* WARNING: Only available after early_node_map[] has been populated, +* on some architectures, that is after all the calls to add_active_range() +* have been done to populate it. */ phys_addr_t __weak __init memblock_nid_range (phys_addr_t start,phys_addr_t end,int *nid) { +#ifdef CONFIG_ARCH_POPULATES_NODE_MAP +/* +* This code originates from sparc which really wants use to walk by addresses +* and returns the nid. This is not very convenient for early_pfn_map[] users +* as the map isn't sorted yet, and it really wants to be walked by nid. +* +* For now, I implement the inefficient method below which walks the early +* map multiple times. Eventually we may want to use an ARCH config option +* to implement a completely different method for both case. +*/ +unsigned long start_pfn, end_pfn; +int i; + +for (i =0 ; i <MAX_NUMNODES ; i++) { +get_pfn_range_for_nid (i, &start_pfn, &end_pfn); +if (start <PFN_PHYS (start_pfn) || start >=PFN_PHYS (end_pfn)) +continue ; + *nid = i; +return min (end,PFN_PHYS (end_pfn)); + } +#endif *nid =0 ;return end;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 34/43 memblock: Separate memblock_alloc_nid() and memblock_alloc_try_nid()
In reply to Benjamin HerrenschmidtThe former is now strict, it will fail if it cannot honor the allocation within the node, while the later implements the previous semantic which falls back to allocating anywhere.
--- arch/sparc/mm/init_64.c | 4 ++-- include/linux/memblock.h | 6 +++++- mm/memblock.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-)
arch/sparc/mm/init_64.c +2 -2
@@ -820,7 +820,7 @@ static void __init allocate_node_data(int nid)struct pglist_data *p;#ifdef CONFIG_NEED_MULTIPLE_NODES - paddr =memblock_alloc_nid (sizeof (struct pglist_data ),SMP_CACHE_BYTES , nid); + paddr =memblock_alloc_try_nid (sizeof (struct pglist_data ),SMP_CACHE_BYTES , nid);if (!paddr) {prom_printf ("Cannot allocate pglist_data for nid[%d]\n" , nid);prom_halt ();
@@ -840,7 +840,7 @@ static void __init allocate_node_data(int nid)if (p->node_spanned_pages) { num_pages =bootmem_bootmap_pages (p->node_spanned_pages); - paddr =memblock_alloc_nid (num_pages <<PAGE_SHIFT ,PAGE_SIZE , nid); + paddr =memblock_alloc_try_nid (num_pages <<PAGE_SHIFT ,PAGE_SIZE , nid);if (!paddr) {prom_printf ("Cannot allocate bootmap for nid[%d]\n" , nid);
include/linux/memblock.h +5 -1
@@ -50,7 +50,11 @@ extern long __init memblock_reserve(phys_addr_t base, phys_addr_t size);/* The numa aware allocator is only available if * CONFIG_ARCH_POPULATES_NODE_MAP is set */ -extern phys_addr_t __init memblock_alloc_nid (phys_addr_t size,phys_addr_t align,int nid); +extern phys_addr_t __init memblock_alloc_nid (phys_addr_t size,phys_addr_t align, +int nid); +extern phys_addr_t __init memblock_alloc_try_nid (phys_addr_t size,phys_addr_t align, +int nid); +extern phys_addr_t __init memblock_alloc (phys_addr_t size,phys_addr_t align);/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */
mm/memblock.c +14 -0
@@ -537,9 +537,23 @@ phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nreturn ret; } +return 0 ; +} + +phys_addr_t __init memblock_alloc_try_nid (phys_addr_t size,phys_addr_t align,int nid) +{ +phys_addr_t res =memblock_alloc_nid (size, align, nid); + +if (res) +return res;return memblock_alloc (size, align); } + +/* +* Remaining API functions +*/ +/* You must call memblock_analyze() before this. */ phys_addr_t __init memblock_phys_mem_size (void ) {
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 35/43 memblock: Make memblock_alloc_try_nid() fallback to MEMBLOCK_ALLOC_ANYWHERE
In reply to Benjamin Herrenschmidtmemblock_alloc_nid() used to fallback to allocating anywhere by using memblock_alloc() as a fallback.
However, some of my previous patches limit memblock_alloc() to the region covered by MEMBLOCK_ALLOC_ACCESSIBLE which is not quite what we want for memblock_alloc_try_nid().
So we fix it by explicitely using MEMBLOCK_ALLOC_ANYWHERE.
Not that so far only sparc uses memblock_alloc_nid() and it hasn't been updated to clamp the accessible zone yet. Thus the temporary "breakage" should have no effect.
--- mm/memblock.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
mm/memblock.c +1 -1
@@ -546,7 +546,7 @@ phys_addr_t __init memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, iif (res)return res; -return memblock_alloc (size, align); +return memblock_alloc_base (size, align,MEMBLOCK_ALLOC_ANYWHERE ); }
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 36/43 memblock: Add debugfs files to dump the arrays content
In reply to Benjamin Herrenschmidt--- mm/memblock.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-)
mm/memblock.c +51 -0
@@ -16,6 +16,8 @@#include <linux/bitops.h> #include <linux/poison.h> #include <linux/pfn.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> #include <linux/memblock.h> struct memblock memblock;
@@ -740,3 +742,52 @@ static int __init early_memblock(char *p) }early_param ("memblock" , early_memblock); +#ifdef CONFIG_DEBUG_FS + +static int memblock_debug_show (struct seq_file *m,void *private) +{ +struct memblock_type *type = m->private; +struct memblock_region *reg; +int i; + +for (i =0 ; i < type->cnt; i++) { + reg = &type->regions[i]; +seq_printf (m,"%4d: " , i); +if (sizeof (phys_addr_t) ==4 ) +seq_printf (m,"0x%08lx..0x%08lx\n" , + (unsigned long )reg->base, + (unsigned long )(reg->base + reg->size -1 )); +else +seq_printf (m,"0x%016llx..0x%016llx\n" , + (unsigned long long )reg->base, + (unsigned long long )(reg->base + reg->size -1 )); + + } +return 0 ; +} + +static int memblock_debug_open (struct inode *inode,struct file *file) +{ +return single_open (file, memblock_debug_show, inode->i_private); +} + +static const struct file_operations memblock_debug_fops = { + .open = memblock_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init memblock_init_debugfs (void ) +{ +struct dentry *root =debugfs_create_dir ("memblock" ,NULL ); +if (!root) +return -ENXIO ; +debugfs_create_file ("memory" ,S_IRUGO , root, &memblock.memory, &memblock_debug_fops); +debugfs_create_file ("reserved" ,S_IRUGO , root, &memblock.reserved, &memblock_debug_fops); + +return 0 ; +} +__initcall (memblock_init_debugfs); + +#endif /* CONFIG_DEBUG_FS */
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 37/43 memblock: Expose some memblock bits for use by x86
In reply to Benjamin HerrenschmidtFrom: Yinghai Lu <[email protected]>
This exposes memblock_debug and associated memblock_dbg() macro, along with memblock_can_resize so that x86 can use these when ported to use memblock
--- include/linux/memblock.h | 5 +++++ mm/memblock.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletions(-)
include/linux/memblock.h +5 -0
@@ -39,6 +39,11 @@ struct memblock { };extern struct memblock memblock; +extern int memblock_debug; +extern int memblock_can_resize; + +#define memblock_dbg (fmt, ...) \ + if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)extern void __init memblock_init (void );extern void __init memblock_analyze (void );
mm/memblock.c +2 -1
@@ -22,7 +22,8 @@struct memblock memblock; -static int memblock_debug, memblock_can_resize; +int memblock_debug; +int memblock_can_resize;static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS +1 ];static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS +1 ];
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 38/43 memblock: Improve debug output when resizing the reserve array
In reply to Benjamin HerrenschmidtFrom: Yinghai Lu <[email protected]>
Print out the location info in addition to which array is being resized. Also use memblocK_dbg() to put that under control of the memblock_debug flag.
--- mm/memblock.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
mm/memblock.c +4 -3
@@ -192,8 +192,6 @@ static int memblock_double_array(struct memblock_type *type)if (!memblock_can_resize)return -1 ; -pr_debug ("memblock: %s array full, doubling..." ,memblock_type_name (type)); -/* Calculate new doubled size */ old_size = type->max *sizeof (struct memblock_region ); new_size = old_size <<1 ;
@@ -221,6 +219,9 @@ static int memblock_double_array(struct memblock_type *type) } new_array =__va (addr); +memblock_dbg ("memblock: %s array is doubled to %ld at [%#010llx-%#010llx]" , +memblock_type_name (type), type->max *2 , (u64 )addr, (u64 )addr + new_size -1 ); +/* Found space, we now need to move the array over before * we add the reserved region since it may be our reserved * array itself that is full.
@@ -672,7 +673,7 @@ static void memblock_dump(struct memblock_type *region, char *name) base = region->regions[i].base; size = region->regions[i].size; -pr_info (" %s[0x%x]\t0x%016llx - 0x%016llx, 0x%llx bytes\n" , +pr_info (" %s[%#x]\t[%#016llx-%#016llx], %#llx bytes\n" , name, i, base, base + size -1 , size); } }
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 39/43 memblock: Export MEMBLOCK_ERROR
In reply to Benjamin HerrenschmidtFrom: Yinghai Lu <[email protected]>
will used by x86 memblock_x86_find_in_range_node and nobootmem replacement
--- include/linux/memblock.h | 3 ++- mm/memblock.c | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-)
include/linux/memblock.h +2 -1
@@ -18,7 +18,8 @@#include <asm/memblock.h> -#define INIT_MEMBLOCK_REGIONS 128 +#define INIT_MEMBLOCK_REGIONS 128 +#define MEMBLOCK_ERROR (~(phys_addr_t)0)struct memblock_region {phys_addr_t base;
mm/memblock.c +0 -2
@@ -27,8 +27,6 @@ int memblock_can_resize;static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS +1 ];static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS +1 ]; -#define MEMBLOCK_ERROR (~(phys_addr_t)0) -/* inline so we don't get a warning when pr_debug is compiled out */ static inline const char *memblock_type_name (struct memblock_type *type) {
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 40/43 memblock: Make MEMBLOCK_ERROR be 0
In reply to Benjamin HerrenschmidtAnd ensure we don't hand out 0 as a valid allocation. We put the low limit at PAGE_SIZE arbitrarily.
--- include/linux/memblock.h | 2 +- mm/memblock.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletions(-)
include/linux/memblock.h +1 -1
@@ -19,7 +19,7 @@#include <asm/memblock.h> #define INIT_MEMBLOCK_REGIONS 128 -#define MEMBLOCK_ERROR (~(phys_addr_t)0) +#define MEMBLOCK_ERROR 0struct memblock_region {phys_addr_t base;
mm/memblock.c +6 -0
@@ -105,6 +105,12 @@ static phys_addr_t __init memblock_find_region(phys_addr_t start, phys_addr_t enphys_addr_t base, res_base;long j; +/* Prevent allocations returning 0 as it's also used to +* indicate an allocation failure +*/ +if (start ==0 ) + start =PAGE_SIZE ; + base =memblock_align_down ((end - size), align);while (start <= base) { j =memblock_overlaps_region (&memblock.reserved, base, size);
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 41/43 memblock: Protect memblock.h with CONFIG_HAVE_MEMBLOCK
In reply to Benjamin HerrenschmidtFrom: Yinghai Lu <[email protected]>
This should make it easier to catch/debug incorrect use when the CONFIG_ option isn't set.
--- include/linux/memblock.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
include/linux/memblock.h +3 -0
@@ -2,6 +2,7 @@#define _LINUX_MEMBLOCK_H#ifdef __KERNEL__ +#ifdef CONFIG_HAVE_MEMBLOCK /* * Logical memory blocks. *
@@ -148,6 +149,8 @@ static inline unsigned long memblock_region_pages(const struct memblock_region * region++) +#endif /* CONFIG_HAVE_MEMBLOCK */ +#endif /* __KERNEL__ */ #endif /* _LINUX_MEMBLOCK_H */
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 42/43 memblock: Option for the architecture to put memblock into the .init section
In reply to Benjamin HerrenschmidtFrom: Yinghai Lu <[email protected]>
Arch code can define ARCH_DISCARD_MEMBLOCK in asm/memblock.h, which in turns causes memblock code and data to go respectively into the .init and .initdata sections. This will be used by the x86 architecture.
If ARCH_DISCARD_MEMBLOCK is defined, the debugfs files to inspect the memblock arrays after boot are not created.
--- include/linux/memblock.h | 8 +++++++ mm/memblock.c | 48 +++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 24 deletions(-)
include/linux/memblock.h +8 -0
@@ -149,6 +149,14 @@ static inline unsigned long memblock_region_pages(const struct memblock_region * region++) +#ifdef ARCH_DISCARD_MEMBLOCK +#define __init_memblock __init +#define __initdata_memblock __initdata +#else +#define __init_memblock +#define __initdata_memblock +#endif +#endif /* CONFIG_HAVE_MEMBLOCK */ #endif /* __KERNEL__ */
mm/memblock.c +24 -24
162 lines not on this page · raw message
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 43/43 memblock: Add memblock_find_in_range()
In reply to Benjamin HerrenschmidtFrom: Yinghai Lu <[email protected]>
This is a wrapper for memblock_find_base() using slightly different arguments (start,end instead of start,size for example) in order to make it easier to convert existing arch/x86 code.
--- include/linux/memblock.h | 2 ++ mm/memblock.c | 8 ++++++++ 2 files changed, 10 insertions(+), 0 deletions(-)
include/linux/memblock.h +2 -0
@@ -47,6 +47,8 @@ extern int memblock_can_resize;#define memblock_dbg (fmt, ...) \ if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +u64 memblock_find_in_range (u64 start,u64 end,u64 size,u64 align); +extern void __init memblock_init (void );extern void __init memblock_analyze (void );extern long memblock_add (phys_addr_t base,phys_addr_t size);
mm/memblock.c +8 -0
@@ -162,6 +162,14 @@ static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t alignreturn MEMBLOCK_ERROR ; } +/* +* Find a free area with specified alignment in a specific range. +*/ +u64 __init_memblock memblock_find_in_range(u64 start, u64 end, u64 size, u64 align) +{ +return memblock_find_base (size, align, start, end); +} + static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r) {unsigned long i;
Signature · 7 lines
1.7.0.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>