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

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
Loading
Loading
Loading
Loading
+15 −42
Original line number Original line Diff line number Diff line
@@ -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)


	/* 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)


	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)
	 */
	 */
	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