Commit 72a7fe39 authored by Bernhard Walle's avatar Bernhard Walle Committed by Linus Torvalds
Browse files

Introduce flags for reserve_bootmem()



This patchset adds a flags variable to reserve_bootmem() and uses the
BOOTMEM_EXCLUSIVE flag in crashkernel reservation code to detect collisions
between crashkernel area and already used memory.

This patch:

Change the reserve_bootmem() function to accept a new flag BOOTMEM_EXCLUSIVE.
If that flag is set, the function returns with -EBUSY if the memory already
has been reserved in the past.  This is to avoid conflicts.

Because that code runs before SMP initialisation, there's no race condition
inside reserve_bootmem_core().

[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: fix powerpc build]
Signed-off-by: default avatarBernhard Walle <bwalle@suse.de>
Cc: <linux-arch@vger.kernel.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 25fad945
......@@ -241,7 +241,8 @@ albacore_init_arch(void)
size / 1024);
}
#endif
reserve_bootmem_node(NODE_DATA(0), pci_mem, memtop - pci_mem);
reserve_bootmem_node(NODE_DATA(0), pci_mem, memtop -
pci_mem, BOOTMEM_DEFAULT);
printk("irongate_init_arch: temporarily reserving "
"region %08lx-%08lx for PCI\n", pci_mem, memtop - 1);
}
......
......@@ -428,7 +428,8 @@ setup_memory(void *kernel_end)
}
/* Reserve the bootmap memory. */
reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size,
BOOTMEM_DEFAULT);
printk("reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
#ifdef CONFIG_BLK_DEV_INITRD
......@@ -446,7 +447,7 @@ setup_memory(void *kernel_end)
phys_to_virt(PFN_PHYS(max_low_pfn)));
} else {
reserve_bootmem(virt_to_phys((void *)initrd_start),
INITRD_SIZE);
INITRD_SIZE, BOOTMEM_DEFAULT);
}
}
#endif /* CONFIG_BLK_DEV_INITRD */
......
......@@ -242,7 +242,8 @@ setup_memory_node(int nid, void *kernel_end)
}
/* Reserve the bootmap memory. */
reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(bootmap_start), bootmap_size);
reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(bootmap_start),
bootmap_size, BOOTMEM_DEFAULT);
printk(" reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
node_set_online(nid);
......@@ -281,7 +282,7 @@ setup_memory(void *kernel_end)
nid = kvaddr_to_nid(initrd_start);
reserve_bootmem_node(NODE_DATA(nid),
virt_to_phys((void *)initrd_start),
INITRD_SIZE);
INITRD_SIZE, BOOTMEM_DEFAULT);
}
}
#endif /* CONFIG_BLK_DEV_INITRD */
......
......@@ -239,7 +239,7 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
* Reserve the bootmem bitmap for this node.
*/
reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
boot_pages << PAGE_SHIFT);
boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
#ifdef CONFIG_BLK_DEV_INITRD
/*
......@@ -247,7 +247,7 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
*/
if (node == initrd_node) {
reserve_bootmem_node(pgdat, phys_initrd_start,
phys_initrd_size);
phys_initrd_size, BOOTMEM_DEFAULT);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
......
......@@ -605,9 +605,11 @@ void __init reserve_node_zero(pg_data_t *pgdat)
* Note that this can only be in node 0.
*/
#ifdef CONFIG_XIP_KERNEL
reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start);
reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start,
BOOTMEM_DEFAULT);
#else
reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext,
BOOTMEM_DEFAULT);
#endif
/*
......@@ -615,7 +617,7 @@ void __init reserve_node_zero(pg_data_t *pgdat)
* and can only be in node 0.
*/
reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
PTRS_PER_PGD * sizeof(pgd_t));
PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
/*
* Hmm... This should go elsewhere, but we really really need to
......@@ -638,8 +640,10 @@ void __init reserve_node_zero(pg_data_t *pgdat)
/* H1940 and RX3715 need to reserve this for suspend */
if (machine_is_h1940() || machine_is_rx3715()) {
reserve_bootmem_node(pgdat, 0x30003000, 0x1000);
reserve_bootmem_node(pgdat, 0x30081000, 0x1000);
reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
BOOTMEM_DEFAULT);
reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
BOOTMEM_DEFAULT);
}
#ifdef CONFIG_SA1111
......@@ -650,7 +654,8 @@ void __init reserve_node_zero(pg_data_t *pgdat)
res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
#endif
if (res_size)
reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
BOOTMEM_DEFAULT);
}
/*
......
......@@ -27,9 +27,11 @@ void __init reserve_node_zero(pg_data_t *pgdat)
* Note that this can only be in node 0.
*/
#ifdef CONFIG_XIP_KERNEL
reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start);
reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start,
BOOTMEM_DEFAULT);
#else
reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext,
BOOTMEM_DEFAULT);
#endif
/*
......@@ -37,7 +39,8 @@ void __init reserve_node_zero(pg_data_t *pgdat)
* some architectures which the DRAM is the exception vector to trap,
* alloc_page breaks with error, although it is not NULL, but "0."
*/
reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE);
reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
BOOTMEM_DEFAULT);
}
/*
......
......@@ -207,7 +207,7 @@ void __init omapfb_reserve_sdram(void)
return;
}
if (rg.paddr)
reserve_bootmem(rg.paddr, rg.size);
reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT);
reserved += rg.size;
omapfb_config.mem_desc.region[i] = rg;
configured_regions++;
......
......@@ -489,7 +489,8 @@ static void __init setup_bootmem(void)
/* Reserve space for the bootmem bitmap... */
reserve_bootmem_node(NODE_DATA(node),
PFN_PHYS(bootmap_pfn),
bootmap_size);
bootmap_size,
BOOTMEM_DEFAULT);
/* ...and any other reserved regions. */
for (res = reserved; res; res = res->sibling) {
......@@ -505,7 +506,8 @@ static void __init setup_bootmem(void)
&& res->end < PFN_PHYS(max_pfn))
reserve_bootmem_node(
NODE_DATA(node), res->start,
res->end - res->start + 1);
res->end - res->start + 1,
BOOTMEM_DEFAULT);
}
node_set_online(node);
......
......@@ -406,7 +406,7 @@ void __init setup_arch(char **cmdline_p)
*/
free_bootmem(memory_start, memory_end - memory_start);
reserve_bootmem(memory_start, bootmap_size);
reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
/*
* get kmalloc into gear
*/
......
......@@ -137,7 +137,7 @@ setup_arch(char **cmdline_p)
* Arguments are start, size
*/
reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size, BOOTMEM_DEFAULT);
/* paging_init() sets up the MMU and marks all pages as reserved */
......
......@@ -925,13 +925,15 @@ static void __init setup_linux_memory(void)
#endif
/* take back the memory occupied by the kernel image and the bootmem alloc map */
reserve_bootmem(kstart, kend - kstart + bootmap_size);
reserve_bootmem(kstart, kend - kstart + bootmap_size,
BOOTMEM_DEFAULT);
/* reserve the memory occupied by the initial ramdisk */
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
reserve_bootmem(INITRD_START, INITRD_SIZE,
BOOTMEM_DEFAULT);
initrd_start = INITRD_START + PAGE_OFFSET;
initrd_end = initrd_start + INITRD_SIZE;
}
......@@ -986,9 +988,10 @@ static void __init setup_uclinux_memory(void)
/* now take back the bits the core kernel is occupying */
#ifndef CONFIG_PROTECT_KERNEL
reserve_bootmem(kend, bootmap_size);
reserve_bootmem(kend, bootmap_size, BOOTMEM_DEFAULT);
reserve_bootmem((unsigned long) &__kernel_image_start,
kend - (unsigned long) &__kernel_image_start);
kend - (unsigned long) &__kernel_image_start,
BOOTMEM_DEFAULT);
#else
dampr = __get_DAMPR(0);
......@@ -996,14 +999,15 @@ static void __init setup_uclinux_memory(void)
dampr = (dampr >> 4) + 17;
dampr = 1 << dampr;
reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr);
reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr, BOOTMEM_DEFAULT);
#endif
/* reserve some memory to do uncached DMA through if requested */
#ifdef CONFIG_RESERVE_DMA_COHERENT
if (dma_coherent_mem_start)
reserve_bootmem(dma_coherent_mem_start,
dma_coherent_mem_end - dma_coherent_mem_start);
dma_coherent_mem_end - dma_coherent_mem_start,
BOOTMEM_DEFAULT);
#endif
} /* end setup_uclinux_memory() */
......
......@@ -173,7 +173,7 @@ void __init setup_arch(char **cmdline_p)
* the bootmem bitmap so we then reserve it after freeing it :-)
*/
free_bootmem(memory_start, memory_end - memory_start);
reserve_bootmem(memory_start, bootmap_size);
reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
/*
* get kmalloc into gear
*/
......
......@@ -218,7 +218,7 @@ find_memory (void)
/* Free all available memory, then mark bootmem-map as being in use. */
efi_memmap_walk(filter_rsvd_memory, free_bootmem);
reserve_bootmem(bootmap_start, bootmap_size);
reserve_bootmem(bootmap_start, bootmap_size, BOOTMEM_DEFAULT);
find_initrd();
......
......@@ -299,12 +299,12 @@ static void __init reserve_pernode_space(void)
pages = bdp->node_low_pfn - (bdp->node_boot_start>>PAGE_SHIFT);
size = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
base = __pa(bdp->node_bootmem_map);
reserve_bootmem_node(pdp, base, size);
reserve_bootmem_node(pdp, base, size, BOOTMEM_DEFAULT);
/* Now the per-node space */
size = mem_data[node].pernode_size;
base = __pa(mem_data[node].pernode_addr);
reserve_bootmem_node(pdp, base, size);
reserve_bootmem_node(pdp, base, size, BOOTMEM_DEFAULT);
}
}
......
......@@ -177,25 +177,28 @@ static unsigned long __init setup_memory(void)
*/
reserve_bootmem(CONFIG_MEMORY_START + PAGE_SIZE,
(PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE - 1)
- CONFIG_MEMORY_START);
- CONFIG_MEMORY_START,
BOOTMEM_DEFAULT);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
* enabling clean reboots, SMP operation, laptop functions.
*/
reserve_bootmem(CONFIG_MEMORY_START, PAGE_SIZE);
reserve_bootmem(CONFIG_MEMORY_START, PAGE_SIZE, BOOTMEM_DEFAULT);
/*
* reserve memory hole
*/
#ifdef CONFIG_MEMHOLE
reserve_bootmem(CONFIG_MEMHOLE_START, CONFIG_MEMHOLE_SIZE);
reserve_bootmem(CONFIG_MEMHOLE_START, CONFIG_MEMHOLE_SIZE,
BOOTMEM_DEFAULT);
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
reserve_bootmem(INITRD_START, INITRD_SIZE,
BOOTMEM_DEFAULT);
initrd_start = INITRD_START + PAGE_OFFSET;
initrd_end = initrd_start + INITRD_SIZE;
printk("initrd:start[%08lx],size[%08lx]\n",
......
......@@ -91,7 +91,8 @@ unsigned long __init setup_memory(void)
PFN_PHYS(mp->pages));
reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size);
PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size,
BOOTMEM_DEFAULT);
if (max_low_pfn < max_pfn)
max_low_pfn = max_pfn;
......@@ -104,7 +105,7 @@ unsigned long __init setup_memory(void)
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
reserve_bootmem_node(NODE_DATA(0), INITRD_START,
INITRD_SIZE);
INITRD_SIZE, BOOTMEM_DEFAULT);
initrd_start = INITRD_START + PAGE_OFFSET;
initrd_end = initrd_start + INITRD_SIZE;
printk("initrd:start[%08lx],size[%08lx]\n",
......
......@@ -154,7 +154,7 @@ void __init atari_stram_reserve_pages(void *start_mem)
/* always reserve first page of ST-RAM, the first 2 kB are
* supervisor-only! */
if (!kernel_in_stram)
reserve_bootmem (0, PAGE_SIZE);
reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
}
......
......@@ -323,7 +323,8 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_BLK_DEV_INITRD
if (m68k_ramdisk.size) {
reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
m68k_ramdisk.addr, m68k_ramdisk.size);
m68k_ramdisk.addr, m68k_ramdisk.size,
BOOTMEM_DEFAULT);
initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
initrd_end = initrd_start + m68k_ramdisk.size;
printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
......
......@@ -203,7 +203,7 @@ void __init setup_arch(char **cmdline_p)
* the bootmem bitmap so we then reserve it after freeing it :-)
*/
free_bootmem(memory_start, memory_end - memory_start);
reserve_bootmem(memory_start, bootmap_size);
reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
/*
* Get kmalloc into gear.
......
......@@ -232,7 +232,7 @@ static void __init finalize_initrd(void)
goto disable;
}
reserve_bootmem(__pa(initrd_start), size);
reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
initrd_below_start_ok = 1;
printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n",
......@@ -413,7 +413,7 @@ static void __init bootmem_init(void)
/*
* Reserve the bootmap memory.
*/
reserve_bootmem(PFN_PHYS(mapstart), bootmap_size);
reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT);
/*
* Reserve initrd memory if needed.
......
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