Commit 4fe9e1d9 authored by Helge Deller's avatar Helge Deller

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: default avatarHelge Deller <deller@gmx.de>
parent 9e91db6b
...@@ -10,6 +10,8 @@ config PARISC ...@@ -10,6 +10,8 @@ config PARISC
select RTC_CLASS select RTC_CLASS
select RTC_DRV_GENERIC select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE select INIT_ALL_POSSIBLE
select HAVE_MEMBLOCK
select NO_BOOTMEM
select BUG select BUG
select BUILDTIME_EXTABLE_SORT select BUILDTIME_EXTABLE_SORT
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
......
...@@ -138,8 +138,6 @@ SECTIONS ...@@ -138,8 +138,6 @@ SECTIONS
/* BSS */ /* BSS */
BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE) BSS_SECTION(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE)
/* bootmap is allocated in setup_bootmem() directly behind bss. */
. = ALIGN(HUGEPAGE_SIZE); . = ALIGN(HUGEPAGE_SIZE);
_end = . ; _end = . ;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/memblock.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -79,6 +80,34 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly; ...@@ -79,6 +80,34 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
int npmem_ranges __read_mostly; int npmem_ranges __read_mostly;
/*
* get_memblock() allocates pages via memblock.
* We can't use memblock_find_in_range(0, KERNEL_INITIAL_SIZE) here since it
* doesn't allocate from bottom to top which is needed because we only created
* the initial mapping up to KERNEL_INITIAL_SIZE in the assembly bootup code.
*/
static void * __init get_memblock(unsigned long size)
{
static phys_addr_t search_addr __initdata;
phys_addr_t phys;
if (!search_addr)
search_addr = PAGE_ALIGN(__pa((unsigned long) &_end));
search_addr = ALIGN(search_addr, size);
while (!memblock_is_region_memory(search_addr, size) ||
memblock_is_region_reserved(search_addr, size)) {
search_addr += size;
}
phys = search_addr;
if (phys)
memblock_reserve(phys, size);
else
panic("get_memblock() failed.\n");
return __va(phys);
}
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define MAX_MEM (~0UL) #define MAX_MEM (~0UL)
#else /* !CONFIG_64BIT */ #else /* !CONFIG_64BIT */
...@@ -118,11 +147,7 @@ static void __init mem_limit_func(void) ...@@ -118,11 +147,7 @@ static void __init mem_limit_func(void)
static void __init setup_bootmem(void) static void __init setup_bootmem(void)
{ {
unsigned long bootmap_size;
unsigned long mem_max; unsigned long mem_max;
unsigned long bootmap_pages;
unsigned long bootmap_start_pfn;
unsigned long bootmap_pfn;
#ifndef CONFIG_DISCONTIGMEM #ifndef CONFIG_DISCONTIGMEM
physmem_range_t pmem_holes[MAX_PHYSMEM_RANGES - 1]; physmem_range_t pmem_holes[MAX_PHYSMEM_RANGES - 1];
int npmem_holes; int npmem_holes;
...@@ -178,33 +203,29 @@ static void __init setup_bootmem(void) ...@@ -178,33 +203,29 @@ static void __init setup_bootmem(void)
} }
#endif #endif
if (npmem_ranges > 1) {
/* Print the memory ranges */ /* Print the memory ranges */
pr_info("Memory Ranges:\n");
printk(KERN_INFO "Memory Ranges:\n");
for (i = 0; i < npmem_ranges; i++) { for (i = 0; i < npmem_ranges; i++) {
struct resource *res = &sysram_resources[i];
unsigned long start; unsigned long start;
unsigned long size; unsigned long size;
size = (pmem_ranges[i].pages << PAGE_SHIFT); size = (pmem_ranges[i].pages << PAGE_SHIFT);
start = (pmem_ranges[i].start_pfn << PAGE_SHIFT); start = (pmem_ranges[i].start_pfn << PAGE_SHIFT);
printk(KERN_INFO "%2d) Start 0x%016lx End 0x%016lx Size %6ld MB\n", pr_info("%2d) Start 0x%016lx End 0x%016lx Size %6ld MB\n",
i,start, start + (size - 1), size >> 20); i, start, start + (size - 1), size >> 20);
}
}
sysram_resource_count = npmem_ranges; /* request memory resource */
for (i = 0; i < sysram_resource_count; i++) {
struct resource *res = &sysram_resources[i];
res->name = "System RAM"; res->name = "System RAM";
res->start = pmem_ranges[i].start_pfn << PAGE_SHIFT; res->start = start;
res->end = res->start + (pmem_ranges[i].pages << PAGE_SHIFT)-1; res->end = start + size - 1;
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res); request_resource(&iomem_resource, res);
} }
sysram_resource_count = npmem_ranges;
/* /*
* For 32 bit kernels we limit the amount of memory we can * For 32 bit kernels we limit the amount of memory we can
* support, in order to preserve enough kernel address space * support, in order to preserve enough kernel address space
...@@ -263,16 +284,9 @@ static void __init setup_bootmem(void) ...@@ -263,16 +284,9 @@ static void __init setup_bootmem(void)
} }
#endif #endif
bootmap_pages = 0;
for (i = 0; i < npmem_ranges; i++)
bootmap_pages += bootmem_bootmap_pages(pmem_ranges[i].pages);
bootmap_start_pfn = PAGE_ALIGN(__pa((unsigned long) &_end)) >> PAGE_SHIFT;
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
for (i = 0; i < MAX_PHYSMEM_RANGES; i++) { for (i = 0; i < MAX_PHYSMEM_RANGES; i++) {
memset(NODE_DATA(i), 0, sizeof(pg_data_t)); memset(NODE_DATA(i), 0, sizeof(pg_data_t));
NODE_DATA(i)->bdata = &bootmem_node_data[i];
} }
memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
...@@ -284,28 +298,24 @@ static void __init setup_bootmem(void) ...@@ -284,28 +298,24 @@ static void __init setup_bootmem(void)
/* /*
* Initialize and free the full range of memory in each range. * Initialize and free the full range of memory in each range.
* Note that the only writing these routines do are to the bootmap,
* and we've made sure to locate the bootmap properly so that they
* won't be writing over anything important.
*/ */
bootmap_pfn = bootmap_start_pfn;
max_pfn = 0; max_pfn = 0;
for (i = 0; i < npmem_ranges; i++) { for (i = 0; i < npmem_ranges; i++) {
unsigned long start_pfn; unsigned long start_pfn;
unsigned long npages; unsigned long npages;
unsigned long start;
unsigned long size;
start_pfn = pmem_ranges[i].start_pfn; start_pfn = pmem_ranges[i].start_pfn;
npages = pmem_ranges[i].pages; npages = pmem_ranges[i].pages;
bootmap_size = init_bootmem_node(NODE_DATA(i), start = start_pfn << PAGE_SHIFT;
bootmap_pfn, size = npages << PAGE_SHIFT;
start_pfn,
(start_pfn + npages) ); /* add system RAM memblock */
free_bootmem_node(NODE_DATA(i), memblock_add(start, size);
(start_pfn << PAGE_SHIFT),
(npages << PAGE_SHIFT) );
bootmap_pfn += (bootmap_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
if ((start_pfn + npages) > max_pfn) if ((start_pfn + npages) > max_pfn)
max_pfn = start_pfn + npages; max_pfn = start_pfn + npages;
} }
...@@ -317,32 +327,22 @@ static void __init setup_bootmem(void) ...@@ -317,32 +327,22 @@ static void __init setup_bootmem(void)
*/ */
max_low_pfn = max_pfn; max_low_pfn = max_pfn;
/* bootmap sizing messed up? */
BUG_ON((bootmap_pfn - bootmap_start_pfn) != bootmap_pages);
/* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */ /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */
#define PDC_CONSOLE_IO_IODC_SIZE 32768 #define PDC_CONSOLE_IO_IODC_SIZE 32768
reserve_bootmem_node(NODE_DATA(0), 0UL, memblock_reserve(0UL, (unsigned long)(PAGE0->mem_free +
(unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE));
PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT); memblock_reserve(__pa(KERNEL_BINARY_TEXT_START),
reserve_bootmem_node(NODE_DATA(0), __pa(KERNEL_BINARY_TEXT_START), (unsigned long)(_end - KERNEL_BINARY_TEXT_START));
(unsigned long)(_end - KERNEL_BINARY_TEXT_START),
BOOTMEM_DEFAULT);
reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT),
BOOTMEM_DEFAULT);
#ifndef CONFIG_DISCONTIGMEM #ifndef CONFIG_DISCONTIGMEM
/* reserve the holes */ /* reserve the holes */
for (i = 0; i < npmem_holes; i++) { for (i = 0; i < npmem_holes; i++) {
reserve_bootmem_node(NODE_DATA(0), memblock_reserve((pmem_holes[i].start_pfn << PAGE_SHIFT),
(pmem_holes[i].start_pfn << PAGE_SHIFT), (pmem_holes[i].pages << PAGE_SHIFT));
(pmem_holes[i].pages << PAGE_SHIFT),
BOOTMEM_DEFAULT);
} }
#endif #endif
...@@ -360,8 +360,7 @@ static void __init setup_bootmem(void) ...@@ -360,8 +360,7 @@ static void __init setup_bootmem(void)
initrd_below_start_ok = 1; initrd_below_start_ok = 1;
printk(KERN_INFO "initrd: reserving %08lx-%08lx (mem_max %08lx)\n", __pa(initrd_start), __pa(initrd_start) + initrd_reserve, mem_max); printk(KERN_INFO "initrd: reserving %08lx-%08lx (mem_max %08lx)\n", __pa(initrd_start), __pa(initrd_start) + initrd_reserve, mem_max);
reserve_bootmem_node(NODE_DATA(0), __pa(initrd_start), memblock_reserve(__pa(initrd_start), initrd_reserve);
initrd_reserve, BOOTMEM_DEFAULT);
} }
} }
#endif #endif
...@@ -439,7 +438,7 @@ static void __init map_pages(unsigned long start_vaddr, ...@@ -439,7 +438,7 @@ static void __init map_pages(unsigned long start_vaddr,
*/ */
if (!pmd) { if (!pmd) {
pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE << PMD_ORDER); pmd = (pmd_t *) get_memblock(PAGE_SIZE << PMD_ORDER);
pmd = (pmd_t *) __pa(pmd); pmd = (pmd_t *) __pa(pmd);
} }
...@@ -458,8 +457,7 @@ static void __init map_pages(unsigned long start_vaddr, ...@@ -458,8 +457,7 @@ static void __init map_pages(unsigned long start_vaddr,
pg_table = (pte_t *)pmd_address(*pmd); pg_table = (pte_t *)pmd_address(*pmd);
if (!pg_table) { if (!pg_table) {
pg_table = (pte_t *) pg_table = (pte_t *) get_memblock(PAGE_SIZE);
alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE);
pg_table = (pte_t *) __pa(pg_table); pg_table = (pte_t *) __pa(pg_table);
} }
...@@ -737,7 +735,7 @@ static void __init pagetable_init(void) ...@@ -737,7 +735,7 @@ static void __init pagetable_init(void)
} }
#endif #endif
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE); empty_zero_page = get_memblock(PAGE_SIZE);
} }
static void __init gateway_init(void) static void __init gateway_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment