Commit 44280733 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar

x86: Change crash kernel to reserve via reserve_early()

use find_e820_area()/reserve_early() instead.

-v2: address Eric's request, to restore original semantics.
     will fail, if the provided address can not be used.
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Acked-by: default avatarEric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <4B09E2F9.7040403@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 350f8f56
...@@ -487,42 +487,11 @@ static void __init reserve_early_setup_data(void) ...@@ -487,42 +487,11 @@ static void __init reserve_early_setup_data(void)
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
/**
* Reserve @size bytes of crashkernel memory at any suitable offset.
*
* @size: Size of the crashkernel memory to reserve.
* Returns the base address on success, and -1ULL on failure.
*/
static
unsigned long long __init find_and_reserve_crashkernel(unsigned long long size)
{
const unsigned long long alignment = 16<<20; /* 16M */
unsigned long long start = 0LL;
while (1) {
int ret;
start = find_e820_area(start, ULONG_MAX, size, alignment);
if (start == -1ULL)
return start;
/* try to reserve it */
ret = reserve_bootmem_generic(start, size, BOOTMEM_EXCLUSIVE);
if (ret >= 0)
return start;
start += alignment;
}
}
static inline unsigned long long get_total_mem(void) static inline unsigned long long get_total_mem(void)
{ {
unsigned long long total; unsigned long long total;
total = max_low_pfn - min_low_pfn; total = max_pfn - min_low_pfn;
#ifdef CONFIG_HIGHMEM
total += highend_pfn - highstart_pfn;
#endif
return total << PAGE_SHIFT; return total << PAGE_SHIFT;
} }
...@@ -542,21 +511,25 @@ static void __init reserve_crashkernel(void) ...@@ -542,21 +511,25 @@ static void __init reserve_crashkernel(void)
/* 0 means: find the address automatically */ /* 0 means: find the address automatically */
if (crash_base <= 0) { if (crash_base <= 0) {
crash_base = find_and_reserve_crashkernel(crash_size); const unsigned long long alignment = 16<<20; /* 16M */
crash_base = find_e820_area(alignment, ULONG_MAX, crash_size,
alignment);
if (crash_base == -1ULL) { if (crash_base == -1ULL) {
pr_info("crashkernel reservation failed. " pr_info("crashkernel reservation failed - No suitable area found.\n");
"No suitable area found.\n");
return; return;
} }
} else { } else {
ret = reserve_bootmem_generic(crash_base, crash_size, unsigned long long start;
BOOTMEM_EXCLUSIVE);
if (ret < 0) { start = find_e820_area(crash_base, ULONG_MAX, crash_size,
pr_info("crashkernel reservation failed - " 1<<20);
"memory is in use\n"); if (start != crash_base) {
pr_info("crashkernel reservation failed - memory is in use.\n");
return; return;
} }
} }
reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL");
printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
"for crashkernel (System RAM: %ldMB)\n", "for crashkernel (System RAM: %ldMB)\n",
...@@ -927,6 +900,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -927,6 +900,8 @@ void __init setup_arch(char **cmdline_p)
reserve_initrd(); reserve_initrd();
reserve_crashkernel();
vsmp_init(); vsmp_init();
io_delay_init(); io_delay_init();
...@@ -957,8 +932,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -957,8 +932,6 @@ void __init setup_arch(char **cmdline_p)
*/ */
find_smp_config(); find_smp_config();
reserve_crashkernel();
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
/* /*
* dma32_reserve_bootmem() allocates bootmem which may conflict * dma32_reserve_bootmem() allocates bootmem which may conflict
......
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