diff options
author | Helge Deller <deller@gmx.de> | 2016-10-07 10:50:21 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2016-10-07 11:03:02 -0400 |
commit | 4fe9e1d957e45ad8eba9885ee860a0e93d13a7c7 (patch) | |
tree | 3b9777d418977e74cdb37404de428c90aa1aee0a | |
parent | 9e91db6b4abecd58647a5e984d538187f1c2ea09 (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/Kconfig | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/vmlinux.lds.S | 2 | ||||
-rw-r--r-- | arch/parisc/mm/init.c | 126 |
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; | |||
79 | physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; | 80 | physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; |
80 | int npmem_ranges __read_mostly; | 81 | int 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 | */ | ||
89 | static 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 | ||
119 | static void __init setup_bootmem(void) | 148 | static 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 | ||
743 | static void __init gateway_init(void) | 741 | static void __init gateway_init(void) |