From 43064c0c8ee2ada8edd421520c633584d648e100 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 22 Nov 2011 14:38:03 +0000 Subject: MIPS: Handle initmem in systems with kernel not in add_memory_region() mem This patch addresses a couple of related problems: 1) The kernel may reside in physical memory outside of the ranges set by plat_mem_setup(). If this is the case, init mem cannot be reused as it resides outside of the range of pages that the kernel memory allocators control. 2) initrd images might be loaded in physical memory outside of the ranges set by plat_mem_setup(). The memory likewise cannot be reused. The patch doesn't handle this specific case, but the infrastructure is useful for future patches that do. The crux of the problem is that there are memory regions that need be memory_present(), but that cannot be free_bootmem() at the time of arch_mem_init(). We create a new type of memory (BOOT_MEM_INIT_RAM) for use with add_memory_region(). Then arch_mem_init() adds the init mem with this type if the init mem is not already covered by existing ranges. When memory is being freed into the bootmem allocator, we skip the BOOT_MEM_INIT_RAM ranges so they are not clobbered, but we do signal them as memory_present(). This way when they are later freed, the necessary memory manager structures have initialized and the Sparse allocater is prevented from crashing. The Octeon specific code that handled this case is removed, because the new general purpose code handles the case. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/1988/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'arch/mips/kernel/setup.c') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 84af26ab2212..e86c2cf554aa 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -121,6 +121,9 @@ static void __init print_memory_map(void) case BOOT_MEM_RAM: printk(KERN_CONT "(usable)\n"); break; + case BOOT_MEM_INIT_RAM: + printk(KERN_CONT "(usable after init)\n"); + break; case BOOT_MEM_ROM_DATA: printk(KERN_CONT "(ROM data)\n"); break; @@ -361,15 +364,24 @@ static void __init bootmem_init(void) for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end, size; + start = PFN_UP(boot_mem_map.map[i].addr); + end = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + /* * Reserve usable memory. */ - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + break; + case BOOT_MEM_INIT_RAM: + memory_present(0, start, end); continue; + default: + /* Not usable memory */ + continue; + } - start = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); /* * We are rounding up the start address of usable memory * and at the end of the usable range downwards. @@ -455,11 +467,33 @@ early_param("mem", early_parse_mem); static void __init arch_mem_init(char **cmdline_p) { + phys_t init_mem, init_end, init_size; + extern void plat_mem_setup(void); /* call board setup routine */ plat_mem_setup(); + init_mem = PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT; + init_end = PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT; + init_size = init_end - init_mem; + if (init_size) { + /* Make sure it is in the boot_mem_map */ + int i, found; + found = 0; + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (init_mem >= boot_mem_map.map[i].addr && + init_mem < (boot_mem_map.map[i].addr + + boot_mem_map.map[i].size)) { + found = 1; + break; + } + } + if (!found) + add_memory_region(init_mem, init_size, + BOOT_MEM_INIT_RAM); + } + pr_info("Determined physical RAM map:\n"); print_memory_map(); @@ -523,6 +557,7 @@ static void __init resource_init(void) res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { case BOOT_MEM_RAM: + case BOOT_MEM_INIT_RAM: case BOOT_MEM_ROM_DATA: res->name = "System RAM"; break; -- cgit v1.2.3 From 9d15ffc824a90842b16592f3a960836841bd6c58 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 8 Dec 2011 10:22:09 -0800 Subject: mips: Use HAVE_MEMBLOCK_NODE_MAP mips used early_node_map[] just to prime free_area_init_nodes(). Now memblock can be used for the same purpose and early_node_map[] is scheduled to be dropped. Use memblock instead. Signed-off-by: Tejun Heo Acked-by: Ralf Baechle Cc: Benjamin Herrenschmidt Cc: Yinghai Lu Cc: linux-mips@linux-mips.org --- arch/mips/Kconfig | 3 +++ arch/mips/kernel/setup.c | 3 ++- arch/mips/sgi-ip27/ip27-memory.c | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'arch/mips/kernel/setup.c') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d46f1da18a3c..b789847d93fd 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -25,6 +25,9 @@ config MIPS select GENERIC_IRQ_SHOW select HAVE_ARCH_JUMP_LABEL select IRQ_FORCED_THREADING + select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_NODE_MAP + select ARCH_DISCARD_MEMBLOCK menu "Machine selection" diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 84af26ab2212..b1cb8f87d7b4 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -352,7 +353,7 @@ static void __init bootmem_init(void) continue; #endif - add_active_range(0, start, end); + memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0); } /* diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index bc1297109cc5..b105eca3c020 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -381,8 +382,8 @@ static void __init szmem(void) continue; } num_physpages += slot_psize; - add_active_range(node, slot_getbasepfn(node, slot), - slot_getbasepfn(node, slot) + slot_psize); + memblock_add_node(PFN_PHYS(slot_getbasepfn(node, slot)), + PFN_PHYS(slot_psize), node); } } } -- cgit v1.2.3