aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2016-10-07 10:50:21 -0400
committerHelge Deller <deller@gmx.de>2016-10-07 11:03:02 -0400
commit4fe9e1d957e45ad8eba9885ee860a0e93d13a7c7 (patch)
tree3b9777d418977e74cdb37404de428c90aa1aee0a
parent9e91db6b4abecd58647a5e984d538187f1c2ea09 (diff)
parisc: Drop bootmem and switch to memblock
Memblock is the standard kernel boot-time memory tracker/allocator. Use it instead of the bootmem allocator. This allows using kmemleak, CMA and other features. Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/parisc/mm/init.c126
3 files changed, 64 insertions, 66 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 689eb74b34b5..2a0339a68894 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -10,6 +10,8 @@ config PARISC
10 select RTC_CLASS 10 select RTC_CLASS
11 select RTC_DRV_GENERIC 11 select RTC_DRV_GENERIC
12 select INIT_ALL_POSSIBLE 12 select INIT_ALL_POSSIBLE
13 select HAVE_MEMBLOCK
14 select NO_BOOTMEM
13 select BUG 15 select BUG
14 select BUILDTIME_EXTABLE_SORT 16 select BUILDTIME_EXTABLE_SORT
15 select HAVE_PERF_EVENTS 17 select HAVE_PERF_EVENTS
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index f3ead0b6ce46..5b8fae8d4d12 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -138,8 +138,6 @@ SECTIONS
138 /* BSS */ 138 /* BSS */
139 BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE) 139 BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE)
140 140
141 /* bootmap is allocated in setup_bootmem() directly behind bss. */
142
143 . = ALIGN(HUGEPAGE_SIZE); 141 . = ALIGN(HUGEPAGE_SIZE);
144 _end = . ; 142 _end = . ;
145 143
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 6b3e7c6ee096..356f38473b5d 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/bootmem.h> 16#include <linux/bootmem.h>
17#include <linux/memblock.h>
17#include <linux/gfp.h> 18#include <linux/gfp.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/init.h> 20#include <linux/init.h>
@@ -79,6 +80,34 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
79physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; 80physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
80int npmem_ranges __read_mostly; 81int npmem_ranges __read_mostly;
81 82
83/*
84 * get_memblock() allocates pages via memblock.
85 * We can't use memblock_find_in_range(0, KERNEL_INITIAL_SIZE) here since it
86 * doesn't allocate from bottom to top which is needed because we only created
87 * the initial mapping up to KERNEL_INITIAL_SIZE in the assembly bootup code.
88 */
89static void * __init get_memblock(unsigned long size)
90{
91 static phys_addr_t search_addr __initdata;
92 phys_addr_t phys;
93
94 if (!search_addr)
95 search_addr = PAGE_ALIGN(__pa((unsigned long) &_end));
96 search_addr = ALIGN(search_addr, size);
97 while (!memblock_is_region_memory(search_addr, size) ||
98 memblock_is_region_reserved(search_addr, size)) {
99 search_addr += size;
100 }
101 phys = search_addr;
102
103 if (phys)
104 memblock_reserve(phys, size);
105 else
106 panic("get_memblock() failed.\n");
107
108 return __va(phys);
109}
110
82#ifdef CONFIG_64BIT 111#ifdef CONFIG_64BIT
83#define MAX_MEM (~0UL) 112#define MAX_MEM (~0UL)
84#else /* !CONFIG_64BIT */ 113#else /* !CONFIG_64BIT */
@@ -118,11 +147,7 @@ static void __init mem_limit_func(void)
118 147
119static void __init setup_bootmem(void) 148static void __init setup_bootmem(void)
120{ 149{
121 unsigned long bootmap_size;
122 unsigned long mem_max; 150 unsigned long mem_max;
123 unsigned long bootmap_pages;
124 unsigned long bootmap_start_pfn;
125 unsigned long bootmap_pfn;
126#ifndef CONFIG_DISCONTIGMEM 151#ifndef CONFIG_DISCONTIGMEM
127 physmem_range_t pmem_holes[MAX_PHYSMEM_RANGES - 1]; 152 physmem_range_t pmem_holes[MAX_PHYSMEM_RANGES - 1];
128 int npmem_holes; 153 int npmem_holes;
@@ -178,33 +203,29 @@ static void __init setup_bootmem(void)
178 } 203 }
179#endif 204#endif
180 205
181 if (npmem_ranges > 1) { 206 /* Print the memory ranges */
182 207 pr_info("Memory Ranges:\n");
183 /* Print the memory ranges */
184 208
185 printk(KERN_INFO "Memory Ranges:\n"); 209 for (i = 0; i < npmem_ranges; i++) {
210 struct resource *res = &sysram_resources[i];
211 unsigned long start;
212 unsigned long size;
186 213
187 for (i = 0; i < npmem_ranges; i++) { 214 size = (pmem_ranges[i].pages << PAGE_SHIFT);
188 unsigned long start; 215 start = (pmem_ranges[i].start_pfn << PAGE_SHIFT);
189 unsigned long size; 216 pr_info("%2d) Start 0x%016lx End 0x%016lx Size %6ld MB\n",
217 i, start, start + (size - 1), size >> 20);
190 218
191 size = (pmem_ranges[i].pages << PAGE_SHIFT); 219 /* request memory resource */
192 start = (pmem_ranges[i].start_pfn << PAGE_SHIFT);
193 printk(KERN_INFO "%2d) Start 0x%016lx End 0x%016lx Size %6ld MB\n",
194 i,start, start + (size - 1), size >> 20);
195 }
196 }
197
198 sysram_resource_count = npmem_ranges;
199 for (i = 0; i < sysram_resource_count; i++) {
200 struct resource *res = &sysram_resources[i];
201 res->name = "System RAM"; 220 res->name = "System RAM";
202 res->start = pmem_ranges[i].start_pfn << PAGE_SHIFT; 221 res->start = start;
203 res->end = res->start + (pmem_ranges[i].pages << PAGE_SHIFT)-1; 222 res->end = start + size - 1;
204 res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; 223 res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
205 request_resource(&iomem_resource, res); 224 request_resource(&iomem_resource, res);
206 } 225 }
207 226
227 sysram_resource_count = npmem_ranges;
228
208 /* 229 /*
209 * For 32 bit kernels we limit the amount of memory we can 230 * For 32 bit kernels we limit the amount of memory we can
210 * support, in order to preserve enough kernel address space 231 * support, in order to preserve enough kernel address space
@@ -263,16 +284,9 @@ static void __init setup_bootmem(void)
263 } 284 }
264#endif 285#endif
265 286
266 bootmap_pages = 0;
267 for (i = 0; i < npmem_ranges; i++)
268 bootmap_pages += bootmem_bootmap_pages(pmem_ranges[i].pages);
269
270 bootmap_start_pfn = PAGE_ALIGN(__pa((unsigned long) &_end)) >> PAGE_SHIFT;
271
272#ifdef CONFIG_DISCONTIGMEM 287#ifdef CONFIG_DISCONTIGMEM
273 for (i = 0; i < MAX_PHYSMEM_RANGES; i++) { 288 for (i = 0; i < MAX_PHYSMEM_RANGES; i++) {
274 memset(NODE_DATA(i), 0, sizeof(pg_data_t)); 289 memset(NODE_DATA(i), 0, sizeof(pg_data_t));
275 NODE_DATA(i)->bdata = &bootmem_node_data[i];
276 } 290 }
277 memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); 291 memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
278 292
@@ -284,28 +298,24 @@ static void __init setup_bootmem(void)
284 298
285 /* 299 /*
286 * Initialize and free the full range of memory in each range. 300 * Initialize and free the full range of memory in each range.
287 * Note that the only writing these routines do are to the bootmap,
288 * and we've made sure to locate the bootmap properly so that they
289 * won't be writing over anything important.
290 */ 301 */
291 302
292 bootmap_pfn = bootmap_start_pfn;
293 max_pfn = 0; 303 max_pfn = 0;
294 for (i = 0; i < npmem_ranges; i++) { 304 for (i = 0; i < npmem_ranges; i++) {
295 unsigned long start_pfn; 305 unsigned long start_pfn;
296 unsigned long npages; 306 unsigned long npages;
307 unsigned long start;
308 unsigned long size;
297 309
298 start_pfn = pmem_ranges[i].start_pfn; 310 start_pfn = pmem_ranges[i].start_pfn;
299 npages = pmem_ranges[i].pages; 311 npages = pmem_ranges[i].pages;
300 312
301 bootmap_size = init_bootmem_node(NODE_DATA(i), 313 start = start_pfn << PAGE_SHIFT;
302 bootmap_pfn, 314 size = npages << PAGE_SHIFT;
303 start_pfn, 315
304 (start_pfn + npages) ); 316 /* add system RAM memblock */
305 free_bootmem_node(NODE_DATA(i), 317 memblock_add(start, size);
306 (start_pfn << PAGE_SHIFT), 318
307 (npages << PAGE_SHIFT) );
308 bootmap_pfn += (bootmap_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
309 if ((start_pfn + npages) > max_pfn) 319 if ((start_pfn + npages) > max_pfn)
310 max_pfn = start_pfn + npages; 320 max_pfn = start_pfn + npages;
311 } 321 }
@@ -317,32 +327,22 @@ static void __init setup_bootmem(void)
317 */ 327 */
318 max_low_pfn = max_pfn; 328 max_low_pfn = max_pfn;
319 329
320 /* bootmap sizing messed up? */
321 BUG_ON((bootmap_pfn - bootmap_start_pfn) != bootmap_pages);
322
323 /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */ 330 /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */
324 331
325#define PDC_CONSOLE_IO_IODC_SIZE 32768 332#define PDC_CONSOLE_IO_IODC_SIZE 32768
326 333
327 reserve_bootmem_node(NODE_DATA(0), 0UL, 334 memblock_reserve(0UL, (unsigned long)(PAGE0->mem_free +
328 (unsigned long)(PAGE0->mem_free + 335 PDC_CONSOLE_IO_IODC_SIZE));
329 PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT); 336 memblock_reserve(__pa(KERNEL_BINARY_TEXT_START),
330 reserve_bootmem_node(NODE_DATA(0), __pa(KERNEL_BINARY_TEXT_START), 337 (unsigned long)(_end - KERNEL_BINARY_TEXT_START));
331 (unsigned long)(_end - KERNEL_BINARY_TEXT_START),
332 BOOTMEM_DEFAULT);
333 reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
334 ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT),
335 BOOTMEM_DEFAULT);
336 338
337#ifndef CONFIG_DISCONTIGMEM 339#ifndef CONFIG_DISCONTIGMEM
338 340
339 /* reserve the holes */ 341 /* reserve the holes */
340 342
341 for (i = 0; i < npmem_holes; i++) { 343 for (i = 0; i < npmem_holes; i++) {
342 reserve_bootmem_node(NODE_DATA(0), 344 memblock_reserve((pmem_holes[i].start_pfn << PAGE_SHIFT),
343 (pmem_holes[i].start_pfn << PAGE_SHIFT), 345 (pmem_holes[i].pages << PAGE_SHIFT));
344 (pmem_holes[i].pages << PAGE_SHIFT),
345 BOOTMEM_DEFAULT);
346 } 346 }
347#endif 347#endif
348 348
@@ -360,8 +360,7 @@ static void __init setup_bootmem(void)
360 initrd_below_start_ok = 1; 360 initrd_below_start_ok = 1;
361 printk(KERN_INFO "initrd: reserving %08lx-%08lx (mem_max %08lx)\n", __pa(initrd_start), __pa(initrd_start) + initrd_reserve, mem_max); 361 printk(KERN_INFO "initrd: reserving %08lx-%08lx (mem_max %08lx)\n", __pa(initrd_start), __pa(initrd_start) + initrd_reserve, mem_max);
362 362
363 reserve_bootmem_node(NODE_DATA(0), __pa(initrd_start), 363 memblock_reserve(__pa(initrd_start), initrd_reserve);
364 initrd_reserve, BOOTMEM_DEFAULT);
365 } 364 }
366 } 365 }
367#endif 366#endif
@@ -439,7 +438,7 @@ static void __init map_pages(unsigned long start_vaddr,
439 */ 438 */
440 439
441 if (!pmd) { 440 if (!pmd) {
442 pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE << PMD_ORDER); 441 pmd = (pmd_t *) get_memblock(PAGE_SIZE << PMD_ORDER);
443 pmd = (pmd_t *) __pa(pmd); 442 pmd = (pmd_t *) __pa(pmd);
444 } 443 }
445 444
@@ -458,8 +457,7 @@ static void __init map_pages(unsigned long start_vaddr,
458 457
459 pg_table = (pte_t *)pmd_address(*pmd); 458 pg_table = (pte_t *)pmd_address(*pmd);
460 if (!pg_table) { 459 if (!pg_table) {
461 pg_table = (pte_t *) 460 pg_table = (pte_t *) get_memblock(PAGE_SIZE);
462 alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE);
463 pg_table = (pte_t *) __pa(pg_table); 461 pg_table = (pte_t *) __pa(pg_table);
464 } 462 }
465 463
@@ -737,7 +735,7 @@ static void __init pagetable_init(void)
737 } 735 }
738#endif 736#endif
739 737
740 empty_zero_page = alloc_bootmem_pages(PAGE_SIZE); 738 empty_zero_page = get_memblock(PAGE_SIZE);
741} 739}
742 740
743static void __init gateway_init(void) 741static void __init gateway_init(void)