From 6fe42bdfec3578914821f5f937ca1914d4726fa6 Mon Sep 17 00:00:00 2001 From: Brian Maly Date: Thu, 15 Jan 2015 18:32:51 -0500 Subject: [PATCH] x86: add support for crashkernel=auto This patch adds support for "crashkernel=auto" and was backported from RHEL7. Orabug: 20351819 Signed-off-by: Brian Maly Signed-off-by: Guangyu Sun Signed-off-by: Santosh Shilimkar --- Documentation/kdump/kdump.txt | 9 +++++ arch/x86/Kconfig | 13 ++++++++ arch/x86/configs/x86_64_defconfig | 1 + arch/x86/include/asm/kexec.h | 12 +++++++ kernel/kexec.c | 55 +++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+) diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index bc4bd5a44b88..e237d12691f1 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt @@ -150,6 +150,15 @@ System kernel config options analysis tools require a vmlinux with debug symbols in order to read and analyze a dump file. +4) Enable "automatically reserve memory for kexec kernel" in + "Processor type and features." + + CONFIG_KEXEC_AUTO_RESERVE=y + + This will let you to use "crashkernel=auto", instead of specifying + numbers for "crashkernel=". Note, you need to have enough memory. + The threshold and reserved memory size are arch-dependent. + Dump-capture kernel config options (Arch Independent) ----------------------------------------------------- diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 226d5696e1d1..c925927b8866 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1763,6 +1763,19 @@ config KEXEC_BZIMAGE_VERIFY_SIG ---help--- Enable bzImage signature verification support. +config KEXEC_AUTO_RESERVE + bool "automatically reserve memory for kexec kernel" + depends on KEXEC + default y + ---help--- + Automatically reserve memory for a kexec kernel, so that you don't + need to specify numbers for the "crashkernel=X@Y" boot option, + instead you can use "crashkernel=auto". To make this work, you need + to have more than 4G memory. + + On x86_32, 128M is reserved, on x86_64 1/32 of your memory is + reserved, but it will not exceed 4G. + config CRASH_DUMP bool "kernel crash dumps" depends on X86_64 || (X86_32 && HIGHMEM) diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 315b86106572..f4d8930beaff 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -54,6 +54,7 @@ CONFIG_X86_CHECK_BIOS_CORRUPTION=y CONFIG_EFI=y CONFIG_HZ_1000=y CONFIG_KEXEC=y +CONFIG_KEXEC_AUTO_RESERVE=y CONFIG_CRASH_DUMP=y # CONFIG_COMPAT_VDSO is not set CONFIG_HIBERNATION=y diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h index d2434c1cad05..1b63c2481be8 100644 --- a/arch/x86/include/asm/kexec.h +++ b/arch/x86/include/asm/kexec.h @@ -214,3 +214,15 @@ extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_KEXEC_H */ + +#ifdef CONFIG_KEXEC_AUTO_RESERVE + +#ifndef KEXEC_AUTO_RESERVED_SIZE +#define KEXEC_AUTO_RESERVED_SIZE (1ULL<<28) /* 256M */ +#endif +#ifndef KEXEC_AUTO_THRESHOLD +#define KEXEC_AUTO_THRESHOLD (1ULL<<31) /* 2G */ +#endif + + +#endif /* CONFIG_KEXEC_AUTO_RESERVE */ diff --git a/kernel/kexec.c b/kernel/kexec.c index 7a36fdcca5bf..77c50a15e197 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -1749,6 +1750,44 @@ static __initdata char *suffix_tbl[] = { [SUFFIX_NULL] = NULL, }; +#ifdef CONFIG_KEXEC_AUTO_RESERVE +#ifndef arch_default_crash_size +unsigned long long __init arch_default_crash_size(unsigned long long total_size) +{ + /* + * BIOS usually will reserve some memory regions for it's own use. + * so we will get less than actual memory in e820 usable areas. + * We workaround this by round up the total size to 128M which is + * enough for our current 2G kdump auto reserve threshold. + */ + if (roundup(total_size, 0x8000000) < KEXEC_AUTO_THRESHOLD) { + return 0; + + } else { + /* + * Filtering logic in kdump initrd requires 2bits per 4K page. + * Hence reserve 2bits per 4K of RAM (or 1byte per 16K of RAM) + * on top of base of 128M (KEXEC_AUTO_RESERVED_SIZE). + */ + return KEXEC_AUTO_RESERVED_SIZE + + roundup((total_size - KEXEC_AUTO_RESERVED_SIZE) + / (1ULL<<14), 1ULL<<20); + } +} +#define arch_default_crash_size arch_default_crash_size +#endif + +#ifndef arch_default_crash_base +unsigned long long __init arch_default_crash_base(void) +{ + /* 0 means find the base address automatically. */ + return 0; +} +#define arch_default_crash_base arch_default_crash_base +#endif + +#endif /*CONFIG_KEXEC_AUTO_RESERVE*/ + /* * That function parses "suffix" crashkernel command lines like * @@ -1847,6 +1886,22 @@ static int __init __parse_crashkernel(char *cmdline, if (suffix) return parse_crashkernel_suffix(ck_cmdline, crash_size, suffix); +#ifdef CONFIG_KEXEC_AUTO_RESERVE + if (strncmp(ck_cmdline, "auto", 4) == 0) { + unsigned long long size; + + size = arch_default_crash_size(system_ram); + if (size != 0) { + *crash_size = size; + *crash_base = arch_default_crash_base(); + return 0; + + } else { + pr_warn("crashkernel=auto resulted in zero bytes of reserved memory.\n"); + return -ENOMEM; + } + } +#endif /* * if the commandline contains a ':', then that's the extended * syntax -- if not, it must be the classic syntax -- 2.50.1