Linus,

Please pull the latest x86-kdump-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-kdump-for-linus

   # HEAD: b9ac3849af412fd3887d7652bdbabf29d2aecc16 x86/kdump: Fall back to 
reserve high crashkernel memory

This tree includes two changes:

 - Raise the crash kernel reservation limit from from ~896MB to ~4GB. 
   Only very old (and already known-broken) kexec-tools is supposed to be 
   affected by this negatively.

 - Allow higher than 4GB crash kernel allocations when low allocations 
   fail.

 Thanks,

        Ingo

------------------>
Dave Young (2):
      x86/kdump: Have crashkernel=X reserve under 4G by default
      x86/kdump: Fall back to reserve high crashkernel memory


 Documentation/admin-guide/kernel-parameters.txt |  7 ++++--
 arch/x86/kernel/setup.c                         | 32 +++++++++++++++----------
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 2b8ee90bb644..24d01648edeb 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -704,8 +704,11 @@
                        upon panic. This parameter reserves the physical
                        memory region [offset, offset + size] for that kernel
                        image. If '@offset' is omitted, then a suitable offset
-                       is selected automatically. Check
-                       Documentation/kdump/kdump.txt for further details.
+                       is selected automatically.
+                       [KNL, x86_64] select a region under 4G first, and
+                       fall back to reserve region above 4G when '@offset'
+                       hasn't been specified.
+                       See Documentation/kdump/kdump.txt for further details.
 
        crashkernel=range1:size1[,range2:size2,...][@offset]
                        [KNL] Same as above, but depends on the memory
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 3d872a527cd9..c15f362a2516 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -71,6 +71,7 @@
 #include <linux/tboot.h>
 #include <linux/jiffies.h>
 #include <linux/mem_encrypt.h>
+#include <linux/sizes.h>
 
 #include <linux/usb/xhci-dbgp.h>
 #include <video/edid.h>
@@ -448,18 +449,17 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 #ifdef CONFIG_KEXEC_CORE
 
 /* 16M alignment for crash kernel regions */
-#define CRASH_ALIGN            (16 << 20)
+#define CRASH_ALIGN            SZ_16M
 
 /*
  * Keep the crash kernel below this limit.  On 32 bits earlier kernels
  * would limit the kernel to the low 512 MiB due to mapping restrictions.
- * On 64bit, old kexec-tools need to under 896MiB.
  */
 #ifdef CONFIG_X86_32
-# define CRASH_ADDR_LOW_MAX    (512 << 20)
-# define CRASH_ADDR_HIGH_MAX   (512 << 20)
+# define CRASH_ADDR_LOW_MAX    SZ_512M
+# define CRASH_ADDR_HIGH_MAX   SZ_512M
 #else
-# define CRASH_ADDR_LOW_MAX    (896UL << 20)
+# define CRASH_ADDR_LOW_MAX    SZ_4G
 # define CRASH_ADDR_HIGH_MAX   MAXMEM
 #endif
 
@@ -541,21 +541,27 @@ static void __init reserve_crashkernel(void)
        }
 
        /* 0 means: find the address automatically */
-       if (crash_base <= 0) {
+       if (!crash_base) {
                /*
                 * Set CRASH_ADDR_LOW_MAX upper bound for crash memory,
-                * as old kexec-tools loads bzImage below that, unless
-                * "crashkernel=size[KMG],high" is specified.
+                * crashkernel=x,high reserves memory over 4G, also allocates
+                * 256M extra low memory for DMA buffers and swiotlb.
+                * But the extra memory is not required for all machines.
+                * So try low memory first and fall back to high memory
+                * unless "crashkernel=size[KMG],high" is specified.
                 */
-               crash_base = memblock_find_in_range(CRASH_ALIGN,
-                                                   high ? CRASH_ADDR_HIGH_MAX
-                                                        : CRASH_ADDR_LOW_MAX,
-                                                   crash_size, CRASH_ALIGN);
+               if (!high)
+                       crash_base = memblock_find_in_range(CRASH_ALIGN,
+                                               CRASH_ADDR_LOW_MAX,
+                                               crash_size, CRASH_ALIGN);
+               if (!crash_base)
+                       crash_base = memblock_find_in_range(CRASH_ALIGN,
+                                               CRASH_ADDR_HIGH_MAX,
+                                               crash_size, CRASH_ALIGN);
                if (!crash_base) {
                        pr_info("crashkernel reservation failed - No suitable 
area found.\n");
                        return;
                }
-
        } else {
                unsigned long long start;
 

Reply via email to