[PATCH ] kernel/crash_core.c - Add crashkernel=auto for x86 and Arm

From: John Donnelly
Date: Wed Dec 04 2019 - 14:22:35 EST


This adds crashkernel=auto feature to configure reserved memory for
vmcore creation to both x86 and Arm platform as implemenented in
RH 4.18.0-147.el8 kernels. The values have been adjusted for x86 and
Arm based from 5.4.0 kernel crash testing.

Signed-off-by: John Donnelly <john.p.donnelly@xxxxxxxxxx>
Tested-by: John Donnelly <john.p.donnelly@xxxxxxxxxx>
---
Documentation/admin-guide/kdump/kdump.rst | 12 ++++++++++
kernel/crash_core.c | 28 +++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index ac7e131d2935..7635bbb4ab34 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -285,6 +285,18 @@ This would mean:
2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M
3) if the RAM size is larger than 2G, then reserve 128M

+Or you can use crashkernel=auto if you have enough memory. The threshold
+is 1G on x86_64, 2G on arm64, ppc64 and ppc64le. The threshold is 4G for s390x.
+If your system memory is less than the threshold crashkernel=auto will not
+reserve memory.
+
+The automatically reserved memory size varies based on architecture.
+The size changes according to system memory size like below:
+ x86_64: 1G-64G:160M,64G-1T:280M,1T-:512M
+ s390x: 4G-64G:160M,64G-1T:256M,1T-:512M
+ arm64: 2G-:768M
+ ppc64: 2G-4G:384M,4G-16G:512M,16G-64G:1G,64G-128G:2G,128G-:4G
+


Boot into System Kernel
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 9f1557b98468..564aca60e57f 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -7,6 +7,7 @@
#include <linux/crash_core.h>
#include <linux/utsname.h>
#include <linux/vmalloc.h>
+#include <linux/kexec.h>

#include <asm/page.h>
#include <asm/sections.h>
@@ -39,6 +40,15 @@ static int __init parse_crashkernel_mem(char *cmdline,
unsigned long long *crash_base)
{
char *cur = cmdline, *tmp;
+ unsigned long long total_mem = system_ram;
+
+ /*
+ * Firmware sometimes reserves some memory regions for it's own use.
+ * so we get less than actual system memory size.
+ * Workaround this by round up the total size to 128M which is
+ * enough for most test cases.
+ */
+ total_mem = roundup(total_mem, SZ_128M);

/* for each entry of the comma-separated list */
do {
@@ -83,13 +93,13 @@ static int __init parse_crashkernel_mem(char *cmdline,
return -EINVAL;
}
cur = tmp;
- if (size >= system_ram) {
+ if (size >= total_mem) {
pr_warn("crashkernel: invalid size\n");
return -EINVAL;
}

/* match ? */
- if (system_ram >= start && system_ram < end) {
+ if (total_mem >= start && total_mem < end) {
*crash_size = size;
break;
}
@@ -248,6 +258,20 @@ static int __init __parse_crashkernel(char *cmdline,
if (suffix)
return parse_crashkernel_suffix(ck_cmdline, crash_size,
suffix);
+
+ if (strncmp(ck_cmdline, "auto", 4) == 0) {
+#ifdef CONFIG_X86_64
+ ck_cmdline = "1G-64G:160M,64G-1T:280M,1T-:512M";
+#elif defined(CONFIG_S390)
+ ck_cmdline = "4G-64G:160M,64G-1T:256M,1T-:512M";
+#elif defined(CONFIG_ARM64)
+ ck_cmdline = "2G-:768M";
+#elif defined(CONFIG_PPC64)
+ ck_cmdline = "2G-4G:384M,4G-16G:512M,16G-64G:1G,64G-128G:2G,128G-:4G";
+#endif
+ pr_info("Using crashkernel=auto, the size chosen is a best effort estimation.\n");
+ }
+
/*
* if the commandline contains a ':', then that's the extended
* syntax -- if not, it must be the classic syntax
--
2.20.1