xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] kexec: allow relaxed placement specification via command line
@ 2016-05-30 13:48 Jan Beulich
  2016-05-31 10:24 ` Andrew Cooper
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Jan Beulich @ 2016-05-30 13:48 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Daniel Kiper, David Vrabel

[-- Attachment #1: Type: text/plain, Size: 4777 bytes --]

Rather than just allowing a fixed address or fully automatic placement,
also allow for specifying an upper bound. Especially on EFI systems,
where firmware memory use is commonly less predictable than on legacy
BIOS ones, this makes success of the reservation more likely when
automatic placement is not an option (e.g. because of special DMA
restrictions of devices involved in actually carrying out the dump).

Also take the opportunity to actually add text to the "crashkernel"
entry in the command line option doc.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -458,7 +458,18 @@ Specify the maximum address to allocate
 combination with the `low_crashinfo` command line option.
 
 ### crashkernel
-> `= <ramsize-range>:<size>[,...][@<offset>]`
+> `= <ramsize-range>:<size>[,...][{@,<}<offset>]`
+> `= <size>[{@,<}<offset>]`
+
+Specify sizes and optionally placement of the kexec reservation area.
+The `<ramsize-range>:<size>' pairs indicate how much memory to set
+aside for kexec (`<size>') for a given range of installed RAM
+(`<ramsize-range>').  Each `<ramsize-range>' is of the form
+`<start>-[<end>]'.
+
+A trailing `@<offset>' specifies the exact address this area should be
+placed at, whereas `<' in place of `@' just specifies an upper bound of
+the address range the area should fall into.
 
 ### credit2\_balance\_over
 > `= <integer>`
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1044,13 +1044,19 @@ void __init noreturn __start_xen(unsigne
         }
 
 #ifdef CONFIG_KEXEC
-        /* Don't overlap with modules. */
-        e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
-                             mod, mbi->mods_count, -1);
-        if ( !kexec_crash_area.start && (s < e) )
+        while ( !kexec_crash_area.start )
         {
-            e = (e - kexec_crash_area.size) & PAGE_MASK;
-            kexec_crash_area.start = e;
+            /* Don't overlap with modules. */
+            e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
+                                 mod, mbi->mods_count, -1);
+            if ( s >= e )
+                break;
+            if ( e > kexec_crash_area_limit )
+            {
+                e = kexec_crash_area_limit & PAGE_MASK;
+                continue;
+            }
+            kexec_crash_area.start = (e - kexec_crash_area.size) & PAGE_MASK;
         }
 #endif
     }
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -60,6 +60,7 @@ static unsigned char vmcoreinfo_data[VMC
 static size_t vmcoreinfo_size = 0;
 
 xen_kexec_reserve_t kexec_crash_area;
+paddr_t __initdata kexec_crash_area_limit = ~(paddr_t)0;
 static struct {
     u64 start, end;
     unsigned long size;
@@ -86,7 +87,7 @@ static void *crash_heap_current = NULL,
 /*
  * Parse command lines in the format
  *
- *   crashkernel=<ramsize-range>:<size>[,...][@<offset>]
+ *   crashkernel=<ramsize-range>:<size>[,...][{@,<}<address>]
  *
  * with <ramsize-range> being of form
  *
@@ -94,7 +95,7 @@ static void *crash_heap_current = NULL,
  *
  * as well as the legacy ones in the format
  *
- *   crashkernel=<size>[@<offset>]
+ *   crashkernel=<size>[{@,<}<address>]
  */
 static void __init parse_crashkernel(const char *str)
 {
@@ -109,7 +110,7 @@ static void __init parse_crashkernel(con
             {
                 printk(XENLOG_WARNING "crashkernel: too many ranges\n");
                 cur = NULL;
-                str = strchr(str, '@');
+                str = strpbrk(str, "@<");
                 break;
             }
 
@@ -154,9 +155,16 @@ static void __init parse_crashkernel(con
     }
     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 )
+    if ( cur != str )
+    {
+        if ( *str == '@' )
+            kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str);
+        else if ( *str == '<' )
+            kexec_crash_area_limit = parse_size_and_unit(cur = str + 1, &str);
+        else
+            printk(XENLOG_WARNING "crashkernel: '%s' ignored\n", str);
+    }
+    if ( cur && cur == str )
         printk(XENLOG_WARNING "crashkernel: memory value expected\n");
 }
 custom_param("crashkernel", parse_crashkernel);
--- a/xen/include/xen/kexec.h
+++ b/xen/include/xen/kexec.h
@@ -14,6 +14,7 @@ typedef struct xen_kexec_reserve {
 } xen_kexec_reserve_t;
 
 extern xen_kexec_reserve_t kexec_crash_area;
+extern paddr_t kexec_crash_area_limit;
 
 extern bool_t kexecing;
 



[-- Attachment #2: kexec-relaxed-placement.patch --]
[-- Type: text/plain, Size: 4838 bytes --]

kexec: allow relaxed placement specification via command line

Rather than just allowing a fixed address or fully automatic placement,
also allow for specifying an upper bound. Especially on EFI systems,
where firmware memory use is commonly less predictable than on legacy
BIOS ones, this makes success of the reservation more likely when
automatic placement is not an option (e.g. because of special DMA
restrictions of devices involved in actually carrying out the dump).

Also take the opportunity to actually add text to the "crashkernel"
entry in the command line option doc.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -458,7 +458,18 @@ Specify the maximum address to allocate
 combination with the `low_crashinfo` command line option.
 
 ### crashkernel
-> `= <ramsize-range>:<size>[,...][@<offset>]`
+> `= <ramsize-range>:<size>[,...][{@,<}<offset>]`
+> `= <size>[{@,<}<offset>]`
+
+Specify sizes and optionally placement of the kexec reservation area.
+The `<ramsize-range>:<size>' pairs indicate how much memory to set
+aside for kexec (`<size>') for a given range of installed RAM
+(`<ramsize-range>').  Each `<ramsize-range>' is of the form
+`<start>-[<end>]'.
+
+A trailing `@<offset>' specifies the exact address this area should be
+placed at, whereas `<' in place of `@' just specifies an upper bound of
+the address range the area should fall into.
 
 ### credit2\_balance\_over
 > `= <integer>`
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1044,13 +1044,19 @@ void __init noreturn __start_xen(unsigne
         }
 
 #ifdef CONFIG_KEXEC
-        /* Don't overlap with modules. */
-        e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
-                             mod, mbi->mods_count, -1);
-        if ( !kexec_crash_area.start && (s < e) )
+        while ( !kexec_crash_area.start )
         {
-            e = (e - kexec_crash_area.size) & PAGE_MASK;
-            kexec_crash_area.start = e;
+            /* Don't overlap with modules. */
+            e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
+                                 mod, mbi->mods_count, -1);
+            if ( s >= e )
+                break;
+            if ( e > kexec_crash_area_limit )
+            {
+                e = kexec_crash_area_limit & PAGE_MASK;
+                continue;
+            }
+            kexec_crash_area.start = (e - kexec_crash_area.size) & PAGE_MASK;
         }
 #endif
     }
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -60,6 +60,7 @@ static unsigned char vmcoreinfo_data[VMC
 static size_t vmcoreinfo_size = 0;
 
 xen_kexec_reserve_t kexec_crash_area;
+paddr_t __initdata kexec_crash_area_limit = ~(paddr_t)0;
 static struct {
     u64 start, end;
     unsigned long size;
@@ -86,7 +87,7 @@ static void *crash_heap_current = NULL,
 /*
  * Parse command lines in the format
  *
- *   crashkernel=<ramsize-range>:<size>[,...][@<offset>]
+ *   crashkernel=<ramsize-range>:<size>[,...][{@,<}<address>]
  *
  * with <ramsize-range> being of form
  *
@@ -94,7 +95,7 @@ static void *crash_heap_current = NULL,
  *
  * as well as the legacy ones in the format
  *
- *   crashkernel=<size>[@<offset>]
+ *   crashkernel=<size>[{@,<}<address>]
  */
 static void __init parse_crashkernel(const char *str)
 {
@@ -109,7 +110,7 @@ static void __init parse_crashkernel(con
             {
                 printk(XENLOG_WARNING "crashkernel: too many ranges\n");
                 cur = NULL;
-                str = strchr(str, '@');
+                str = strpbrk(str, "@<");
                 break;
             }
 
@@ -154,9 +155,16 @@ static void __init parse_crashkernel(con
     }
     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 )
+    if ( cur != str )
+    {
+        if ( *str == '@' )
+            kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str);
+        else if ( *str == '<' )
+            kexec_crash_area_limit = parse_size_and_unit(cur = str + 1, &str);
+        else
+            printk(XENLOG_WARNING "crashkernel: '%s' ignored\n", str);
+    }
+    if ( cur && cur == str )
         printk(XENLOG_WARNING "crashkernel: memory value expected\n");
 }
 custom_param("crashkernel", parse_crashkernel);
--- a/xen/include/xen/kexec.h
+++ b/xen/include/xen/kexec.h
@@ -14,6 +14,7 @@ typedef struct xen_kexec_reserve {
 } xen_kexec_reserve_t;
 
 extern xen_kexec_reserve_t kexec_crash_area;
+extern paddr_t kexec_crash_area_limit;
 
 extern bool_t kexecing;
 

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-06-01 10:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-30 13:48 [PATCH] kexec: allow relaxed placement specification via command line Jan Beulich
2016-05-31 10:24 ` Andrew Cooper
2016-05-31 10:50   ` Jan Beulich
2016-05-31 10:30 ` David Vrabel
2016-05-31 12:44   ` Jan Beulich
2016-05-31 16:02     ` David Vrabel
2016-06-01 10:26 ` Daniel Kiper
2016-06-01 10:42   ` Jan Beulich

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).