From: "Jan Beulich" <JBeulich@novell.com>
To: xen-devel@lists.xensource.com
Cc: xen-ia64-devel@lists.xensource.com
Subject: [PATCH] support Linux' advanced crashkernel= syntax (v2)
Date: Mon, 26 Apr 2010 09:00:10 +0100 [thread overview]
Message-ID: <4BD5642A020000780003C16B@vpn.id2.novell.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 5490 bytes --]
Quoting the original Linux patch's description:
"This patch adds a extended crashkernel syntax that makes the value of
reserved system RAM dependent on the system RAM itself:
crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
range=start-[end]
For example:
crashkernel=512M-2G:64M,2G-:128M
The motivation comes from distributors that configure their
crashkernel command line automatically with some configuration tool
(YaST, you know ;)). Of course that tool knows the value of System
RAM, but if the user removes RAM, then the system becomes unbootable
or at least unusable and error handling is very difficult."
For x86, other than Linux we pass the actual amount of RAM rather than
the highest page's address (to cope with sparse physical address maps).
This still needs to be hooked up for ia64.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- 2010-04-22.orig/xen/arch/x86/setup.c 2010-04-23 00:00:00.000000000 +0200
+++ 2010-04-22/xen/arch/x86/setup.c 2010-04-26 08:52:06.000000000 +0200
@@ -643,6 +643,11 @@ void __init __start_xen(unsigned long mb
memcpy(&boot_e820, &e820, sizeof(e820));
/* Early kexec reservation (explicit static start address). */
+ nr_pages = 0;
+ for ( i = 0; i < e820.nr_map; i++ )
+ if ( e820.map[i].type == E820_RAM )
+ nr_pages += e820.map[i].size >> PAGE_SHIFT;
+ set_kexec_crash_area_size((u64)nr_pages << PAGE_SHIFT);
kexec_reserve_area(&boot_e820);
/*
--- 2010-04-22.orig/xen/common/kexec.c 2010-01-13 18:58:11.000000000 +0100
+++ 2010-04-22/xen/common/kexec.c 2010-04-26 09:52:29.000000000 +0200
@@ -47,15 +47,109 @@ static unsigned char vmcoreinfo_data[VMC
static size_t vmcoreinfo_size = 0;
xen_kexec_reserve_t kexec_crash_area;
+static struct {
+ u64 start, end;
+ unsigned long size;
+} ranges[16] __initdata;
+/*
+ * Parse command lines in the format
+ *
+ * crashkernel=<ramsize-range>:<size>[,...][@<offset>]
+ *
+ * with <ramsize-range> being of form
+ *
+ * <start>-[<end>]
+ *
+ * as well as the legacy ones in the format
+ *
+ * crashkernel=<size>[@<offset>]
+ */
static void __init parse_crashkernel(const char *str)
{
- kexec_crash_area.size = parse_size_and_unit(str, &str);
- if ( *str == '@' )
- kexec_crash_area.start = parse_size_and_unit(str+1, NULL);
+ const char *cur;
+
+ if ( strchr(str, ':' ) )
+ {
+ unsigned int idx = 0;
+
+ do {
+ if ( idx >= ARRAY_SIZE(ranges) )
+ {
+ printk(XENLOG_WARNING "crashkernel: too many ranges\n");
+ cur = NULL;
+ str = strchr(str, '@');
+ break;
+ }
+
+ ranges[idx].start = parse_size_and_unit(cur = str + !!idx, &str);
+ if ( cur == str )
+ break;
+
+ if ( *str != '-' )
+ {
+ printk(XENLOG_WARNING "crashkernel: '-' expected\n");
+ break;
+ }
+
+ if ( *++str != ':' )
+ {
+ ranges[idx].end = parse_size_and_unit(cur = str, &str);
+ if ( cur == str )
+ break;
+ if ( ranges[idx].end <= ranges[idx].start )
+ {
+ printk(XENLOG_WARNING "crashkernel: end <= start\n");
+ break;
+ }
+ }
+ else
+ ranges[idx].end = -1;
+
+ if ( *str != ':' )
+ {
+ printk(XENLOG_WARNING "crashkernel: ':' expected\n");
+ break;
+ }
+
+ ranges[idx].size = parse_size_and_unit(cur = str + 1, &str);
+ if ( cur == str )
+ break;
+
+ ++idx;
+ } while ( *str == ',' );
+ if ( idx < ARRAY_SIZE(ranges) )
+ ranges[idx].size = 0;
+ }
+ else
+ kexec_crash_area.size = parse_size_and_unit(cur = str, &str);
+ if ( cur != str && *str == '@' )
+ kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str);
+ if ( cur == str )
+ printk(XENLOG_WARNING "crashkernel: memory value expected\n");
}
custom_param("crashkernel", parse_crashkernel);
+void __init set_kexec_crash_area_size(u64 system_ram)
+{
+ unsigned int idx;
+
+ for ( idx = 0; idx < ARRAY_SIZE(ranges) && !kexec_crash_area.size; ++idx )
+ {
+ if ( !ranges[idx].size )
+ break;
+
+ if ( ranges[idx].size >= system_ram )
+ {
+ printk(XENLOG_WARNING "crashkernel: invalid size\n");
+ continue;
+ }
+
+ if ( ranges[idx].start <= system_ram && ranges[idx].end > system_ram )
+ kexec_crash_area.size = ranges[idx].size;
+ }
+}
+
static void one_cpu_only(void)
{
/* Only allow the first cpu to continue - force other cpus to spin */
--- 2010-04-22.orig/xen/include/xen/kexec.h 2010-01-13 18:58:11.000000000 +0100
+++ 2010-04-22/xen/include/xen/kexec.h 2010-04-26 08:43:26.000000000 +0200
@@ -12,6 +12,8 @@ typedef struct xen_kexec_reserve {
extern xen_kexec_reserve_t kexec_crash_area;
+void set_kexec_crash_area_size(u64 system_ram);
+
/* We have space for 4 images to support atomic update
* of images. This is important for CRASH images since
* a panic can happen at any time...
[-- Attachment #2: crashkernel-advanced.patch --]
[-- Type: text/plain, Size: 5486 bytes --]
Quoting the original Linux patch's description:
"This patch adds a extended crashkernel syntax that makes the value of
reserved system RAM dependent on the system RAM itself:
crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
range=start-[end]
For example:
crashkernel=512M-2G:64M,2G-:128M
The motivation comes from distributors that configure their
crashkernel command line automatically with some configuration tool
(YaST, you know ;)). Of course that tool knows the value of System
RAM, but if the user removes RAM, then the system becomes unbootable
or at least unusable and error handling is very difficult."
For x86, other than Linux we pass the actual amount of RAM rather than
the highest page's address (to cope with sparse physical address maps).
This still needs to be hooked up for ia64.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- 2010-04-22.orig/xen/arch/x86/setup.c 2010-04-23 00:00:00.000000000 +0200
+++ 2010-04-22/xen/arch/x86/setup.c 2010-04-26 08:52:06.000000000 +0200
@@ -643,6 +643,11 @@ void __init __start_xen(unsigned long mb
memcpy(&boot_e820, &e820, sizeof(e820));
/* Early kexec reservation (explicit static start address). */
+ nr_pages = 0;
+ for ( i = 0; i < e820.nr_map; i++ )
+ if ( e820.map[i].type == E820_RAM )
+ nr_pages += e820.map[i].size >> PAGE_SHIFT;
+ set_kexec_crash_area_size((u64)nr_pages << PAGE_SHIFT);
kexec_reserve_area(&boot_e820);
/*
--- 2010-04-22.orig/xen/common/kexec.c 2010-01-13 18:58:11.000000000 +0100
+++ 2010-04-22/xen/common/kexec.c 2010-04-26 09:52:29.000000000 +0200
@@ -47,15 +47,109 @@ static unsigned char vmcoreinfo_data[VMC
static size_t vmcoreinfo_size = 0;
xen_kexec_reserve_t kexec_crash_area;
+static struct {
+ u64 start, end;
+ unsigned long size;
+} ranges[16] __initdata;
+/*
+ * Parse command lines in the format
+ *
+ * crashkernel=<ramsize-range>:<size>[,...][@<offset>]
+ *
+ * with <ramsize-range> being of form
+ *
+ * <start>-[<end>]
+ *
+ * as well as the legacy ones in the format
+ *
+ * crashkernel=<size>[@<offset>]
+ */
static void __init parse_crashkernel(const char *str)
{
- kexec_crash_area.size = parse_size_and_unit(str, &str);
- if ( *str == '@' )
- kexec_crash_area.start = parse_size_and_unit(str+1, NULL);
+ const char *cur;
+
+ if ( strchr(str, ':' ) )
+ {
+ unsigned int idx = 0;
+
+ do {
+ if ( idx >= ARRAY_SIZE(ranges) )
+ {
+ printk(XENLOG_WARNING "crashkernel: too many ranges\n");
+ cur = NULL;
+ str = strchr(str, '@');
+ break;
+ }
+
+ ranges[idx].start = parse_size_and_unit(cur = str + !!idx, &str);
+ if ( cur == str )
+ break;
+
+ if ( *str != '-' )
+ {
+ printk(XENLOG_WARNING "crashkernel: '-' expected\n");
+ break;
+ }
+
+ if ( *++str != ':' )
+ {
+ ranges[idx].end = parse_size_and_unit(cur = str, &str);
+ if ( cur == str )
+ break;
+ if ( ranges[idx].end <= ranges[idx].start )
+ {
+ printk(XENLOG_WARNING "crashkernel: end <= start\n");
+ break;
+ }
+ }
+ else
+ ranges[idx].end = -1;
+
+ if ( *str != ':' )
+ {
+ printk(XENLOG_WARNING "crashkernel: ':' expected\n");
+ break;
+ }
+
+ ranges[idx].size = parse_size_and_unit(cur = str + 1, &str);
+ if ( cur == str )
+ break;
+
+ ++idx;
+ } while ( *str == ',' );
+ if ( idx < ARRAY_SIZE(ranges) )
+ ranges[idx].size = 0;
+ }
+ else
+ kexec_crash_area.size = parse_size_and_unit(cur = str, &str);
+ if ( cur != str && *str == '@' )
+ kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str);
+ if ( cur == str )
+ printk(XENLOG_WARNING "crashkernel: memory value expected\n");
}
custom_param("crashkernel", parse_crashkernel);
+void __init set_kexec_crash_area_size(u64 system_ram)
+{
+ unsigned int idx;
+
+ for ( idx = 0; idx < ARRAY_SIZE(ranges) && !kexec_crash_area.size; ++idx )
+ {
+ if ( !ranges[idx].size )
+ break;
+
+ if ( ranges[idx].size >= system_ram )
+ {
+ printk(XENLOG_WARNING "crashkernel: invalid size\n");
+ continue;
+ }
+
+ if ( ranges[idx].start <= system_ram && ranges[idx].end > system_ram )
+ kexec_crash_area.size = ranges[idx].size;
+ }
+}
+
static void one_cpu_only(void)
{
/* Only allow the first cpu to continue - force other cpus to spin */
--- 2010-04-22.orig/xen/include/xen/kexec.h 2010-01-13 18:58:11.000000000 +0100
+++ 2010-04-22/xen/include/xen/kexec.h 2010-04-26 08:43:26.000000000 +0200
@@ -12,6 +12,8 @@ typedef struct xen_kexec_reserve {
extern xen_kexec_reserve_t kexec_crash_area;
+void set_kexec_crash_area_size(u64 system_ram);
+
/* We have space for 4 images to support atomic update
* of images. This is important for CRASH images since
* a panic can happen at any time...
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
reply other threads:[~2010-04-26 8:00 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=4BD5642A020000780003C16B@vpn.id2.novell.com \
--to=jbeulich@novell.com \
--cc=xen-devel@lists.xensource.com \
--cc=xen-ia64-devel@lists.xensource.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;
as well as URLs for NNTP newsgroup(s).