From: Youling Tang <youling.tang@linux.dev>
To: Andrew Morton <akpm@linux-foundation.org>,
Baoquan He <bhe@redhat.com>, Jonathan Corbet <corbet@lwn.net>
Cc: Vivek Goyal <vgoyal@redhat.com>, Dave Young <dyoung@redhat.com>,
kexec@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, youling.tang@linux.dev,
Youling Tang <tangyouling@kylinos.cn>
Subject: [PATCH] crash: Support high memory reservation for range syntax
Date: Sat, 4 Apr 2026 15:41:03 +0800 [thread overview]
Message-ID: <20260404074103.506793-1-youling.tang@linux.dev> (raw)
From: Youling Tang <tangyouling@kylinos.cn>
The crashkernel range syntax (range1:size1[,range2:size2,...]) allows
automatic size selection based on system RAM, but it always reserves
from low memory. When a large crashkernel is selected, this can
consume most of the low memory, causing subsequent hardware
hotplug or drivers requiring low memory to fail due to allocation
failures.
Add a new optional conditional suffix ",>boundary" to the crashkernel
range syntax. When the selected crashkernel size exceeds the specified
boundary, the kernel will automatically apply the same reservation
policy as "crashkernel=size,high" - preferring high memory first
and reserving the default low memory area.
Syntax:
crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset],>boundary
Example:
crashkernel=2G-16G:512M,16G-:1G,>512M
This means:
- For 2G-16G RAM: reserve 512M normally
- For >16G RAM: reserve 1G with high memory preference (since 1G > 512M)
For systems with >16G RAM, 1G is selected which exceeds 512M, so it
will be reserved from high memory instead of consuming 1G of
precious low memory.
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
Documentation/admin-guide/kdump/kdump.rst | 25 ++++++++-
.../admin-guide/kernel-parameters.txt | 2 +-
kernel/crash_reserve.c | 56 ++++++++++++++++---
3 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index 7587caadbae1..b5ae4556e9ca 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -293,7 +293,28 @@ crashkernel syntax
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
-3) crashkernel=size,high and crashkernel=size,low
+3) range1:size1[,range2:size2,...][@offset],>boundary
+ Optionally, the range list can be followed by a conditional suffix
+ `,>boundary`. When the selected crashkernel size matches the
+ condition, the kernel will reserve memory using the same policy as
+ `crashkernel=size,high` (i.e. prefer high memory first and reserve the
+ default low memory area).
+
+ The syntax is::
+
+ crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset],>boundary
+ range=start-[end]
+
+ For example::
+
+ crashkernel=2G-16G:512M,16G-:1G,>512M
+
+ This would mean:
+ 1) if the RAM size is between 2G and 16G (exclusive), then reserve 512M.
+ 2) if the RAM size is larger than 16G, allocation will behave like
+ `crashkernel=1G,high`.
+
+4) crashkernel=size,high and crashkernel=size,low
If memory above 4G is preferred, crashkernel=size,high can be used to
fulfill that. With it, physical memory is allowed to be allocated from top,
@@ -311,7 +332,7 @@ crashkernel syntax
crashkernel=0,low
-4) crashkernel=size,cma
+5) crashkernel=size,cma
Reserve additional crash kernel memory from CMA. This reservation is
usable by the first system's userspace memory and kernel movable
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 03a550630644..b2e1892ab4d8 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1087,7 +1087,7 @@ Kernel parameters
4G when '@offset' hasn't been specified.
See Documentation/admin-guide/kdump/kdump.rst for further details.
- crashkernel=range1:size1[,range2:size2,...][@offset]
+ crashkernel=range1:size1[,range2:size2,...][@offset][,>boundary]
[KNL] Same as above, but depends on the memory
in the running system. The syntax of range is
start-[end] where start and end are both
diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
index 62e60e0223cf..917738412390 100644
--- a/kernel/crash_reserve.c
+++ b/kernel/crash_reserve.c
@@ -254,15 +254,47 @@ static __init char *get_last_crashkernel(char *cmdline,
return ck_cmdline;
}
+/*
+ * This function parses command lines in the format
+ *
+ * crashkernel=ramsize-range:size[,...][@offset],>boundary
+ */
+static void __init parse_crashkernel_boundary(char *ck_cmdline,
+ unsigned long long *boundary)
+{
+ char *cur = ck_cmdline, *next;
+ char *first_gt = false;
+
+ first_gt = strchr(cur, '>');
+ if (!first_gt)
+ return;
+
+ cur = first_gt + 1;
+ if (*cur == '\0' || *cur == ' ' || *cur == ',') {
+ pr_warn("crashkernel: '>' specified without boundary size, ignoring\n");
+ return;
+ }
+
+ *boundary = memparse(cur, &next);
+ if (cur == next) {
+ pr_warn("crashkernel: invalid boundary size after '>'\n");
+ return;
+ }
+}
+
static int __init __parse_crashkernel(char *cmdline,
unsigned long long system_ram,
unsigned long long *crash_size,
unsigned long long *crash_base,
- const char *suffix)
+ const char *suffix,
+ bool *high,
+ unsigned long long *low_size)
{
char *first_colon, *first_space;
char *ck_cmdline;
char *name = "crashkernel=";
+ unsigned long long boundary = 0;
+ int ret;
BUG_ON(!crash_size || !crash_base);
*crash_size = 0;
@@ -283,10 +315,20 @@ static int __init __parse_crashkernel(char *cmdline,
*/
first_colon = strchr(ck_cmdline, ':');
first_space = strchr(ck_cmdline, ' ');
- if (first_colon && (!first_space || first_colon < first_space))
- return parse_crashkernel_mem(ck_cmdline, system_ram,
+ if (first_colon && (!first_space || first_colon < first_space)) {
+ ret = parse_crashkernel_mem(ck_cmdline, system_ram,
crash_size, crash_base);
+ /* Handle optional ',>boundary' condition for range ':' syntax only. */
+ parse_crashkernel_boundary(ck_cmdline, &boundary);
+ if (!ret && *crash_size > boundary) {
+ *high = true;
+ *low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
+ }
+
+ return ret;
+ }
+
return parse_crashkernel_simple(ck_cmdline, crash_size, crash_base);
}
@@ -310,7 +352,7 @@ int __init parse_crashkernel(char *cmdline,
/* crashkernel=X[@offset] */
ret = __parse_crashkernel(cmdline, system_ram, crash_size,
- crash_base, NULL);
+ crash_base, NULL, high, low_size);
#ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
/*
* If non-NULL 'high' passed in and no normal crashkernel
@@ -318,7 +360,7 @@ int __init parse_crashkernel(char *cmdline,
*/
if (high && ret == -ENOENT) {
ret = __parse_crashkernel(cmdline, 0, crash_size,
- crash_base, suffix_tbl[SUFFIX_HIGH]);
+ crash_base, suffix_tbl[SUFFIX_HIGH], high, low_size);
if (ret || !*crash_size)
return -EINVAL;
@@ -327,7 +369,7 @@ int __init parse_crashkernel(char *cmdline,
* is not allowed.
*/
ret = __parse_crashkernel(cmdline, 0, low_size,
- crash_base, suffix_tbl[SUFFIX_LOW]);
+ crash_base, suffix_tbl[SUFFIX_LOW], high, low_size);
if (ret == -ENOENT) {
*low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
ret = 0;
@@ -344,7 +386,7 @@ int __init parse_crashkernel(char *cmdline,
*/
if (cma_size)
__parse_crashkernel(cmdline, 0, cma_size,
- &cma_base, suffix_tbl[SUFFIX_CMA]);
+ &cma_base, suffix_tbl[SUFFIX_CMA], high, low_size);
#endif
if (!*crash_size)
ret = -EINVAL;
--
2.43.0
reply other threads:[~2026-04-04 7:42 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260404074103.506793-1-youling.tang@linux.dev \
--to=youling.tang@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=bhe@redhat.com \
--cc=corbet@lwn.net \
--cc=dyoung@redhat.com \
--cc=kexec@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tangyouling@kylinos.cn \
--cc=vgoyal@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox