[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Support Linux's advanced crashkernel= syntax



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1272280332 -3600
# Node ID 3ce824963dc41827bdf1617b37a40e5e5e9dce29
# Parent  d01ea51fc929c57c7d5f427e1aafa0de7a436473
Support Linux's advanced crashkernel= syntax

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=3D<range1>:<size1>[,<range2>:<size2>,...][@offset]
    range=3Dstart-[end]

 For example:

    crashkernel=3D512M-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@xxxxxxxxxx>
---
 xen/arch/x86/setup.c    |    5 ++
 xen/common/kexec.c      |  102 ++++++++++++++++++++++++++++++++++++++++++++++--
 xen/include/xen/kexec.h |    2 
 3 files changed, 105 insertions(+), 4 deletions(-)

diff -r d01ea51fc929 -r 3ce824963dc4 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Mon Apr 26 12:11:30 2010 +0100
+++ b/xen/arch/x86/setup.c      Mon Apr 26 12:12:12 2010 +0100
@@ -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);
 
     /*
diff -r d01ea51fc929 -r 3ce824963dc4 xen/common/kexec.c
--- a/xen/common/kexec.c        Mon Apr 26 12:11:30 2010 +0100
+++ b/xen/common/kexec.c        Mon Apr 26 12:12:12 2010 +0100
@@ -47,14 +47,108 @@ static size_t vmcoreinfo_size = 0;
 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)
 {
diff -r d01ea51fc929 -r 3ce824963dc4 xen/include/xen/kexec.h
--- a/xen/include/xen/kexec.h   Mon Apr 26 12:11:30 2010 +0100
+++ b/xen/include/xen/kexec.h   Mon Apr 26 12:12:12 2010 +0100
@@ -11,6 +11,8 @@ typedef struct xen_kexec_reserve {
 } xen_kexec_reserve_t;
 
 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

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.