[PATCH v14 01/11] x86: kdump: replace the hard-coded alignment with macro CRASH_ALIGN

2021-01-29 Thread Chen Zhou
Move CRASH_ALIGN to header asm/kexec.h for later use. Besides, the
alignment of crash kernel regions in x86 is 16M(CRASH_ALIGN), but
function reserve_crashkernel() also used 1M alignment. So just
replace hard-coded alignment 1M with macro CRASH_ALIGN.

Suggested-by: Dave Young 
Suggested-by: Baoquan He 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/include/asm/kexec.h | 3 +++
 arch/x86/kernel/setup.c  | 5 +
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 6802c59e8252..be18dc7ae51f 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,9 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_16M
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 3412c4595efd..da769845597d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -390,9 +390,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
-
 /*
  * Keep the crash kernel below this limit.
  *
@@ -510,7 +507,7 @@ static void __init reserve_crashkernel(void)
} else {
unsigned long long start;
 
-   start = memblock_phys_alloc_range(crash_size, SZ_1M, crash_base,
+   start = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, 
crash_base,
  crash_base + crash_size);
if (start != crash_base) {
pr_info("crashkernel reservation failed - memory is in 
use.\n");
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 04/11] x86: kdump: move xen_pv_domain() check and insert_resource() to setup_arch()

2021-01-29 Thread Chen Zhou
We will make the functions reserve_crashkernel() as generic, the
xen_pv_domain() check in reserve_crashkernel() is relevant only to
x86, the same as insert_resource() in reserve_crashkernel[_low]().
So move xen_pv_domain() check and insert_resource() to setup_arch()
to keep them in x86.

Suggested-by: Mike Rapoport 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/kernel/setup.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 086a04235be4..5d676efc32f6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -454,7 +454,6 @@ static int __init reserve_crashkernel_low(void)
 
crashk_low_res.start = low_base;
crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
 #endif
return 0;
 }
@@ -478,11 +477,6 @@ static void __init reserve_crashkernel(void)
high = true;
}
 
-   if (xen_pv_domain()) {
-   pr_info("Ignoring crashkernel for a Xen PV domain\n");
-   return;
-   }
-
/* 0 means: find the address automatically */
if (!crash_base) {
/*
@@ -529,7 +523,6 @@ static void __init reserve_crashkernel(void)
 
crashk_res.start = crash_base;
crashk_res.end   = crash_base + crash_size - 1;
-   insert_resource(_resource, _res);
 }
 #else
 static void __init reserve_crashkernel(void)
@@ -1151,7 +1144,17 @@ void __init setup_arch(char **cmdline_p)
 * Reserve memory for crash kernel after SRAT is parsed so that it
 * won't consume hotpluggable memory.
 */
-   reserve_crashkernel();
+   if (xen_pv_domain())
+   pr_info("Ignoring crashkernel for a Xen PV domain\n");
+   else {
+   reserve_crashkernel();
+#ifdef CONFIG_KEXEC_CORE
+   if (crashk_res.end > crashk_res.start)
+   insert_resource(_resource, _res);
+   if (crashk_low_res.end > crashk_low_res.start)
+   insert_resource(_resource, _low_res);
+#endif
+   }
 
memblock_find_dma_reserve();
 
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 06/11] x86/elf: Move vmcore_elf_check_arch_cross to arch/x86/include/asm/elf.h

2021-01-29 Thread Chen Zhou
Move macro vmcore_elf_check_arch_cross from arch/x86/include/asm/kexec.h
to arch/x86/include/asm/elf.h to fix the following compiling warning:

make ARCH=i386
In file included from arch/x86/kernel/setup.c:39:0:
./arch/x86/include/asm/kexec.h:77:0: warning: "vmcore_elf_check_arch_cross" 
redefined
 # define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)

In file included from arch/x86/kernel/setup.c:9:0:
./include/linux/crash_dump.h:39:0: note: this is the location of the previous 
definition
 #define vmcore_elf_check_arch_cross(x) 0

The root cause is that vmcore_elf_check_arch_cross under CONFIG_CRASH_CORE
depend on CONFIG_KEXEC_CORE. Commit 2db65f1db17d ("x86: kdump: move
reserve_crashkernel[_low]() into crash_core.c") triggered the issue.

Suggested by Mike, simply move vmcore_elf_check_arch_cross from
arch/x86/include/asm/kexec.h to arch/x86/include/asm/elf.h to fix
the warning.

Fixes: 2db65f1db17d ("x86: kdump: move reserve_crashkernel[_low]() into 
crash_core.c")
Reported-by: kernel test robot 
Suggested-by: Mike Rapoport 
Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/elf.h   | 3 +++
 arch/x86/include/asm/kexec.h | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 66bdfe838d61..5333777cc758 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -94,6 +94,9 @@ extern unsigned int vdso32_enabled;
 
 #define elf_check_arch(x)  elf_check_arch_ia32(x)
 
+/* We can also handle crash dumps from 64 bit kernel. */
+# define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
+
 /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
contains a pointer to a function which might be registered using `atexit'.
This provides a mean for the dynamic linker to call DT_FINI functions for
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 2b18f918203e..6fcae01a9cca 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -72,9 +72,6 @@ struct kimage;
 
 /* The native architecture */
 # define KEXEC_ARCH KEXEC_ARCH_386
-
-/* We can also handle crash dumps from 64 bit kernel. */
-# define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
 #else
 /* Maximum physical address we can use pages from */
 # define KEXEC_SOURCE_MEMORY_LIMIT  (MAXMEM-1)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 00/11] support reserving crashkernel above 4G on arm64 kdump

2021-01-29 Thread Chen Zhou
Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-June/020737.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213
[v9]: https://lkml.org/lkml/2020/6/28/73
[v10]: https://lkml.org/lkml/2020/7/2/1443
[v11]: https://lkml.org/lkml/2020/8/1/150
[v12]: https://lkml.org/lkml/2020/9/7/1037
[v13]: https://lkml.org/lkml/2020/10/31/34

Chen Zhou (11):
  x86: kdump: replace the hard-coded alignment with macro CRASH_ALIGN
  x86: kdump: make the lower bound of crash kernel reservation
consistent
  x86: kdump: use macro CRASH_ADDR_LOW_MAX in functions
reserve_crashkernel()
  x86: kdump: move xen_pv_domain() check and insert_resource() to
setup_arch()
  x86: kdump: move reserve_crashkernel[_low]() into crash_core.c
  x86/elf: Move vmcore_elf_check_arch_cross to
arch/x86/include/asm/elf.h
  arm64: kdump: introduce some macroes for crash kernel reservation
  arm64: kdump: reimplement crashkernel=X
  x86, arm64: Add ARCH_WANT_RESERVE_CRASH_KERNEL config
  arm64: kdump: add memory for devices by DT property
linux,usable-memory-range
  kdump: update Documentation about crashkernel

 Documentation/admin-guide/kdump/kdump.rst |  22 ++-
 .../admin-guide/kernel-parameters.txt |  11 +-
 arch/Kconfig  |   3 +
 arch/arm64/Kconfig|   1 +
 arch/arm64/include/asm/kexec.h|  10 ++
 arch/arm64/kernel/setup.c |  13 +-
 arch/arm64/mm/init.c  | 111 +---
 arch/x86/Kconfig  |   2 +
 arch/x86/include/asm/elf.h|   3 +
 arch/x86/include/asm/kexec.h  |  31 +++-
 arch/x86/kernel/setup.c   | 163 ++
 include/linux/crash_core.h|   3 +
 include/linux/kexec.h |   2 -
 kernel/crash_core.c   | 156 +
 kernel/kexec_core.c   |  17 --
 15 files changed, 303 insertions(+), 245 deletions(-)

-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 11/11] kdump: update Documentation about crashkernel

2021-01-29 Thread Chen Zhou
For arm64, the behavior of crashkernel=X has been changed, which
tries low allocation in DMA zone and fall back to high allocation
if it fails.

We can also use "crashkernel=X,high" to select a high region above
DMA zone, which also tries to allocate at least 256M low memory in
DMA zone automatically and "crashkernel=Y,low" can be used to allocate
specified size low memory.

So update the Documentation.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 Documentation/admin-guide/kdump/kdump.rst | 22 ---
 .../admin-guide/kernel-parameters.txt | 11 --
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index 75a9dd98e76e..0877c76f8015 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,16 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=X" to select a region under 4G first, and
+   fall back to reserve region above 4G. And go for high allocation
+   directly if the required size is too large.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if you really have to reserve memory from specified
+   start address X.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +325,15 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
-   the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   On arm64, use "crashkernel=X" to try low allocation in DMA zone and
+   fall back to high allocation if it fails.
+   We can also use "crashkernel=X,high" to select a high region above
+   DMA zone, which also tries to allocate at least 256M low memory in
+   DMA zone automatically.
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if you really have to reserve memory from
+   specified start address X. Note that the start address of the kernel,
+   X if explicitly specified, must be aligned to 2MiB (0x20).
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index a10b545c2070..908e5c8b61ba 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -738,6 +738,9 @@
[KNL, X86-64] Select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] Try low allocation in DMA zone and fall 
back
+   to high allocation if it fails when '@offset' hasn't 
been
+   specified.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -754,6 +757,8 @@
Otherwise memory region will be allocated below 4G, if
available.
It will be ignored if crashkernel=X is specified.
+   [KNL, arm64] range in high memory.
+   Allow kernel to allocate physical memory region from 
top.
crashkernel=size[KMG],low
[KNL, X86-64] range under 4G. When crashkernel=X,high
is passed, kernel could allocate physical memory region
@@ -762,13 +767,15 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
-
+   [KNL, arm64] range in low memory.
+   This

[PATCH v14 07/11] arm64: kdump: introduce some macroes for crash kernel reservation

2021-01-29 Thread Chen Zhou
Introduce macro CRASH_ALIGN for alignment, macro CRASH_ADDR_LOW_MAX
for upper bound of low crash memory, macro CRASH_ADDR_HIGH_MAX for
upper bound of high crash memory, use macroes instead.

Besides, keep consistent with x86, use CRASH_ALIGN as the lower bound
of crash kernel reservation.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/arm64/include/asm/kexec.h | 6 ++
 arch/arm64/mm/init.c   | 6 +++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index d24b527e8c00..3f6ecae0bc68 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -25,6 +25,12 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
+#define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit
+#define CRASH_ADDR_HIGH_MAXMEMBLOCK_ALLOC_ACCESSIBLE
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 709d98fea90c..912f64f505f7 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -84,8 +84,8 @@ static void __init reserve_crashkernel(void)
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(CRASH_ALIGN, 
CRASH_ADDR_LOW_MAX,
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -103,7 +103,7 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 03/11] x86: kdump: use macro CRASH_ADDR_LOW_MAX in functions reserve_crashkernel()

2021-01-29 Thread Chen Zhou
To make the functions reserve_crashkernel() as generic,
replace some hard-coded numbers with macro CRASH_ADDR_LOW_MAX.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/kernel/setup.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 27470479e4a3..086a04235be4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -487,8 +487,9 @@ static void __init reserve_crashkernel(void)
if (!crash_base) {
/*
 * Set CRASH_ADDR_LOW_MAX upper bound for crash memory,
-* crashkernel=x,high reserves memory over 4G, also allocates
-* 256M extra low memory for DMA buffers and swiotlb.
+* crashkernel=x,high reserves memory over CRASH_ADDR_LOW_MAX,
+* 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.
@@ -516,7 +517,7 @@ static void __init reserve_crashkernel(void)
}
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+   if (crash_base >= CRASH_ADDR_LOW_MAX && reserve_crashkernel_low()) {
memblock_free(crash_base, crash_size);
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 09/11] x86, arm64: Add ARCH_WANT_RESERVE_CRASH_KERNEL config

2021-01-29 Thread Chen Zhou
We make the functions reserve_crashkernel[_low]() as generic for
x86 and arm64. Since reserve_crashkernel[_low]() implementations
are quite similar on other architectures as well, we can have more
users of this later.

So have CONFIG_ARCH_WANT_RESERVE_CRASH_KERNEL in arch/Kconfig and
select this by X86 and ARM64.

Suggested-by: Mike Rapoport 
Suggested-by: Baoquan He 
Signed-off-by: Chen Zhou 
---
 arch/Kconfig| 3 +++
 arch/arm64/Kconfig  | 1 +
 arch/x86/Kconfig| 2 ++
 kernel/crash_core.c | 7 ++-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 24862d15f3a3..0ca1ff5bb157 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -24,6 +24,9 @@ config KEXEC_ELF
 config HAVE_IMA_KEXEC
bool
 
+config ARCH_WANT_RESERVE_CRASH_KERNEL
+   bool
+
 config SET_FS
bool
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f39568b28ec1..09365c7ff469 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -82,6 +82,7 @@ config ARM64
select ARCH_WANT_FRAME_POINTERS
select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES 
&& !ARM64_VA_BITS_36)
select ARCH_WANT_LD_ORPHAN_WARN
+   select ARCH_WANT_RESERVE_CRASH_KERNEL if KEXEC_CORE
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARM_AMBA
select ARM_ARCH_TIMER
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 21f851179ff0..e6926fcb4a40 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -12,6 +12,7 @@ config X86_32
depends on !64BIT
# Options that are inherently 32-bit kernel only:
select ARCH_WANT_IPC_PARSE_VERSION
+   select ARCH_WANT_RESERVE_CRASH_KERNEL if KEXEC_CORE
select CLKSRC_I8253
select CLONE_BACKWARDS
select GENERIC_VDSO_32
@@ -28,6 +29,7 @@ config X86_64
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
select ARCH_USE_CMPXCHG_LOCKREF
+   select ARCH_WANT_RESERVE_CRASH_KERNEL if KEXEC_CORE
select HAVE_ARCH_SOFT_DIRTY
select MODULES_USE_ELF_RELA
select NEED_DMA_MAP_STATE
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 8479be270c0b..2c5783985db5 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -320,9 +320,7 @@ int __init parse_crashkernel_low(char *cmdline,
  * - Crashkernel reservation --
  */
 
-#ifdef CONFIG_KEXEC_CORE
-
-#if defined(CONFIG_X86) || defined(CONFIG_ARM64)
+#ifdef CONFIG_ARCH_WANT_RESERVE_CRASH_KERNEL
 static int __init reserve_crashkernel_low(void)
 {
 #ifdef CONFIG_64BIT
@@ -450,8 +448,7 @@ void __init reserve_crashkernel(void)
crashk_res.start = crash_base;
crashk_res.end   = crash_base + crash_size - 1;
 }
-#endif
-#endif /* CONFIG_KEXEC_CORE */
+#endif /* CONFIG_ARCH_WANT_RESERVE_CRASH_KERNEL */
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
  void *data, size_t data_len)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 10/11] arm64: kdump: add memory for devices by DT property linux, usable-memory-range

2021-01-29 Thread Chen Zhou
When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices and never mapped by the first kernel.
This memory range is advertised to crash dump kernel via DT property
under /chosen,
linux,usable-memory-range = 

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/arm64/mm/init.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d20f5c444ebf..180a25b67f55 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -68,6 +68,15 @@ static void __init reserve_crashkernel(void)
 }
 #endif
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now there may
+ * be two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES  2
+
 #ifdef CONFIG_CRASH_DUMP
 static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
const char *uname, int depth, void *data)
@@ -201,9 +210,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_region *usable_rgns = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -212,22 +221,36 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   usable_rgns[nr].base = dt_mem_next_cell(dt_root_addr_cells, 
);
+   usable_rgns[nr].size = dt_mem_next_cell(dt_root_size_cells, 
);
+
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_rgns[MAX_USABLE_RANGES] = {
+   { .size = 0 },
+   { .size = 0 }
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, _rgns);
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   /*
+* The first range of usable-memory regions is for crash dump
+* kernel with only one region or for high region with two regions,
+* the second range is dedicated for low region if exist.
+*/
+   if (usable_rgns[0].size)
+   memblock_cap_memory_range(usable_rgns[0].base, 
usable_rgns[0].size);
+   if (usable_rgns[1].size)
+   memblock_add(usable_rgns[1].base, usable_rgns[1].size);
 }
 
 void __init arm64_memblock_init(void)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v14 08/11] arm64: kdump: reimplement crashkernel=X

2021-01-29 Thread Chen Zhou
There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.

To solve these issues, change the behavior of crashkernel=X and
introduce crashkernel=X,[high,low]. crashkernel=X tries low allocation
in DMA zone, and fall back to high allocation if it fails.
We can also use "crashkernel=X,high" to select a region above DMA zone,
which also tries to allocate at least 256M in DMA zone automatically.
"crashkernel=Y,low" can be used to allocate specified size low memory.

Another minor change, there may be two regions reserved for crash
dump kernel, in order to distinct from the high region and make no
effect to the use of existing kexec-tools, rename the low region as
"Crash kernel (low)".

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/arm64/include/asm/kexec.h |  4 ++
 arch/arm64/kernel/setup.c  | 13 ++-
 arch/arm64/mm/init.c   | 68 ++
 kernel/crash_core.c|  6 +--
 4 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 3f6ecae0bc68..f0caed0cb5e1 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -96,6 +96,10 @@ static inline void crash_prepare_suspend(void) {}
 static inline void crash_post_resume(void) {}
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+extern void __init reserve_crashkernel(void);
+#endif
+
 #ifdef CONFIG_KEXEC_FILE
 #define ARCH_HAS_KIMAGE_ARCH
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index c18aacde8bb0..69c592c546de 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,18 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" or "Crash kernel (low)"
+* region in /proc/iomem.
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end) {
+   crashk_low_res.name = "Crash kernel (low)";
+   request_resource(res, _low_res);
+   }
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 912f64f505f7..d20f5c444ebf 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -61,66 +62,11 @@ EXPORT_SYMBOL(memstart_addr);
  */
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
-#ifdef CONFIG_KEXEC_CORE
-/*
- * reserve_crashkernel() - reserves memory for crash kernel
- *
- * This function reserves memory area given in "crashkernel=" kernel command
- * line parameter. The memory reserved is used by dump capture kernel when
- * primary kernel is crashing.
- */
+#ifndef CONFIG_KEXEC_CORE
 static void __init reserve_crashkernel(void)
 {
-   unsigned long long crash_base, crash_size;
-   int ret;
-
-   ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
-   _size, _base);
-   /* no crashkernel= or invalid value specified */
-   if (ret || !crash_size)
-   return;
-
-   crash_size = PAGE_ALIGN(crash_size);
-
-   if (crash_base == 0) {
-   /* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(CRASH_ALIGN, 
CRASH_ADDR_LOW_MAX,
-   crash_size, CRASH_ALIGN);
-   if (crash_base == 0) {
-   pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
-   crash_size);
-   return;
-   }
-   } else {
-   /* User specifies base address explicitly. */
-   if (!memblock_is_region_memory(crash_base, crash_size)) {
-   pr_warn("cannot reserve crashkernel: region is not 
memory\n");
-   return;
-   }

[PATCH v14 05/11] x86: kdump: move reserve_crashkernel[_low]() into crash_core.c

2021-01-29 Thread Chen Zhou
Make the functions reserve_crashkernel[_low]() as generic.
Arm64 will use these to reimplement crashkernel=X.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/include/asm/kexec.h |  25 ++
 arch/x86/kernel/setup.c  | 143 +--
 include/linux/crash_core.h   |   3 +
 include/linux/kexec.h|   2 -
 kernel/crash_core.c  | 159 +++
 kernel/kexec_core.c  |  17 
 6 files changed, 189 insertions(+), 160 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index be18dc7ae51f..2b18f918203e 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -21,6 +21,27 @@
 /* 16M alignment for crash kernel regions */
 #define CRASH_ALIGNSZ_16M
 
+/*
+ * Keep the crash kernel below this limit.
+ *
+ * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
+ * due to mapping restrictions.
+ *
+ * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
+ * the upper limit of system RAM in 4-level paging mode. Since the kdump
+ * jump could be from 5-level paging to 4-level paging, the jump will fail if
+ * the kernel is put above 64 TB, and during the 1st kernel bootup there's
+ * no good way to detect the paging mode of the target kernel which will be
+ * loaded for dumping.
+ */
+#ifdef CONFIG_X86_32
+# define CRASH_ADDR_LOW_MAXSZ_512M
+# define CRASH_ADDR_HIGH_MAX   SZ_512M
+#else
+# define CRASH_ADDR_LOW_MAXSZ_4G
+# define CRASH_ADDR_HIGH_MAX   SZ_64T
+#endif
+
 #ifndef __ASSEMBLY__
 
 #include 
@@ -200,6 +221,10 @@ typedef void crash_vmclear_fn(void);
 extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss;
 extern void kdump_nmi_shootdown_cpus(void);
 
+#ifdef CONFIG_KEXEC_CORE
+extern void __init reserve_crashkernel(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 5d676efc32f6..d136d6ad3fa8 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -384,147 +385,7 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
}
 }
 
-/*
- * - Crashkernel reservation --
- */
-
-#ifdef CONFIG_KEXEC_CORE
-
-/*
- * Keep the crash kernel below this limit.
- *
- * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
- * due to mapping restrictions.
- *
- * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
- * the upper limit of system RAM in 4-level paging mode. Since the kdump
- * jump could be from 5-level paging to 4-level paging, the jump will fail if
- * the kernel is put above 64 TB, and during the 1st kernel bootup there's
- * no good way to detect the paging mode of the target kernel which will be
- * loaded for dumping.
- */
-#ifdef CONFIG_X86_32
-# define CRASH_ADDR_LOW_MAXSZ_512M
-# define CRASH_ADDR_HIGH_MAX   SZ_512M
-#else
-# define CRASH_ADDR_LOW_MAXSZ_4G
-# define CRASH_ADDR_HIGH_MAX   SZ_64T
-#endif
-
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long low_mem_limit;
-   int ret;
-
-   low_mem_limit = min(memblock_phys_mem_size(), CRASH_ADDR_LOW_MAX);
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, low_mem_limit, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, CRASH_ALIGN,
-   CRASH_ADDR_LOW_MAX);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (low 
RAM limit: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(low_mem_limit >> 20));
-
-   crashk_low_res.start = low_base;
-  

[PATCH v14 02/11] x86: kdump: make the lower bound of crash kernel reservation consistent

2021-01-29 Thread Chen Zhou
The lower bounds of crash kernel reservation and crash kernel low
reservation are different, use the consistent value CRASH_ALIGN.

Suggested-by: Dave Young 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/kernel/setup.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index da769845597d..27470479e4a3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -439,7 +439,8 @@ static int __init reserve_crashkernel_low(void)
return 0;
}
 
-   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, 
CRASH_ADDR_LOW_MAX);
+   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, CRASH_ALIGN,
+   CRASH_ADDR_LOW_MAX);
if (!low_base) {
pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
   (unsigned long)(low_size >> 20));
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 1/8] x86: kdump: replace the hard-coded alignment with macro CRASH_ALIGN

2020-10-31 Thread Chen Zhou
Move CRASH_ALIGN to header asm/kexec.h and replace the hard-coded
alignment with macro CRASH_ALIGN in function reserve_crashkernel().

Suggested-by: Dave Young 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/include/asm/kexec.h | 3 +++
 arch/x86/kernel/setup.c  | 5 +
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 6802c59e8252..8cf9d3fd31c7 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,9 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_16M
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 84f581c91db4..bf373422dc8a 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -395,9 +395,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
-
 /*
  * Keep the crash kernel below this limit.
  *
@@ -515,7 +512,7 @@ static void __init reserve_crashkernel(void)
} else {
unsigned long long start;
 
-   start = memblock_phys_alloc_range(crash_size, SZ_1M, crash_base,
+   start = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, 
crash_base,
  crash_base + crash_size);
if (start != crash_base) {
pr_info("crashkernel reservation failed - memory is in 
use.\n");
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 2/8] x86: kdump: make the lower bound of crash kernel reservation consistent

2020-10-31 Thread Chen Zhou
The lower bounds of crash kernel reservation and crash kernel low
reservation are different, use the consistent value CRASH_ALIGN.

Suggested-by: Dave Young 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/kernel/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index bf373422dc8a..d1599449a001 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -444,7 +444,7 @@ static int __init reserve_crashkernel_low(void)
return 0;
}
 
-   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, 
CRASH_ADDR_LOW_MAX);
+   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 
CRASH_ALIGN, CRASH_ADDR_LOW_MAX);
if (!low_base) {
pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
   (unsigned long)(low_size >> 20));
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 0/8] support reserving crashkernel above 4G on arm64 kdump

2020-10-31 Thread Chen Zhou
 i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-June/020737.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213
[v9]: https://lkml.org/lkml/2020/6/28/73
[v10]: https://lkml.org/lkml/2020/7/2/1443
[v11]: https://lkml.org/lkml/2020/8/1/150
[v12]: https://lkml.org/lkml/2020/9/7/1037

Chen Zhou (8):
  x86: kdump: replace the hard-coded alignment with macro CRASH_ALIGN
  x86: kdump: make the lower bound of crash kernel reservation
consistent
  x86: kdump: use macro CRASH_ADDR_LOW_MAX in functions
reserve_crashkernel()
  x86: kdump: move reserve_crashkernel[_low]() into crash_core.c
  arm64: kdump: introduce some macroes for crash kernel reservation
  arm64: kdump: reimplement crashkernel=X
  arm64: kdump: add memory for devices by DT property
linux,usable-memory-range
  kdump: update Documentation about crashkernel

 Documentation/admin-guide/kdump/kdump.rst |  23 ++-
 .../admin-guide/kernel-parameters.txt |  12 +-
 arch/arm64/include/asm/kexec.h|  15 ++
 arch/arm64/include/asm/processor.h|   1 +
 arch/arm64/kernel/setup.c |  13 +-
 arch/arm64/mm/init.c  | 105 ---
 arch/arm64/mm/mmu.c   |   4 +
 arch/x86/include/asm/kexec.h  |  28 +++
 arch/x86/kernel/setup.c   | 153 +---
 include/linux/crash_core.h|   4 +
 include/linux/kexec.h |   2 -
 kernel/crash_core.c   | 168 ++
 kernel/kexec_core.c   |  17 --
 13 files changed, 301 insertions(+), 244 deletions(-)

-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 4/8] x86: kdump: move reserve_crashkernel[_low]() into crash_core.c

2020-10-31 Thread Chen Zhou
Make the functions reserve_crashkernel[_low]() as generic.
Arm64 will use these to reimplement crashkernel=X.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/include/asm/kexec.h |  25 ++
 arch/x86/kernel/setup.c  | 151 +---
 include/linux/crash_core.h   |   4 +
 include/linux/kexec.h|   2 -
 kernel/crash_core.c  | 164 +++
 kernel/kexec_core.c  |  17 
 6 files changed, 195 insertions(+), 168 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 8cf9d3fd31c7..34afa7b645f9 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -21,6 +21,27 @@
 /* 2M alignment for crash kernel regions */
 #define CRASH_ALIGNSZ_16M
 
+/*
+ * Keep the crash kernel below this limit.
+ *
+ * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
+ * due to mapping restrictions.
+ *
+ * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
+ * the upper limit of system RAM in 4-level paging mode. Since the kdump
+ * jump could be from 5-level paging to 4-level paging, the jump will fail if
+ * the kernel is put above 64 TB, and during the 1st kernel bootup there's
+ * no good way to detect the paging mode of the target kernel which will be
+ * loaded for dumping.
+ */
+#ifdef CONFIG_X86_32
+# define CRASH_ADDR_LOW_MAXSZ_512M
+# define CRASH_ADDR_HIGH_MAX   SZ_512M
+#else
+# define CRASH_ADDR_LOW_MAXSZ_4G
+# define CRASH_ADDR_HIGH_MAX   SZ_64T
+#endif
+
 #ifndef __ASSEMBLY__
 
 #include 
@@ -200,6 +221,10 @@ typedef void crash_vmclear_fn(void);
 extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss;
 extern void kdump_nmi_shootdown_cpus(void);
 
+#ifdef CONFIG_KEXEC_CORE
+extern void __init reserve_crashkernel(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 1289f079ad5f..00b3840d30f9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -25,8 +25,6 @@
 
 #include 
 
-#include 
-
 #include 
 #include 
 #include 
@@ -38,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -389,153 +388,7 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
}
 }
 
-/*
- * - Crashkernel reservation --
- */
-
-#ifdef CONFIG_KEXEC_CORE
-
-/*
- * Keep the crash kernel below this limit.
- *
- * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
- * due to mapping restrictions.
- *
- * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
- * the upper limit of system RAM in 4-level paging mode. Since the kdump
- * jump could be from 5-level paging to 4-level paging, the jump will fail if
- * the kernel is put above 64 TB, and during the 1st kernel bootup there's
- * no good way to detect the paging mode of the target kernel which will be
- * loaded for dumping.
- */
-#ifdef CONFIG_X86_32
-# define CRASH_ADDR_LOW_MAXSZ_512M
-# define CRASH_ADDR_HIGH_MAX   SZ_512M
-#else
-# define CRASH_ADDR_LOW_MAXSZ_4G
-# define CRASH_ADDR_HIGH_MAX   SZ_64T
-#endif
-
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long low_mem_limit;
-   int ret;
-
-   low_mem_limit = min(memblock_phys_mem_size(), CRASH_ADDR_LOW_MAX);
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, low_mem_limit, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 
CRASH_ALIGN, CRASH_ADDR_LOW_MAX);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (low 
RAM limit: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(low_mem_limit 

[PATCH v13 7/8] arm64: kdump: add memory for devices by DT property linux, usable-memory-range

2020-10-31 Thread Chen Zhou
When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices and never mapped by the first kernel.
This memory range is advertised to crash dump kernel via DT property
under /chosen,
linux,usable-memory-range = 

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/arm64/mm/init.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 888c4f7eadc3..794f992cb200 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -69,6 +69,15 @@ static void __init reserve_crashkernel(void)
 }
 #endif
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now there may
+ * be two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES  2
+
 #ifdef CONFIG_CRASH_DUMP
 static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
const char *uname, int depth, void *data)
@@ -184,9 +193,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_region *usable_rgns = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -195,22 +204,36 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   usable_rgns[nr].base = dt_mem_next_cell(dt_root_addr_cells, 
);
+   usable_rgns[nr].size = dt_mem_next_cell(dt_root_size_cells, 
);
+
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_rgns[MAX_USABLE_RANGES] = {
+   { .size = 0 },
+   { .size = 0 }
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, _rgns);
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   /*
+* The first range of usable-memory regions is for crash dump
+* kernel with only one region or for high region with two regions,
+* the second range is dedicated for low region if exist.
+*/
+   if (usable_rgns[0].size)
+   memblock_cap_memory_range(usable_rgns[0].base, 
usable_rgns[0].size);
+   if (usable_rgns[1].size)
+   memblock_add(usable_rgns[1].base, usable_rgns[1].size);
 }
 
 void __init arm64_memblock_init(void)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 3/8] x86: kdump: use macro CRASH_ADDR_LOW_MAX in functions reserve_crashkernel()

2020-10-31 Thread Chen Zhou
To make the functions reserve_crashkernel() as generic,
replace some hard-coded numbers with macro CRASH_ADDR_LOW_MAX.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/x86/kernel/setup.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d1599449a001..1289f079ad5f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -491,8 +491,9 @@ static void __init reserve_crashkernel(void)
if (!crash_base) {
/*
 * Set CRASH_ADDR_LOW_MAX upper bound for crash memory,
-* crashkernel=x,high reserves memory over 4G, also allocates
-* 256M extra low memory for DMA buffers and swiotlb.
+* crashkernel=x,high reserves memory over CRASH_ADDR_LOW_MAX,
+* 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.
@@ -520,7 +521,7 @@ static void __init reserve_crashkernel(void)
}
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+   if (crash_base >= CRASH_ADDR_LOW_MAX && reserve_crashkernel_low()) {
memblock_free(crash_base, crash_size);
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 5/8] arm64: kdump: introduce some macroes for crash kernel reservation

2020-10-31 Thread Chen Zhou
Introduce macro CRASH_ALIGN for alignment, macro CRASH_ADDR_LOW_MAX
for upper bound of low crash memory, macro CRASH_ADDR_HIGH_MAX for
upper bound of high crash memory, use macroes instead.

Besides, keep consistent with x86, use CRASH_ALIGN as the lower bound
of crash kernel reservation.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/arm64/include/asm/kexec.h | 6 ++
 arch/arm64/include/asm/processor.h | 1 +
 arch/arm64/mm/init.c   | 8 
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index d24b527e8c00..402d208265a3 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -25,6 +25,12 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
+#define CRASH_ADDR_LOW_MAX arm64_dma32_phys_limit
+#define CRASH_ADDR_HIGH_MAXMEMBLOCK_ALLOC_ACCESSIBLE
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/include/asm/processor.h 
b/arch/arm64/include/asm/processor.h
index fce8cbecd6bc..12131655cab7 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -96,6 +96,7 @@
 #endif /* CONFIG_ARM64_FORCE_52BIT */
 
 extern phys_addr_t arm64_dma_phys_limit;
+extern phys_addr_t arm64_dma32_phys_limit;
 #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1)
 
 struct debug_info {
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 095540667f0f..a07fd8e1f926 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -60,7 +60,7 @@ EXPORT_SYMBOL(memstart_addr);
  * bit addressable memory area.
  */
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
-static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
+phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
 /*
@@ -85,8 +85,8 @@ static void __init reserve_crashkernel(void)
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(CRASH_ALIGN, 
CRASH_ADDR_LOW_MAX,
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -104,7 +104,7 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v13 6/8] arm64: kdump: reimplement crashkernel=X

2020-10-31 Thread Chen Zhou
There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.
3. Since commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32"),
if the memory reserved for crash dump kernel falled in ZONE_DMA32,
the devices in crash dump kernel need to use ZONE_DMA will alloc
fail.

To solve these issues, change the behavior of crashkernel=X and
introduce crashkernel=X,[high,low]. crashkernel=X tries low allocation
in DMA zone or DMA32 zone if CONFIG_ZONE_DMA is disabled, and fall back
to high allocation if it fails.
We can also use "crashkernel=X,high" to select a region above DMA zone,
which also tries to allocate at least 256M in DMA zone automatically
(or the DMA32 zone if CONFIG_ZONE_DMA is disabled).
"crashkernel=Y,low" can be used to allocate specified size low memory.

Another minor change, there may be two regions reserved for crash
dump kernel, in order to distinct from the high region and make no
effect to the use of existing kexec-tools, rename the low region as
"Crash kernel (low)".

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 arch/arm64/include/asm/kexec.h |  9 +
 arch/arm64/kernel/setup.c  | 13 +++-
 arch/arm64/mm/init.c   | 60 ++
 arch/arm64/mm/mmu.c|  4 +++
 kernel/crash_core.c|  8 +++--
 5 files changed, 34 insertions(+), 60 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 402d208265a3..79909ae5e22e 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -28,7 +28,12 @@
 /* 2M alignment for crash kernel regions */
 #define CRASH_ALIGNSZ_2M
 
+#ifdef CONFIG_ZONE_DMA
+#define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit
+#else
 #define CRASH_ADDR_LOW_MAX arm64_dma32_phys_limit
+#endif
+
 #define CRASH_ADDR_HIGH_MAXMEMBLOCK_ALLOC_ACCESSIBLE
 
 #ifndef __ASSEMBLY__
@@ -96,6 +101,10 @@ static inline void crash_prepare_suspend(void) {}
 static inline void crash_post_resume(void) {}
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+extern void __init reserve_crashkernel(void);
+#endif
+
 #ifdef CONFIG_KEXEC_FILE
 #define ARCH_HAS_KIMAGE_ARCH
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 133257ffd859..6aff30de8f47 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,18 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" or "Crash kernel (low)"
+* region in /proc/iomem.
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end) {
+   crashk_low_res.name = "Crash kernel (low)";
+   request_resource(res, _low_res);
+   }
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index a07fd8e1f926..888c4f7eadc3 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -62,66 +63,11 @@ EXPORT_SYMBOL(memstart_addr);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
-#ifdef CONFIG_KEXEC_CORE
-/*
- * reserve_crashkernel() - reserves memory for crash kernel
- *
- * This function reserves memory area given in "crashkernel=" kernel command
- * line parameter. The memory reserved is used by dump capture kernel when
- * primary kernel is crashing.
- */
-static void __init reserve_crashkernel(void)
-{
-   unsigned long long crash_base, crash_size;
-   int ret;
-
-   ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
-   _size, _base);
-   /* no crashkernel= or invalid value specified */
-   if (ret || !crash_size)
-   return;
-
-   crash_size = PAGE_ALIGN(crash_size);
-
-   if (crash_base == 0) {
-   /* Current arm64 boot protocol requi

[PATCH v13 8/8] kdump: update Documentation about crashkernel

2020-10-31 Thread Chen Zhou
For arm64, the behavior of crashkernel=X has been changed, which
tries low allocation in DMA zone or DMA32 zone if CONFIG_ZONE_DMA
is disabled, and fall back to high allocation if it fails.

We can also use "crashkernel=X,high" to select a high region above
DMA zone, which also tries to allocate at least 256M low memory in
DMA zone automatically (or the DMA32 zone if CONFIG_ZONE_DMA is disabled).

"crashkernel=Y,low" can be used to allocate specified size low memory.

So update the Documentation.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
---
 Documentation/admin-guide/kdump/kdump.rst | 23 ---
 .../admin-guide/kernel-parameters.txt | 12 --
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index 75a9dd98e76e..bde5f994d185 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,16 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=X" to select a region under 4G first, and
+   fall back to reserve region above 4G. And go for high allocation
+   directly if the required size is too large.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if you really have to reserve memory from specified
+   start address X.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +325,16 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
-   the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   On arm64, use "crashkernel=X" to try low allocation in DMA zone (or
+   DMA32 zone if CONFIG_ZONE_DMA is disabled), and fall back to high
+   allocation if it fails.
+   We can also use "crashkernel=X,high" to select a high region above
+   DMA zone, which also tries to allocate at least 256M low memory in
+   DMA zone automatically (or the DMA32 zone if CONFIG_ZONE_DMA is disabled).
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if you really have to reserve memory from
+   specified start address X. Note that the start address of the kernel,
+   X if explicitly specified, must be aligned to 2MiB (0x20).
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 526d65d8573a..b2955d9379e8 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -738,6 +738,9 @@
[KNL, X86-64] Select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] Try low allocation in DMA zone (or DMA32 
zone
+   if CONFIG_ZONE_DMA is disabled), fall back to high 
allocation
+   if it fails when '@offset' hasn't been specified.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -754,6 +757,8 @@
Otherwise memory region will be allocated below 4G, if
available.
It will be ignored if crashkernel=X is specified.
+   [KNL, arm64] range in high memory.
+   Allow kernel to allocate physical memory region from 
top.
crashkernel=size[KMG],low
[KNL, X86-64] range under 4G. When crashkernel=X,high
is passed, kernel could allocate physical memory region
@@ -762,13 +767,16 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable

[PATCH v12 6/9] arm64: kdump: reimplement crashkernel=X

2020-09-07 Thread Chen Zhou
There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.
3. Since commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32"),
if the memory reserved for crash dump kernel falled in ZONE_DMA32,
the devices in crash dump kernel need to use ZONE_DMA will alloc
fail.

To solve these issues, change the behavior of crashkernel=X and
introduce crashkernel=X,[high,low].
crashkernel=X tries low allocation in DMA zone, and fall back to
high allocation if it fails.
We can also use "crashkernel=X,high" to select a region above DMA zone,
which also tries to allocate at least 256M in DMA zone automatically.
"crashkernel=Y,low" can be used to allocate specified size low memory.

For non-RPi4 platforms, change DMA zone memtioned above to DMA32 zone.

Another minor change, there may be two regions reserved for crash
dump kernel, in order to distinct from the high region and make no
effect to the use of existing kexec-tools, rename the low region as
"Crash kernel (low)".

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h |  9 +
 arch/arm64/kernel/setup.c  | 13 +++-
 arch/arm64/mm/init.c   | 60 ++
 arch/arm64/mm/mmu.c|  4 +++
 kernel/crash_core.c|  8 +++--
 5 files changed, 34 insertions(+), 60 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 402d208265a3..79909ae5e22e 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -28,7 +28,12 @@
 /* 2M alignment for crash kernel regions */
 #define CRASH_ALIGNSZ_2M
 
+#ifdef CONFIG_ZONE_DMA
+#define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit
+#else
 #define CRASH_ADDR_LOW_MAX arm64_dma32_phys_limit
+#endif
+
 #define CRASH_ADDR_HIGH_MAXMEMBLOCK_ALLOC_ACCESSIBLE
 
 #ifndef __ASSEMBLY__
@@ -96,6 +101,10 @@ static inline void crash_prepare_suspend(void) {}
 static inline void crash_post_resume(void) {}
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+extern void __init reserve_crashkernel(void);
+#endif
+
 #ifdef CONFIG_KEXEC_FILE
 #define ARCH_HAS_KIMAGE_ARCH
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 53acbeca4f57..1b24072f2bae 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,18 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" or "Crash kernel (low)"
+* region in /proc/iomem.
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end) {
+   crashk_low_res.name = "Crash kernel (low)";
+   request_resource(res, _low_res);
+   }
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ad27dc4cc55e..e56a0e5d5b77 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -69,66 +70,11 @@ EXPORT_SYMBOL(vmemmap);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
-#ifdef CONFIG_KEXEC_CORE
-/*
- * reserve_crashkernel() - reserves memory for crash kernel
- *
- * This function reserves memory area given in "crashkernel=" kernel command
- * line parameter. The memory reserved is used by dump capture kernel when
- * primary kernel is crashing.
- */
-static void __init reserve_crashkernel(void)
-{
-   unsigned long long crash_base, crash_size;
-   int ret;
-
-   ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
-   _size, _base);
-   /* no crashkernel= or invalid value specified */
-   if (ret || !crash_size)
-   return;
-
-   crash_size = PAGE_ALIGN(crash_size);
-
-   if (crash_base == 0) {
-   /* Current arm64 boot protocol requires 2MB alignment */
-   c

[PATCH v12 8/9] arm64: kdump: add memory for devices by DT property linux, usable-memory-range

2020-09-07 Thread Chen Zhou
When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices and never mapped by the first kernel.
This memory range is advertised to crash dump kernel via DT property
under /chosen,
linux,usable-memory-range = 

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index e56a0e5d5b77..2af8c38279d9 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -76,6 +76,15 @@ static void __init reserve_crashkernel(void)
 }
 #endif
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now there may
+ * be two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES  2
+
 #ifdef CONFIG_CRASH_DUMP
 static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
const char *uname, int depth, void *data)
@@ -191,9 +200,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_region *usable_rgns = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -202,22 +211,36 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   usable_rgns[nr].base = dt_mem_next_cell(dt_root_addr_cells, 
);
+   usable_rgns[nr].size = dt_mem_next_cell(dt_root_size_cells, 
);
+
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_rgns[MAX_USABLE_RANGES] = {
+   { .size = 0 },
+   { .size = 0 }
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, _rgns);
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   /*
+* The first range of usable-memory regions is for crash dump
+* kernel with only one region or for high region with two regions,
+* the second range is dedicated for low region if exist.
+*/
+   if (usable_rgns[0].size)
+   memblock_cap_memory_range(usable_rgns[0].base, 
usable_rgns[0].size);
+   if (usable_rgns[1].size)
+   memblock_add(usable_rgns[1].base, usable_rgns[1].size);
 }
 
 void __init arm64_memblock_init(void)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v12 3/9] x86: kdump: use macro CRASH_ADDR_LOW_MAX in functions reserve_crashkernel[_low]()

2020-09-07 Thread Chen Zhou
To make the functions reserve_crashkernel[_low]() as generic,
replace some hard-coded numbers with macro CRASH_ADDR_LOW_MAX.

Signed-off-by: Chen Zhou 
---
 arch/x86/kernel/setup.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d7fd90c52dae..71a6a6e7ca5b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -430,7 +430,7 @@ static int __init reserve_crashkernel_low(void)
unsigned long total_low_mem;
int ret;
 
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
+   total_low_mem = memblock_mem_size(CRASH_ADDR_LOW_MAX >> PAGE_SHIFT);
 
/* crashkernel=Y,low */
ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
@@ -451,7 +451,7 @@ static int __init reserve_crashkernel_low(void)
return 0;
}
 
-   low_base = memblock_find_in_range(CRASH_ALIGN, 1ULL << 32, low_size, 
CRASH_ALIGN);
+   low_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_LOW_MAX, 
low_size, CRASH_ALIGN);
if (!low_base) {
pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
   (unsigned long)(low_size >> 20));
@@ -504,8 +504,9 @@ static void __init reserve_crashkernel(void)
if (!crash_base) {
/*
 * Set CRASH_ADDR_LOW_MAX upper bound for crash memory,
-* crashkernel=x,high reserves memory over 4G, also allocates
-* 256M extra low memory for DMA buffers and swiotlb.
+* crashkernel=x,high reserves memory over CRASH_ADDR_LOW_MAX,
+* 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.
@@ -539,7 +540,7 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+   if (crash_base >= CRASH_ADDR_LOW_MAX && reserve_crashkernel_low()) {
memblock_free(crash_base, crash_size);
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v12 0/9] support reserving crashkernel above 4G on arm64 kdump

2020-09-07 Thread Chen Zhou
n a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-June/020737.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213
[v9]: https://lkml.org/lkml/2020/6/28/73
[v10]: https://lkml.org/lkml/2020/7/2/1443
[v11]: https://lkml.org/lkml/2020/8/1/150

Chen Zhou (9):
  x86: kdump: move CRASH_ALIGN to 2M
  x86: kdump: make the lower bound of crash kernel reservation
consistent
  x86: kdump: use macro CRASH_ADDR_LOW_MAX in functions
reserve_crashkernel[_low]()
  x86: kdump: move reserve_crashkernel[_low]() into crash_core.c
  arm64: kdump: introduce some macroes for crash kernel reservation
  arm64: kdump: reimplement crashkernel=X
  kdump: add threshold for the required memory
  arm64: kdump: add memory for devices by DT property
linux,usable-memory-range
  kdump: update Documentation about crashkernel

 Documentation/admin-guide/kdump/kdump.rst |  25 ++-
 .../admin-guide/kernel-parameters.txt |  13 +-
 arch/arm64/include/asm/kexec.h|  15 ++
 arch/arm64/include/asm/processor.h|   1 +
 arch/arm64/kernel/setup.c |  13 +-
 arch/arm64/mm/init.c  | 105 --
 arch/arm64/mm/mmu.c   |   4 +
 arch/x86/include/asm/kexec.h  |  28 +++
 arch/x86/kernel/setup.c   | 165 +--
 include/linux/crash_core.h|   4 +
 include/linux/kexec.h |   2 -
 kernel/crash_core.c   | 192 ++
 kernel/kexec_core.c   |  17 --
 13 files changed, 328 insertions(+), 256 deletions(-)

-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v12 4/9] x86: kdump: move reserve_crashkernel[_low]() into crash_core.c

2020-09-07 Thread Chen Zhou
Make the functions reserve_crashkernel[_low]() as generic.
Arm64 will use these to reimplement crashkernel=X.

There is no functional change.

Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/kexec.h |  25 +
 arch/x86/kernel/setup.c  | 163 +--
 include/linux/crash_core.h   |   4 +
 include/linux/kexec.h|   2 -
 kernel/crash_core.c  | 179 +++
 kernel/kexec_core.c  |  17 
 6 files changed, 210 insertions(+), 180 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 83f200dd54a1..adf5e9a016bd 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -21,6 +21,27 @@
 /* 2M alignment for crash kernel regions */
 #define CRASH_ALIGNSZ_2M
 
+/*
+ * Keep the crash kernel below this limit.
+ *
+ * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
+ * due to mapping restrictions.
+ *
+ * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
+ * the upper limit of system RAM in 4-level paging mode. Since the kdump
+ * jump could be from 5-level paging to 4-level paging, the jump will fail if
+ * the kernel is put above 64 TB, and during the 1st kernel bootup there's
+ * no good way to detect the paging mode of the target kernel which will be
+ * loaded for dumping.
+ */
+#ifdef CONFIG_X86_32
+# define CRASH_ADDR_LOW_MAXSZ_512M
+# define CRASH_ADDR_HIGH_MAX   SZ_512M
+#else
+# define CRASH_ADDR_LOW_MAXSZ_4G
+# define CRASH_ADDR_HIGH_MAX   SZ_64T
+#endif
+
 #ifndef __ASSEMBLY__
 
 #include 
@@ -200,6 +221,10 @@ typedef void crash_vmclear_fn(void);
 extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss;
 extern void kdump_nmi_shootdown_cpus(void);
 
+#ifdef CONFIG_KEXEC_CORE
+extern void __init reserve_crashkernel(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_KEXEC_H */
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 71a6a6e7ca5b..927ba83e8da4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -22,8 +22,6 @@
 
 #include 
 
-#include 
-
 #include 
 #include 
 #include 
@@ -35,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -396,165 +395,7 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
}
 }
 
-/*
- * - Crashkernel reservation --
- */
-
-#ifdef CONFIG_KEXEC_CORE
-
-/*
- * Keep the crash kernel below this limit.
- *
- * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
- * due to mapping restrictions.
- *
- * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
- * the upper limit of system RAM in 4-level paging mode. Since the kdump
- * jump could be from 5-level paging to 4-level paging, the jump will fail if
- * the kernel is put above 64 TB, and during the 1st kernel bootup there's
- * no good way to detect the paging mode of the target kernel which will be
- * loaded for dumping.
- */
-#ifdef CONFIG_X86_32
-# define CRASH_ADDR_LOW_MAXSZ_512M
-# define CRASH_ADDR_HIGH_MAX   SZ_512M
-#else
-# define CRASH_ADDR_LOW_MAXSZ_4G
-# define CRASH_ADDR_HIGH_MAX   SZ_64T
-#endif
-
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(CRASH_ADDR_LOW_MAX >> PAGE_SHIFT);
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_LOW_MAX, 
low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at

[PATCH v12 9/9] kdump: update Documentation about crashkernel

2020-09-07 Thread Chen Zhou
For arm64, the behavior of crashkernel=X has been changed, which
tries low allocation in DMA zone, and fall back to high allocation
if it fails.
We can also use "crashkernel=X,high" to select a high region above
DMA zone, which also tries to allocate at least 256M low memory in
DMA zone automatically.
"crashkernel=Y,low" can be used to allocate specified size low memory
in DMA zone.
For non-RPi4 platforms, change DMA zone memtioned above to DMA32 zone.

For x86 and arm64, we introduce threshold for the required memory.
if required size X is too large and leads to very little free low
memory after low allocation, the system may not work well.
So add a threshold and go for high allocation directly if the required
size is too large. The threshold is set as the half of low memory.

So update the Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kdump/kdump.rst | 25 ---
 .../admin-guide/kernel-parameters.txt | 13 --
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index 2da65fef2a1c..549611abc581 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,16 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=X" to select a region under 4G first, and
+   fall back to reserve region above 4G. And go for high allocation
+   directly if the required size is too large.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if you really have to reserve memory from specified
+   start address X.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +325,18 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
-   the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   On arm64, use "crashkernel=X" to try low allocation in DMA zone, and
+   fall back to high allocation if it fails. And go for high allocation
+   directly if the required size is too large.
+   We can also use "crashkernel=X,high" to select a high region above
+   DMA zone, which also tries to allocate at least 256M low memory in
+   DMA zone automatically.
+   "crashkernel=Y,low" can be used to allocate specified size low memory
+   in DMA zone.
+   For non-RPi4 platforms, change DMA zone memtioned above to DMA32 zone.
+   Use "crashkernel=Y@X" if you really have to reserve memory from
+   specified start address X. Note that the start address of the kernel,
+   X if explicitly specified, must be aligned to 2MiB (0x20).
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index a1068742a6df..f7df572d8f64 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -727,6 +727,10 @@
[KNL, X86-64] Select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] Try low allocation in DMA zone, fall back
+   to high allocation if it fails when '@offset' hasn't 
been
+   specified. For non-RPi4 platforms, change DMA zone to
+   DMA32 zone.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -743,6 +747,8 @@
Otherwise memory region will be allocated below 4G, if
available.
It will be ignored if crashkernel=X is specified.
+   [KNL, arm64] range in high memory.
+   Allow kernel to allocate physical memory region from 
top.
crashkernel=size[KMG],low
[KNL, X86-64] range under 4G. When crashkernel=X,high
is passed, kernel could allocate physical memory region
@@ -751,13 +757,16 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sur

[PATCH v12 5/9] arm64: kdump: introduce some macroes for crash kernel reservation

2020-09-07 Thread Chen Zhou
Introduce macro CRASH_ALIGN for alignment, macro CRASH_ADDR_LOW_MAX
for upper bound of low crash memory, macro CRASH_ADDR_HIGH_MAX for
upper bound of high crash memory, use macroes instead.

Besides, keep consistent with x86, use CRASH_ALIGN as the lower bound
of crash kernel reservation.

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h | 6 ++
 arch/arm64/include/asm/processor.h | 1 +
 arch/arm64/mm/init.c   | 8 
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index d24b527e8c00..402d208265a3 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -25,6 +25,12 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
+#define CRASH_ADDR_LOW_MAX arm64_dma32_phys_limit
+#define CRASH_ADDR_HIGH_MAXMEMBLOCK_ALLOC_ACCESSIBLE
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/include/asm/processor.h 
b/arch/arm64/include/asm/processor.h
index 240fe5e5b720..af71063f352c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -95,6 +95,7 @@
 #endif /* CONFIG_ARM64_FORCE_52BIT */
 
 extern phys_addr_t arm64_dma_phys_limit;
+extern phys_addr_t arm64_dma32_phys_limit;
 #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1)
 
 struct debug_info {
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 481d22c32a2e..ad27dc4cc55e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL(vmemmap);
  * bit addressable memory area.
  */
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
-static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
+phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
 /*
@@ -92,8 +92,8 @@ static void __init reserve_crashkernel(void)
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(CRASH_ALIGN, 
CRASH_ADDR_LOW_MAX,
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -111,7 +111,7 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v12 7/9] kdump: add threshold for the required memory

2020-09-07 Thread Chen Zhou
For crashkernel=X, if required size X is too large and leads to very
little free low memory after low allocation, the system may not work
normally.
So add a threshold and go for high allocation directly if the required
size is too large. The value of threshold is set as the half of the
low memory.

Signed-off-by: Chen Zhou 
---
 kernel/crash_core.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 3f735cb37ace..d11d597a470d 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -378,6 +378,15 @@ int __init reserve_crashkernel_low(void)
 }
 
 #if defined(CONFIG_X86) || defined(CONFIG_ARM64)
+
+/*
+ * Add a threshold for required memory size of crashkernel. If required memory
+ * size is greater than threshold, just go for high allocation directly. The
+ * value of threshold is set as half of the total low memory.
+ */
+#define REQUIRED_MEMORY_THRESHOLD  (memblock_mem_size(CRASH_ADDR_LOW_MAX 
>> \
+   PAGE_SHIFT) >> 1)
+
 #ifdef CONFIG_KEXEC_CORE
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
@@ -422,7 +431,7 @@ void __init reserve_crashkernel(void)
 * So try low memory first and fall back to high memory
 * unless "crashkernel=size[KMG],high" is specified.
 */
-   if (!high)
+   if (!high && crash_size <= REQUIRED_MEMORY_THRESHOLD)
crash_base = memblock_find_in_range(CRASH_ALIGN,
CRASH_ADDR_LOW_MAX,
crash_size, CRASH_ALIGN);
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v12 2/9] x86: kdump: make the lower bound of crash kernel reservation consistent

2020-09-07 Thread Chen Zhou
The lower bounds of crash kernel reservation and crash kernel low
reservation are different, use the consistent value CRASH_ALIGN.

Suggested-by: Dave Young 
Signed-off-by: Chen Zhou 
---
 arch/x86/kernel/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 296294ad0dd8..d7fd90c52dae 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -451,7 +451,7 @@ static int __init reserve_crashkernel_low(void)
return 0;
}
 
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
+   low_base = memblock_find_in_range(CRASH_ALIGN, 1ULL << 32, low_size, 
CRASH_ALIGN);
if (!low_base) {
pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
   (unsigned long)(low_size >> 20));
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v12 1/9] x86: kdump: move CRASH_ALIGN to 2M

2020-09-07 Thread Chen Zhou
CONFIG_PHYSICAL_ALIGN can be selected from 2M to 16M and default
value is 2M, so move CRASH_ALIGN to 2M, with smaller value reservation
can have more chance to succeed.
And replace the hard-coded alignment with macro CRASH_ALIGN in function
reserve_crashkernel().

Suggested-by: Dave Young 
Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/kexec.h | 3 +++
 arch/x86/kernel/setup.c  | 5 +
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 6802c59e8252..83f200dd54a1 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,9 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 3511736fbc74..296294ad0dd8 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -402,9 +402,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
-
 /*
  * Keep the crash kernel below this limit.
  *
@@ -530,7 +527,7 @@ static void __init reserve_crashkernel(void)
 
start = memblock_find_in_range(crash_base,
   crash_base + crash_size,
-  crash_size, 1 << 20);
+  crash_size, CRASH_ALIGN);
if (start != crash_base) {
pr_info("crashkernel reservation failed - memory is in 
use.\n");
return;
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v11 5/5] kdump: update Documentation about crashkernel

2020-08-01 Thread Chen Zhou
Now the behavior of crashkernel=X has been changed, which tries low
allocation in ZONE_DMA, and fall back to high allocation if it fails.

If requized size X is too large and leads to very little free memory
in ZONE_DMA after low allocation, the system may not work well.
So add a threshold and go for high allocation directly if the required
size is too large. The threshold is set as the half of low memory.

If crash_base is outside ZONE_DMA, try to allocate at least 256M in
ZONE_DMA automatically. "crashkernel=Y,low" can be used to allocate
specified size low memory. For non-RPi4 platforms, change ZONE_DMA
memtioned above to ZONE_DMA32.

So update the Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kdump/kdump.rst | 21 ---
 .../admin-guide/kernel-parameters.txt | 11 --
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index 2da65fef2a1c..4b58f97351d5 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,15 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=X" to select a region under 4G first, and
+   fall back to reserve region above 4G.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if you really have to reserve memory from specified
+   start address X.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +324,15 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
-   the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   On arm64, use "crashkernel=X" to try low allocation in ZONE_DMA, and
+   fall back to high allocation if it fails. And go for high allocation
+   directly if the required size is too large. If crash_base is outside
+   ZONE_DMA, try to allocate at least 256M in ZONE_DMA automatically.
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   For non-RPi4 platforms, change ZONE_DMA memtioned above to ZONE_DMA32.
+   Use "crashkernel=Y@X" if you really have to reserve memory from
+   specified start address X. Note that the start address of the kernel,
+   X if explicitly specified, must be aligned to 2MiB (0x20).
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index fb95fad81c79..d1b6016850d6 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -722,6 +722,10 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] Try low allocation in ZONE_DMA, fall back
+   to high allocation if it fails when '@offset' hasn't 
been
+   specified. For non-RPi4 platforms, change ZONE_DMA to
+   ZONE_DMA32.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -746,13 +750,16 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
-
+   [KNL, arm64] range under 4G.
+   This one let user to specify a low range in ZONE_DMA for
+   crash dump kernel. For non-RPi4 platforms, change 
ZONE_DMA
+   to ZONE_DMA32.
cryptomgr.notests
[KNL] Disable 

[PATCH v11 0/5] support reserving crashkernel above 4G on arm64 kdump

2020-08-01 Thread Chen Zhou
There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.
3. Since commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32"),
if the memory reserved for crash dump kernel falled in ZONE_DMA32,
the devices in crash dump kernel need to use ZONE_DMA will alloc
fail.

To solve these issues, change the behavior of crashkernel=X.
crashkernel=X tries low allocation in ZONE_DMA, and fall back to
high allocation if it fails.

If requized size X is too large and leads to very little free memory
in ZONE_DMA after low allocation, the system may not work normally.
So add a threshold and go for high allocation directly if the required
size is too large. The value of threshold is set as the half of
the low memory.

If crash_base is outside ZONE_DMA, try to allocate at least 256M in
ZONE_DMA automatically. "crashkernel=Y,low" can be used to allocate
specified size low memory.
For non-RPi4 platforms, change ZONE_DMA memtioned above to ZONE_DMA32.

When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices. So there may be two regions reserved for
crash dump kernel, one is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use
of existing kexec-tools, rename the low region as "Crash kernel (low)",
and pass the low region by reusing DT property
"linux,usable-memory-range". We made the low memory region as the last
range of "linux,usable-memory-range" to keep compatibility with existing
user-space and older kdump kernels.

Besides, we need to modify kexec-tools:
arm64: support more than one crash kernel regions(see [1])

Another update is document about DT property 'linux,usable-memory-range':
schemas: update 'linux,usable-memory-range' node schema(see [2])

Changes since [v10]
- Reimplement crashkernel=X suggested by Catalin, Many thanks to Catalin.

Changes since [v9]
- Patch 1 add Acked-by from Dave.
- Update patch 5 according to Dave's comments.
- Update chosen schema.

Changes since [v8]
- Reuse DT property "linux,usable-memory-range".
Suggested by Rob, reuse DT property "linux,usable-memory-range" to pass the low
memory region.
- Fix kdump broken with ZONE_DMA reintroduced.
- Update chosen schema.

Changes since [v7]
- Move x86 CRASH_ALIGN to 2M
Suggested by Dave and do some test, move x86 CRASH_ALIGN to 2M.
- Update Documentation/devicetree/bindings/chosen.txt.
Add corresponding documentation to Documentation/devicetree/bindings/chosen.txt
suggested by Arnd.
- Add Tested-by from Jhon and pk.

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-June/020737.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213
[v9]: https://lkml.org/lkml/2020/6/28/73
[v10]: https://lkml.org/lkml/2020/7/2/1443

Chen Zhou (5):
  arm64: kdump: add macro CRASH_ALIGN and CRASH_ADDR_LOW_MAX
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reimplement crashkernel=X
  arm64: kdump: add memory for devices by DT property
linux,usable-mem

[PATCH v11 4/5] arm64: kdump: add memory for devices by DT property linux, usable-memory-range

2020-08-01 Thread Chen Zhou
When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices and never mapped by the first kernel.
This memory range is advertised to crash dump kernel via DT property
under /chosen,
linux,usable-memory-range = 

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 44 ++--
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 53c8916fd32f..f385a8281d1b 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -69,6 +69,16 @@ EXPORT_SYMBOL(vmemmap);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now there may
+ * be two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES  2
+
+
 #ifdef CONFIG_KEXEC_CORE
 
 /*
@@ -286,9 +296,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_region *usable_rgns = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -297,22 +307,36 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   usable_rgns[nr].base = dt_mem_next_cell(dt_root_addr_cells, 
);
+   usable_rgns[nr].size = dt_mem_next_cell(dt_root_size_cells, 
);
+
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_rgns[MAX_USABLE_RANGES] = {
+   { .size = 0 },
+   { .size = 0 }
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, _rgns);
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   /*
+* The first range of usable-memory regions is for crash dump
+* kernel with only one region or for high region with two regions,
+* the second range is dedicated for low region if exist.
+*/
+   if (usable_rgns[0].size)
+   memblock_cap_memory_range(usable_rgns[0].base, 
usable_rgns[0].size);
+   if (usable_rgns[1].size)
+   memblock_add(usable_rgns[1].base, usable_rgns[1].size);
 }
 
 void __init arm64_memblock_init(void)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v11 2/5] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-08-01 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.

BTW, move x86_64 CRASH_ALIGN to 2M suggested by Dave. CONFIG_PHYSICAL_ALIGN
can be selected from 2M to 16M, move to the same as arm64.

Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/kexec.h | 24 ++
 arch/x86/kernel/setup.c  | 86 +++-
 include/linux/crash_core.h   |  3 ++
 include/linux/kexec.h|  2 -
 kernel/crash_core.c  | 74 +++
 kernel/kexec_core.c  | 17 ---
 6 files changed, 107 insertions(+), 99 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 6802c59e8252..f8f9d952e09f 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,30 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
+/*
+ * Keep the crash kernel below this limit.
+ *
+ * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
+ * due to mapping restrictions.
+ *
+ * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
+ * the upper limit of system RAM in 4-level paging mode. Since the kdump
+ * jump could be from 5-level paging to 4-level paging, the jump will fail if
+ * the kernel is put above 64 TB, and during the 1st kernel bootup there's
+ * no good way to detect the paging mode of the target kernel which will be
+ * loaded for dumping.
+ */
+#ifdef CONFIG_X86_32
+# define CRASH_ADDR_LOW_MAXSZ_512M
+# define CRASH_ADDR_HIGH_MAX   SZ_512M
+#else
+# define CRASH_ADDR_LOW_MAXSZ_4G
+# define CRASH_ADDR_HIGH_MAX   SZ_64T
+#endif
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a3767e74c758..46763c1e5d9f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -401,83 +401,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
-
-/*
- * Keep the crash kernel below this limit.
- *
- * Earlier 32-bits kernels would limit the kernel to the low 512 MB range
- * due to mapping restrictions.
- *
- * 64-bit kdump kernels need to be restricted to be under 64 TB, which is
- * the upper limit of system RAM in 4-level paging mode. Since the kdump
- * jump could be from 5-level paging to 4-level paging, the jump will fail if
- * the kernel is put above 64 TB, and during the 1st kernel bootup there's
- * no good way to detect the paging mode of the target kernel which will be
- * loaded for dumping.
- */
-#ifdef CONFIG_X86_32
-# define CRASH_ADDR_LOW_MAXSZ_512M
-# define CRASH_ADDR_HIGH_MAX   SZ_512M
-#else
-# define CRASH_ADDR_LOW_MAXSZ_4G
-# define CRASH_ADDR_HIGH_MAX   SZ_64T
-#endif
-
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   ins

[PATCH v11 3/5] arm64: kdump: reimplement crashkernel=X

2020-08-01 Thread Chen Zhou
There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.
3. Since commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32"),
if the memory reserved for crash dump kernel falled in ZONE_DMA32,
the devices in crash dump kernel need to use ZONE_DMA will alloc
fail.

To solve these issues, change the behavior of crashkernel=X.
crashkernel=X tries low allocation in ZONE_DMA, and fall back to
high allocation if it fails.

If requized size X is too large and leads to very little free memory
in ZONE_DMA after low allocation, the system may not work normally.
So add a threshold and go for high allocation directly if the required
size is too large. The value of threshold is set as the half of
the low memory.

If crash_base is outside ZONE_DMA, try to allocate at least 256M in
ZONE_DMA automatically. "crashkernel=Y,low" can be used to allocate
specified size low memory.

For non-RPi4 platforms, change ZONE_DMA memtioned above to ZONE_DMA32.

Another minor change, there may be two regions reserved for crash
dump kernel, in order to distinct from the high region and make no
effect to the use of existing kexec-tools, rename the low region as
"Crash kernel (low)".

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h |  4 +++
 arch/arm64/kernel/setup.c  |  8 +-
 arch/arm64/mm/init.c   | 51 ++
 3 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 1a2f27f12794..92ed53d0bf21 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -28,7 +28,11 @@
 /* 2M alignment for crash kernel regions */
 #define CRASH_ALIGNSZ_2M
 
+#ifdef CONFIG_ZONE_DMA
+#define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit
+#else
 #define CRASH_ADDR_LOW_MAX arm64_dma32_phys_limit
+#endif
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 93b3844cf442..4dc51a2ac012 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index a3d0193f6a0a..53c8916fd32f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -70,6 +70,14 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
+
+/*
+ * Add a threshold for required memory size of crashkernel. If required memory
+ * size is greater than threshold, just go for high allocation directly. The
+ * value of threshold is set as half of the total low memory.
+ */
+#define REQUIRED_MEMORY_THRESHOLD  (memblock_mem_size(CRASH_ADDR_LOW_MAX 
>> \
+   PAGE_SHIFT) >> 1)
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -90,11 +98,22 @@ static void __init reserve_crashkernel(void)
 
crash_size = PAGE_ALIGN(crash_size);
 
-   if (crash_base == 0) {
-   /* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, CRASH_ADDR_LOW_MAX,
-   crash_size, CRASH_ALIGN);
-   if (crash_base == 0) {
+   if (!crash_base) {
+   /*
+* Current arm64 boot protocol requires 2MB alignment.
+* If required memory size is greater than threshold, just go
+* for high allocation directly.
+* If required memory size is less than or equal to threshold,
+* try low allocation firstly, and then fall back to high 
allocation
+* if it fails.
+*/
+   if (crash_size <= REQUIRED_MEMORY_THRESHOLD)
+   crash_base = memblock_find_in_range(0, 
CRASH_ADDR_LOW_MAX,
+ 

[PATCH v11 1/5] arm64: kdump: add macro CRASH_ALIGN and CRASH_ADDR_LOW_MAX

2020-08-01 Thread Chen Zhou
Expose variable arm64_dma32_phys_limit for followup, and add macro
CRASH_ALIGN for alignment, macro CRASH_ADDR_LOW_MAX for upper bound
of low crash memory. Use macros instead.

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h | 5 +
 arch/arm64/include/asm/processor.h | 1 +
 arch/arm64/mm/init.c   | 8 
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index d24b527e8c00..1a2f27f12794 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -25,6 +25,11 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
+#define CRASH_ADDR_LOW_MAX arm64_dma32_phys_limit
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/include/asm/processor.h 
b/arch/arm64/include/asm/processor.h
index 240fe5e5b720..af71063f352c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -95,6 +95,7 @@
 #endif /* CONFIG_ARM64_FORCE_52BIT */
 
 extern phys_addr_t arm64_dma_phys_limit;
+extern phys_addr_t arm64_dma32_phys_limit;
 #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1)
 
 struct debug_info {
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1e93cfc7c47a..a3d0193f6a0a 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL(vmemmap);
  * bit addressable memory area.
  */
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
-static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
+phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
 /*
@@ -92,8 +92,8 @@ static void __init reserve_crashkernel(void)
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, CRASH_ADDR_LOW_MAX,
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -111,7 +111,7 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v10 1/5] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-07-02 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.

BTW, move x86_64 CRASH_ALIGN to 2M suggested by Dave. CONFIG_PHYSICAL_ALIGN
can be selected from 2M to 16M, move to the same as arm64.

Note, in arm64, we reserve low memory if and only if crashkernel=X,low
is specified. Different with x86_64, don't set low memory automatically.

Reported-by: kbuild test robot 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
Acked-by: Dave Young 
---
 arch/x86/kernel/setup.c| 66 -
 include/linux/crash_core.h |  3 ++
 include/linux/kexec.h  |  2 -
 kernel/crash_core.c| 85 ++
 kernel/kexec_core.c| 17 
 5 files changed, 96 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a3767e74c758..33db99ae3035 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -401,8 +401,8 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
 
 /*
  * Keep the crash kernel below this limit.
@@ -425,59 +425,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   SZ_64T
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -541,9 +488,12 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 525510a9f965..4df8c0bff03e 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -63,6 +63,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 extern unsigned char *vmcoreinfo_data;
 extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
+extern struct resource crashk_res;
+extern struct resource crashk_low_res;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
  void *data, size_t data_len);
@@ -74,5 +76,6 @@ int parse_crashkernel_high(char *cmdline, uns

[PATCH v10 5/5] kdump: update Documentation about crashkernel on arm64

2020-07-02 Thread Chen Zhou
Now we support crashkernel=X,[low] on arm64, update the Documentation.
We could use parameters "crashkernel=X crashkernel=Y,low" to reserve
memory above 4G.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 Documentation/admin-guide/kdump/kdump.rst   | 14 --
 Documentation/admin-guide/kernel-parameters.txt | 17 +++--
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index 2da65fef2a1c..e80fc9e28a9a 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,15 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=Y" to select a region under 4G first, and
+   fall back to reserve region above 4G.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y@X" if we really have to reserve memory from specified
+   start address X.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +324,10 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   On arm64, use "crashkernel=Y[@X]". Note that the start address of
the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   If crashkernel=Z,low is specified simultaneously, reserve spcified size
+   low memory firstly and then reserve memory above 4G.
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index fb95fad81c79..58a731eed011 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -722,6 +722,9 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] If crashkernel=X,low is specified, reserve
+   spcified size low memory firstly, and then reserve 
memory
+   above 4G.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -746,13 +749,23 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
-
+   [KNL, arm64] range under 4G.
+   This one let user to specify own low range under 4G
+   for crash dump kernel instead.
+   Be different from x86_64, kernel reserves specified size
+   physical memory region only when this parameter is 
specified
+   instead of trying to reserve at least 256M below 4G
+   automatically.
+   Use this parameter along with crashkernel=X when we want
+   to reserve crashkernel above 4G. If there are devices
+   need to use ZONE_DMA in crash dump kernel, it is also
+   a good choice.
cryptomgr.notests
[KNL] Disable crypto self-tests
 
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v10 0/5] support reserving crashkernel above 4G on arm64 kdump

2020-07-02 Thread Chen Zhou
This patch series enable reserving crashkernel above 4G in arm64.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are required, crash dump kernel
will boot failure because there is no low memory available for allocation.
3. commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32") broken
the arm64 kdump. If the memory reserved for crash dump kernel falled in
ZONE_DMA32, the devices in crash dump kernel need to use ZONE_DMA will alloc
fail.

To solve these issues, introduce crashkernel=X,low to reserve specified
size low memory.
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

When crashkernel is reserved above 4G in memory and crashkernel=X,low
is specified simultaneously, kernel should reserve specified size low memory
for crash dump kernel devices. So there may be two crash kernel regions, one
is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use of
kexec-tools, rename the low region as "Crash kernel (low)", and pass the
low region by reusing DT property "linux,usable-memory-range". We made the low
memory region as the last range of "linux,usable-memory-range" to keep
compatibility with existing user-space and older kdump kernels.

Besides, we need to modify kexec-tools:
arm64: support more than one crash kernel regions(see [1])

Another update is document about DT property 'linux,usable-memory-range':
schemas: update 'linux,usable-memory-range' node schema(see [2])

The previous changes and discussions can be retrieved from:

Changes since [v9]
- Patch 1 add Acked-by from Dave.
- Update patch 5 according to Dave's comments.
- Update chosen schema.

Changes since [v8]
- Reuse DT property "linux,usable-memory-range".
Suggested by Rob, reuse DT property "linux,usable-memory-range" to pass the low
memory region.
- Fix kdump broken with ZONE_DMA reintroduced.
- Update chosen schema.

Changes since [v7]
- Move x86 CRASH_ALIGN to 2M
Suggested by Dave and do some test, move x86 CRASH_ALIGN to 2M.
- Update Documentation/devicetree/bindings/chosen.txt.
Add corresponding documentation to Documentation/devicetree/bindings/chosen.txt
suggested by Arnd.
- Add Tested-by from Jhon and pk.

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-June/020737.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213
[v9]: https://lkml.org/lkml/2020/6/28/73

Chen Zhou (5):
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reserve crashkenel above 4G for crash dump kernel
  arm64: kdump: add memory for devices by DT property
linux,usable-memory-range
  arm64: kdump: fix kdump broken with ZONE_DMA reintroduced
  kdump: update Documentation about crashkernel on arm64

 Documentation/admin-guide/kdump/kdump.rst | 14 ++-
 .../admin-guide/kernel-parameters.txt | 17 +++-
 arch/arm64/kernel/setup.c 

[PATCH v10 3/5] arm64: kdump: add memory for devices by DT property linux, usable-memory-range

2020-07-02 Thread Chen Zhou
If we want to reserve crashkernel above 4G, we could use parameters
"crashkernel=X crashkernel=Y,low", in this case, specified size low
memory is reserved for crash dump kernel devices and never mapped by
the first kernel. This memory range is advertised to crash dump kernel
via DT property under /chosen,
linux,usable-memory-range = 

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/arm64/mm/init.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ce7ced85f5fb..f5b31e8f1f34 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -69,6 +69,15 @@ EXPORT_SYMBOL(vmemmap);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now crash dump
+ * kernel support at most two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES  2
+
 #ifdef CONFIG_KEXEC_CORE
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
@@ -272,9 +281,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_region *usable_rgns = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -283,22 +292,36 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   usable_rgns[nr].base = dt_mem_next_cell(dt_root_addr_cells, 
);
+   usable_rgns[nr].size = dt_mem_next_cell(dt_root_size_cells, 
);
+
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_rgns[MAX_USABLE_RANGES] = {
+   { .size = 0 },
+   { .size = 0 }
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, _rgns);
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   /*
+* The first range of usable-memory regions is for crash dump
+* kernel with only one region or for high region with two regions,
+* the second range is dedicated for low region if exist.
+*/
+   if (usable_rgns[0].size)
+   memblock_cap_memory_range(usable_rgns[0].base, 
usable_rgns[0].size);
+   if (usable_rgns[1].size)
+   memblock_add(usable_rgns[1].base, usable_rgns[1].size);
 }
 
 void __init arm64_memblock_init(void)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v10 4/5] arm64: kdump: fix kdump broken with ZONE_DMA reintroduced

2020-07-02 Thread Chen Zhou
commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32")
broken the arm64 kdump. If the memory reserved for crash dump kernel
falled in ZONE_DMA32, the devices in crash dump kernel need to use
ZONE_DMA will alloc fail.

This patch addressed the above issue based on "reserving crashkernel
above 4G". Originally, we reserve low memory below 4G, and now just need
to adjust memory limit to arm64_dma_phys_limit in reserve_crashkernel_low
if ZONE_DMA is enabled. That is, if there are devices need to use ZONE_DMA
in crash dump kernel, it is a good choice to use parameters
"crashkernel=X crashkernel=Y,low".

Signed-off-by: Chen Zhou 
---
 kernel/crash_core.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index a7580d291c37..e8ecbbc761a3 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -320,6 +320,7 @@ int __init reserve_crashkernel_low(void)
unsigned long long base, low_base = 0, low_size = 0;
unsigned long total_low_mem;
int ret;
+   phys_addr_t crash_max = 1ULL << 32;
 
total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
 
@@ -352,7 +353,11 @@ int __init reserve_crashkernel_low(void)
return 0;
}
 
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
+#ifdef CONFIG_ARM64
+   if (IS_ENABLED(CONFIG_ZONE_DMA))
+   crash_max = arm64_dma_phys_limit;
+#endif
+   low_base = memblock_find_in_range(0, crash_max, low_size, CRASH_ALIGN);
if (!low_base) {
pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
   (unsigned long)(low_size >> 20));
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v10 2/5] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2020-07-02 Thread Chen Zhou
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

Suggested by James, just introduced crashkernel=X,low to arm64. As memtioned
above, if crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G, which is much simpler.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/arm64/kernel/setup.c |  8 +++-
 arch/arm64/mm/init.c  | 31 +--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 93b3844cf442..4dc51a2ac012 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1e93cfc7c47a..ce7ced85f5fb 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -81,6 +81,7 @@ static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
int ret;
+   phys_addr_t crash_max = arm64_dma32_phys_limit;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
@@ -88,12 +89,38 @@ static void __init reserve_crashkernel(void)
if (ret || !crash_size)
return;
 
+   ret = reserve_crashkernel_low();
+   if (!ret && crashk_low_res.end) {
+   /*
+* If crashkernel=X,low specified, there may be two regions,
+* we need to make some changes as follows:
+*
+* 1. rename the low region as "Crash kernel (low)"
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*
+* 2. change the upper bound for crash memory
+* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash memory.
+*
+* 3. mark the low region as "nomap"
+* The low region is intended to be used for crash dump kernel
+* devices, just mark the low region as "nomap" simply.
+*/
+   const char *rename = "Crash kernel (low)";
+
+   crashk_low_res.name = rename;
+   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
+   memblock_mark_nomap(crashk_low_res.start,
+   resource_size(_low_res));
+   }
+
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, crash_max, crash_size,
+   SZ_2M);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v9 2/5] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2020-06-28 Thread Chen Zhou
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

Suggested by James, just introduced crashkernel=X,low to arm64. As memtioned
above, if crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G, which is much simpler.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/arm64/kernel/setup.c |  8 +++-
 arch/arm64/mm/init.c  | 31 +--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 93b3844cf442..4dc51a2ac012 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1e93cfc7c47a..ce7ced85f5fb 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -81,6 +81,7 @@ static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
int ret;
+   phys_addr_t crash_max = arm64_dma32_phys_limit;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
@@ -88,12 +89,38 @@ static void __init reserve_crashkernel(void)
if (ret || !crash_size)
return;
 
+   ret = reserve_crashkernel_low();
+   if (!ret && crashk_low_res.end) {
+   /*
+* If crashkernel=X,low specified, there may be two regions,
+* we need to make some changes as follows:
+*
+* 1. rename the low region as "Crash kernel (low)"
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*
+* 2. change the upper bound for crash memory
+* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash memory.
+*
+* 3. mark the low region as "nomap"
+* The low region is intended to be used for crash dump kernel
+* devices, just mark the low region as "nomap" simply.
+*/
+   const char *rename = "Crash kernel (low)";
+
+   crashk_low_res.name = rename;
+   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
+   memblock_mark_nomap(crashk_low_res.start,
+   resource_size(_low_res));
+   }
+
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, crash_max, crash_size,
+   SZ_2M);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v9 3/5] arm64: kdump: add memory for devices by DT property linux, usable-memory-range

2020-06-28 Thread Chen Zhou
If we want to reserve crashkernel above 4G, we could use parameters
"crashkernel=X crashkernel=Y,low", in this case, specified size low
memory is reserved for crash dump kernel devices and never mapped by
the first kernel. This memory range is advertised to crash dump kernel
via DT property under /chosen,
linux,usable-memory-range = 

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/arm64/mm/init.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ce7ced85f5fb..f5b31e8f1f34 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -69,6 +69,15 @@ EXPORT_SYMBOL(vmemmap);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now crash dump
+ * kernel support at most two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES  2
+
 #ifdef CONFIG_KEXEC_CORE
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
@@ -272,9 +281,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_region *usable_rgns = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -283,22 +292,36 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   usable_rgns[nr].base = dt_mem_next_cell(dt_root_addr_cells, 
);
+   usable_rgns[nr].size = dt_mem_next_cell(dt_root_size_cells, 
);
+
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_rgns[MAX_USABLE_RANGES] = {
+   { .size = 0 },
+   { .size = 0 }
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, _rgns);
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   /*
+* The first range of usable-memory regions is for crash dump
+* kernel with only one region or for high region with two regions,
+* the second range is dedicated for low region if exist.
+*/
+   if (usable_rgns[0].size)
+   memblock_cap_memory_range(usable_rgns[0].base, 
usable_rgns[0].size);
+   if (usable_rgns[1].size)
+   memblock_add(usable_rgns[1].base, usable_rgns[1].size);
 }
 
 void __init arm64_memblock_init(void)
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v9 0/5] support reserving crashkernel above 4G on arm64 kdump

2020-06-28 Thread Chen Zhou
This patch series enable reserving crashkernel above 4G in arm64.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are required, crash dump kernel
will boot failure because there is no low memory available for allocation.
3. commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32") broken
the arm64 kdump. If the memory reserved for crash dump kernel falled in
ZONE_DMA32, the devices in crash dump kernel need to use ZONE_DMA will alloc
fail.

To solve these issues, introduce crashkernel=X,low to reserve specified
size low memory.
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

When crashkernel is reserved above 4G in memory and crashkernel=X,low
is specified simultaneously, kernel should reserve specified size low memory
for crash dump kernel devices. So there may be two crash kernel regions, one
is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use of
kexec-tools, rename the low region as "Crash kernel (low)", and pass the
low region by reusing DT property "linux,usable-memory-range". We made the low
memory region as the last range of "linux,usable-memory-range" to keep
compatibility with existing user-space and older kdump kernels.

Besides, we need to modify kexec-tools:
arm64: support more than one crash kernel regions(see [1])

Another update is document about DT property 'linux,usable-memory-range':
schemas: update 'linux,usable-memory-range' node schema(see [2])

The previous changes and discussions can be retrieved from:

Changes since [v8]
- Reuse DT property "linux,usable-memory-range".
Suggested by Rob, reuse DT property "linux,usable-memory-range" to pass the low
memory region.
- Fix kdump broken with ZONE_DMA reintroduced.
- Update chosen schema.

Changes since [v7]
- Move x86 CRASH_ALIGN to 2M
Suggested by Dave and do some test, move x86 CRASH_ALIGN to 2M.
- Update Documentation/devicetree/bindings/chosen.txt.
Add corresponding documentation to Documentation/devicetree/bindings/chosen.txt
suggested by Arnd.
- Add Tested-by from Jhon and pk.

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-June/020737.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213

Chen Zhou (5):
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reserve crashkenel above 4G for crash dump kernel
  arm64: kdump: add memory for devices by DT property
linux,usable-memory-range
  arm64: kdump: fix kdump broken with ZONE_DMA reintroduced
  kdump: update Documentation about crashkernel on arm64

 Documentation/admin-guide/kdump/kdump.rst | 13 ++-
 .../admin-guide/kernel-parameters.txt | 17 +++-
 arch/arm64/kernel/setup.c |  8 +-
 arch/arm64/mm/init.c  | 74 ---
 arch/x86/kernel/setup.c   | 66 ++
 include/linux/

[PATCH v9 1/5] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-06-28 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.

BTW, move x86_64 CRASH_ALIGN to 2M suggested by Dave. CONFIG_PHYSICAL_ALIGN
can be selected from 2M to 16M, move to the same as arm64.

Note, in arm64, we reserve low memory if and only if crashkernel=X,low
is specified. Different with x86_64, don't set low memory automatically.

Reported-by: kbuild test robot 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/x86/kernel/setup.c| 66 -
 include/linux/crash_core.h |  3 ++
 include/linux/kexec.h  |  2 -
 kernel/crash_core.c| 85 ++
 kernel/kexec_core.c| 17 
 5 files changed, 96 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a3767e74c758..33db99ae3035 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -401,8 +401,8 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
 
 /*
  * Keep the crash kernel below this limit.
@@ -425,59 +425,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   SZ_64T
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -541,9 +488,12 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 525510a9f965..4df8c0bff03e 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -63,6 +63,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 extern unsigned char *vmcoreinfo_data;
 extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
+extern struct resource crashk_res;
+extern struct resource crashk_low_res;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
  void *data, size_t data_len);
@@ -74,5 +76,6 @@ int parse_crashkernel_high(char *cmdline, unsigned long long 
system_ram

[PATCH v9 5/5] kdump: update Documentation about crashkernel on arm64

2020-06-28 Thread Chen Zhou
Now we support crashkernel=X,[low] on arm64, update the Documentation.
We could use parameters "crashkernel=X crashkernel=Y,low" to reserve
memory above 4G.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 Documentation/admin-guide/kdump/kdump.rst   | 13 +++--
 Documentation/admin-guide/kernel-parameters.txt | 17 +++--
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index 2da65fef2a1c..6ba294d425c9 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,13 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=Y[@X]" to select a region under 4G first, and
+   fall back to reserve region above 4G when '@offset' hasn't been specified.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +322,11 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   On arm64, use "crashkernel=Y[@X]". Note that the start address of
the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   If crashkernel=Z,low is specified simultaneously, reserve spcified size
+   low memory for crash kdump kernel devices firstly and then reserve memory
+   above 4G.
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index fb95fad81c79..335431a351c0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -722,6 +722,9 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] If crashkernel=X,low is specified, reserve
+   spcified size low memory for crash kdump kernel devices
+   firstly, and then reserve memory above 4G.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -746,13 +749,23 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
-
+   [KNL, arm64] range under 4G.
+   This one let user to specify own low range under 4G
+   for crash dump kernel instead.
+   Different with x86_64, kernel allocates specified size
+   physical memory region only when this parameter is 
specified
+   instead of trying to allocate at least 256M below 4G
+   automatically.
+   This parameter is used along with crashkernel=X when we
+   want to reserve crashkernel above 4G. If there are 
devices
+   need to use ZONE_DMA in crash dump kernel, it is also
+   a good choice.
cryptomgr.notests
[KNL] Disable crypto self-tests
 
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v9 4/5] arm64: kdump: fix kdump broken with ZONE_DMA reintroduced

2020-06-28 Thread Chen Zhou
commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32")
broken the arm64 kdump. If the memory reserved for crash dump kernel
falled in ZONE_DMA32, the devices in crash dump kernel need to use
ZONE_DMA will alloc fail.

This patch addressed the above issue based on "reserving crashkernel
above 4G". Originally, we reserve low memory below 4G, and now just need
to adjust memory limit to arm64_dma_phys_limit in reserve_crashkernel_low
if ZONE_DMA is enabled. That is, if there are devices need to use ZONE_DMA
in crash dump kernel, it is a good choice to use parameters
"crashkernel=X crashkernel=Y,low".

Signed-off-by: Chen Zhou 
---
 kernel/crash_core.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index a7580d291c37..e8ecbbc761a3 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -320,6 +320,7 @@ int __init reserve_crashkernel_low(void)
unsigned long long base, low_base = 0, low_size = 0;
unsigned long total_low_mem;
int ret;
+   phys_addr_t crash_max = 1ULL << 32;
 
total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
 
@@ -352,7 +353,11 @@ int __init reserve_crashkernel_low(void)
return 0;
}
 
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
+#ifdef CONFIG_ARM64
+   if (IS_ENABLED(CONFIG_ZONE_DMA))
+   crash_max = arm64_dma_phys_limit;
+#endif
+   low_base = memblock_find_in_range(0, crash_max, low_size, CRASH_ALIGN);
if (!low_base) {
pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
   (unsigned long)(low_size >> 20));
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v4] arm64: support more than one crash kernel regions

2020-06-27 Thread Chen Zhou
When crashkernel is reserved above 4G in memory, kernel should
reserve some amount of low memory for swiotlb and some DMA buffers.
So there may be two crash kernel regions, one is below 4G, the other
is above 4G.

Currently, there is only one crash kernel region on arm64, and pass
"linux,usable-memory-range = " property to crash dump
kernel.
Now, we pass "linux,usable-memory-range = "
to crash dump kernel to support two crash kernel regions and load crash
kernel high. Make the low memory region as the second range "BASE2 SIZE2"
to keep compatibility with existing user-space and older kdump kernels.

Signed-off-by: Chen Zhou 
---
For "support reserving crashkernel above 4G on arm64 kdump", we need
to modify the kexec-tools.

Changes since [v3]:
- Reuse DT property "linux,usable-memory-range".
Reuse DT property "linux,usable-memory-range" to pass the low 
memory region.

Changes since [v2]:
- Rebase to latest kexec-tools code.

Changes since [v1]:
- Add another DT property "linux,low-memory-range" to crash dump kernel's
dtb to pass the low region instead of reusing "linux,usable-memory-range".

[1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
[2]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
[3]: http://lists.infradead.org/pipermail/kexec/2020-May/025128.html
---
 kexec/arch/arm64/crashdump-arm64.c | 49 +-
 kexec/arch/arm64/crashdump-arm64.h |  5 ++-
 kexec/arch/arm64/iomem.h   |  1 +
 kexec/arch/arm64/kexec-arm64.c | 65 --
 4 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index 38d1a0f..d8338eb 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -27,11 +27,11 @@
 static struct memory_ranges system_memory_rgns;
 
 /* memory range reserved for crashkernel */
-struct memory_range crash_reserved_mem;
+struct memory_range crash_reserved_mem[CRASH_MAX_RESERVED_RANGES];
 struct memory_ranges usablemem_rgns = {
.size = 0,
-   .max_size = 1,
-   .ranges = _reserved_mem,
+   .max_size = CRASH_MAX_RESERVED_RANGES,
+   .ranges = crash_reserved_mem,
 };
 
 struct memory_range elfcorehdr_mem;
@@ -84,7 +84,10 @@ static int iomem_range_callback(void *UNUSED(data), int 
UNUSED(nr),
char *str, unsigned long long base,
unsigned long long length)
 {
-   if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
+   if (strncmp(str, CRASH_KERNEL_LOW, strlen(CRASH_KERNEL_LOW)) == 0)
+   return mem_regions_alloc_and_add(_rgns,
+   base, length, RANGE_RAM);
+   else if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
return mem_regions_alloc_and_add(_rgns,
base, length, RANGE_RAM);
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
@@ -103,7 +106,7 @@ int is_crashkernel_mem_reserved(void)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-   return crash_reserved_mem.start != crash_reserved_mem.end;
+   return usablemem_rgns.size;
 }
 
 /*
@@ -117,6 +120,8 @@ int is_crashkernel_mem_reserved(void)
  */
 static int crash_get_memory_ranges(void)
 {
+   int i;
+
/*
 * First read all memory regions that can be considered as
 * system memory including the crash area.
@@ -124,16 +129,19 @@ static int crash_get_memory_ranges(void)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-   /* allow only a single region for crash dump kernel */
-   if (usablemem_rgns.size != 1)
+   /* allow one or two region for crash dump kernel */
+   if (!usablemem_rgns.size)
return -EINVAL;
 
-   dbgprint_mem_range("Reserved memory range", _reserved_mem, 1);
+   dbgprint_mem_range("Reserved memory range",
+   usablemem_rgns.ranges, usablemem_rgns.size);
 
-   if (mem_regions_alloc_and_exclude(_memory_rgns,
-   _reserved_mem)) {
-   fprintf(stderr, "Cannot allocate memory for ranges\n");
-   return -ENOMEM;
+   for (i = 0; i < usablemem_rgns.size; i++) {
+   if (mem_regions_alloc_and_exclude(_memory_rgns,
+   _reserved_mem[i])) {
+   fprintf(stderr, "Cannot allocate memory for ranges\n");
+   return -ENOMEM;
+   }
}
 
/*
@@ -194,7 +202,8 @@ int load_crashdump_segments(struct kexec_info *info)
return EFAILED;
 
elf

[PATCH v8 3/5] arm64: kdump: add memory for devices by DT property, low-memory-range

2020-05-21 Thread Chen Zhou
If we want to reserve crashkernel above 4G, we could use parameters
"crashkernel=X crashkernel=Y,low", in this case, specified size low
memory is reserved for crash dump kernel devices and never mapped by
the first kernel. This memory range is advertised to crash dump kernel
via DT property under /chosen,
linux,low-memory-range=

Crash dump kernel reads this property at boot time and call
memblock_add() after memblock_cap_memory_range() has been called.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/arm64/mm/init.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 71498acf0cd8..fcc3abee7003 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -323,6 +323,26 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init early_init_dt_scan_lowmem(unsigned long node,
+   const char *uname, int depth, void *data)
+{
+   struct memblock_region *lowmem = data;
+   const __be32 *reg;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "chosen") != 0)
+   return 0;
+
+   reg = of_get_flat_dt_prop(node, "linux,low-memory-range", );
+   if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
+   return 1;
+
+   lowmem->base = dt_mem_next_cell(dt_root_addr_cells, );
+   lowmem->size = dt_mem_next_cell(dt_root_size_cells, );
+
+   return 1;
+}
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
@@ -353,13 +373,21 @@ static void __init fdt_enforce_memory_region(void)
 
if (reg.size)
memblock_cap_memory_range(reg.base, reg.size);
+
+   of_scan_flat_dt(early_init_dt_scan_lowmem, );
+
+   if (reg.size)
+   memblock_add(reg.base, reg.size);
 }
 
 void __init arm64_memblock_init(void)
 {
const s64 linear_region_size = BIT(vabits_actual - 1);
 
-   /* Handle linux,usable-memory-range property */
+   /*
+* Handle linux,usable-memory-range and linux,low-memory-range
+* properties.
+*/
fdt_enforce_memory_region();
 
/* Remove memory above our supported physical address size */
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v8 4/5] kdump: update Documentation about crashkernel on arm64

2020-05-21 Thread Chen Zhou
Now we support crashkernel=X,[low] on arm64, update the Documentation.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 Documentation/admin-guide/kdump/kdump.rst   | 13 +++--
 Documentation/admin-guide/kernel-parameters.txt | 12 +++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index ac7e131d2935..e55173ec1666 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,13 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=Y[@X]" to select a region under 4G first, and
+   fall back to reserve region above 4G when '@offset' hasn't been specified.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +322,11 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   On arm64, use "crashkernel=Y[@X]". Note that the start address of
the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   If crashkernel=Z,low is specified simultaneously, reserve spcified size
+   low memory for crash kdump kernel devices firstly and then reserve memory
+   above 4G.
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 7bc83f3d9bdf..97695783b817 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -722,6 +722,9 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] If crashkernel=X,low is specified, reserve
+   spcified size low memory for crash kdump kernel devices
+   firstly, and then reserve memory above 4G.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -746,12 +749,19 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
+   [KNL, arm64] range under 4G.
+   This one let user to specify own low range under 4G
+   for crash dump kernel instead.
+   Different with x86_64, kernel allocates specified size
+   physical memory region only when this parameter is 
specified
+   instead of trying to allocate at least 256M below 4G
+   automatically.
 
cryptomgr.notests
[KNL] Disable crypto self-tests
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v8 5/5] dt-bindings: chosen: Document linux, low-memory-range for arm64 kdump

2020-05-21 Thread Chen Zhou
Add documentation for DT property used by arm64 kdump:
linux,low-memory-range.
"linux,low-memory-range" is an another memory region used for crash
dump kernel devices.

Signed-off-by: Chen Zhou 
---
 Documentation/devicetree/bindings/chosen.txt | 25 
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/chosen.txt 
b/Documentation/devicetree/bindings/chosen.txt
index 45e79172a646..bfe6fb6976e6 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -103,6 +103,31 @@ While this property does not represent a real hardware, 
the address
 and the size are expressed in #address-cells and #size-cells,
 respectively, of the root node.
 
+linux,low-memory-range
+--
+This property (arm64 only) holds a base address and size, describing a
+limited region below 4G. Similar to "linux,usable-memory-range", it is
+an another memory range which may be considered available for use by the
+kernel.
+
+e.g.
+
+/ {
+   chosen {
+   linux,low-memory-range = <0x0 0x7000 0x0 0x1000>;
+   linux,usable-memory-range = <0x202f 0xc000 0x0 0x4000>;
+   };
+};
+
+The main usage is for crash dump kernel devices when reserving crashkernel
+above 4G. When reserving crashkernel above 4G, there may be two crash kernel
+regions, one is below 4G, the other is above 4G. In order to distinct from
+the high region, use this property to pass the low region.
+
+While this property does not represent a real hardware, the address
+and the size are expressed in #address-cells and #size-cells,
+respectively, of the root node.
+
 linux,elfcorehdr
 
 
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v8 1/5] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-05-21 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
BTW, move x86 CRASH_ALIGN to 2M.

Note, in arm64, we reserve low memory if and only if crashkernel=X,low
is specified. Different with x86_64, don't set low memory automatically.

Reported-by: kbuild test robot 
Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/x86/kernel/setup.c| 66 -
 include/linux/crash_core.h |  3 ++
 include/linux/kexec.h  |  2 -
 kernel/crash_core.c| 85 ++
 kernel/kexec_core.c| 17 
 5 files changed, 96 insertions(+), 77 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 4b3fa6cd3106..de75fec73d47 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -395,8 +395,8 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
 
 /*
  * Keep the crash kernel below this limit.
@@ -419,59 +419,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   SZ_64T
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -535,9 +482,12 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 525510a9f965..4df8c0bff03e 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -63,6 +63,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 extern unsigned char *vmcoreinfo_data;
 extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
+extern struct resource crashk_res;
+extern struct resource crashk_low_res;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
  void *data, size_t data_len);
@@ -74,5 +76,6 @@ int parse_crashkernel_high(char *cmdline, unsigned long long 
system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_lo

[PATCH v8 2/5] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2020-05-21 Thread Chen Zhou
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

Signed-off-by: Chen Zhou 
Tested-by: John Donnelly 
Tested-by: Prabhakar Kushwaha 
---
 arch/arm64/kernel/setup.c |  8 +++-
 arch/arm64/mm/init.c  | 31 +--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 3fd2c11c09fc..a8487e4d3e5a 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index e42727e3568e..71498acf0cd8 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -81,6 +81,7 @@ static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
int ret;
+   phys_addr_t crash_max = arm64_dma32_phys_limit;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
@@ -88,12 +89,38 @@ static void __init reserve_crashkernel(void)
if (ret || !crash_size)
return;
 
+   ret = reserve_crashkernel_low();
+   if (!ret && crashk_low_res.end) {
+   /*
+* If crashkernel=X,low specified, there may be two regions,
+* we need to make some changes as follows:
+*
+* 1. rename the low region as "Crash kernel (low)"
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*
+* 2. change the upper bound for crash memory
+* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash memory.
+*
+* 3. mark the low region as "nomap"
+* The low region is intended to be used for crash dump kernel
+* devices, just mark the low region as "nomap" simply.
+*/
+   const char *rename = "Crash kernel (low)";
+
+   crashk_low_res.name = rename;
+   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
+   memblock_mark_nomap(crashk_low_res.start,
+   resource_size(_low_res));
+   }
+
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, crash_max, crash_size,
+   SZ_2M);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v8 0/5] support reserving crashkernel above 4G on arm64 kdump

2020-05-21 Thread Chen Zhou
This patch series enable reserving crashkernel above 4G in arm64.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are required, crash dump kernel
will boot failure because there is no low memory available for allocation.

To solve these issues, introduce crashkernel=X,low to reserve specified
size low memory.
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
is specified simultaneously, kernel should reserve specified size low memory
for crash dump kernel devices. So there may be two crash kernel regions, one
is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use of
kexec-tools, rename the low region as "Crash kernel (low)", and add DT property
"linux,low-memory-range" to crash dump kernel's dtb to pass the low region.

Besides, we need to modify kexec-tools:
arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])

The previous changes and discussions can be retrieved from:

Changes since [v7]
- Move x86 CRASH_ALIGN to 2M
Suggested by Dave and do some test, move x86 CRASH_ALIGN to 2M.
- Update Documentation/devicetree/bindings/chosen.txt 
Add corresponding documentation to Documentation/devicetree/bindings/chosen.txt 
suggested by Arnd.
- Add Tested-by from Jhon and pk

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2020-May/025128.html
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411

Chen Zhou (5):
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reserve crashkenel above 4G for crash dump kernel
  arm64: kdump: add memory for devices by DT property, low-memory-range
  kdump: update Documentation about crashkernel on arm64
  dt-bindings: chosen: Document linux,low-memory-range for arm64 kdump

 Documentation/admin-guide/kdump/kdump.rst | 13 ++-
 .../admin-guide/kernel-parameters.txt | 12 ++-
 Documentation/devicetree/bindings/chosen.txt  | 25 ++
 arch/arm64/kernel/setup.c |  8 +-
 arch/arm64/mm/init.c  | 61 -
 arch/x86/kernel/setup.c   | 66 ++
 include/linux/crash_core.h|  3 +
 include/linux/kexec.h |  2 -
 kernel/crash_core.c   | 85 +++
 kernel/kexec_core.c   | 17 
 10 files changed, 208 insertions(+), 84 deletions(-)

-- 
2.20.1


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v3] arm64: kdump: add another DT property to crash dump kernel's dtb

2020-05-21 Thread Chen Zhou
Currently, there is only one crash kernel region on arm64, we add
another region "crash kernel low" used for crash dump kernel devices.

To do this, we add DT property "linux,low-memory-range" to crash
dump kernel's dtb to pass the low region.

Signed-off-by: Chen Zhou 
---
For "support reserving crashkernel above 4G on arm64 kdump", we need
to modify the kexec-tools.

Changes since [v2]:
- Rebase to latest kexec-tools code.

Changes since [v1]:
- Add another DT property "linux,low-memory-range" to crash dump kernel's
dtb to pass the low region instead of reusing "linux,usable-memory-range".

[1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
[2]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
---
 kexec/arch/arm64/crashdump-arm64.c | 29 +++--
 kexec/arch/arm64/crashdump-arm64.h |  2 ++
 kexec/arch/arm64/iomem.h   |  1 +
 kexec/arch/arm64/kexec-arm64.c | 27 +++
 4 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index 38d1a0f..32b7e9f 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -34,6 +34,14 @@ struct memory_ranges usablemem_rgns = {
.ranges = _reserved_mem,
 };
 
+/* memory range reserved for crashkernel low, optional */
+struct memory_range crash_reserved_low_mem;
+struct memory_ranges lowmem_rgns = {
+   .size = 0,
+   .max_size = 1,
+   .ranges = _reserved_low_mem,
+};
+
 struct memory_range elfcorehdr_mem;
 
 static struct crash_elf_info elf_info = {
@@ -84,7 +92,10 @@ static int iomem_range_callback(void *UNUSED(data), int 
UNUSED(nr),
char *str, unsigned long long base,
unsigned long long length)
 {
-   if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
+   if (strncmp(str, CRASH_KERNEL_LOW, strlen(CRASH_KERNEL_LOW)) == 0)
+   return mem_regions_alloc_and_add(_rgns,
+   base, length, RANGE_RAM);
+   else if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
return mem_regions_alloc_and_add(_rgns,
base, length, RANGE_RAM);
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
@@ -124,7 +135,7 @@ static int crash_get_memory_ranges(void)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-   /* allow only a single region for crash dump kernel */
+   /* allow only a single usablemem region for crash dump kernel */
if (usablemem_rgns.size != 1)
return -EINVAL;
 
@@ -136,6 +147,20 @@ static int crash_get_memory_ranges(void)
return -ENOMEM;
}
 
+   /* lowmem region for crash dump kernel is optional, at most one region 
*/
+   if (lowmem_rgns.size > 1)
+   return -EINVAL;
+
+   if (lowmem_rgns.size) {
+   dbgprint_mem_range("Reserved low memory range", 
_reserved_low_mem,
+   1);
+
+   if (mem_regions_exclude(_memory_rgns, 
_reserved_low_mem)) {
+   fprintf(stderr,
+   "Error: Number of crash memory ranges 
excedeed the max limit\n");
+   return -ENOMEM;
+   }
+   }
/*
 * Make sure that the memory regions are sorted.
 */
diff --git a/kexec/arch/arm64/crashdump-arm64.h 
b/kexec/arch/arm64/crashdump-arm64.h
index 880b83a..f185534 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -18,6 +18,8 @@
 
 extern struct memory_ranges usablemem_rgns;
 extern struct memory_range crash_reserved_mem;
+extern struct memory_ranges lowmem_rgns;
+extern struct memory_range crash_reserved_low_mem;
 extern struct memory_range elfcorehdr_mem;
 
 extern int load_crashdump_segments(struct kexec_info *info);
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
index d4864bb..45d7953 100644
--- a/kexec/arch/arm64/iomem.h
+++ b/kexec/arch/arm64/iomem.h
@@ -4,6 +4,7 @@
 #define SYSTEM_RAM "System RAM\n"
 #define KERNEL_CODE"Kernel code\n"
 #define KERNEL_DATA"Kernel data\n"
+#define CRASH_KERNEL_LOW   "Crash kernel (low)\n"
 #define CRASH_KERNEL   "Crash kernel\n"
 #define IOMEM_RESERVED "reserved\n"
 
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 45ebc54..afa4fda 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -41,6 +41,7 @@
 #define PROP_SIZE_CELLS "#size-cells"
 #define PROP_ELFCOREHDR "linux,elfcorehdr"
 #define PROP_USABLE_MEM_RANGE "li

Re: [PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-04-03 Thread Chen Zhou
Hi Dave/James,

On 2020/1/17 11:58, Dave Young wrote:
> On 01/16/20 at 03:17pm, James Morse wrote:
>> Hi guys,
>>
>> On 28/12/2019 09:32, Dave Young wrote:
>>> On 12/27/19 at 07:04pm, Chen Zhou wrote:
>>>> On 2019/12/27 13:54, Dave Young wrote:
>>>>> On 12/23/19 at 11:23pm, Chen Zhou wrote:
>>>>>> In preparation for supporting reserve_crashkernel_low in arm64 as
>>>>>> x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
>>>>>>
>>>>>> Note, in arm64, we reserve low memory if and only if crashkernel=X,low
>>>>>> is specified. Different with x86_64, don't set low memory automatically.
>>>>>
>>>>> Do you have any reason for the difference?  I'd expect we have same
>>>>> logic if possible and remove some of the ifdefs.
>>>>
>>>> In x86_64, if we reserve crashkernel above 4G, then we call 
>>>> reserve_crashkernel_low()
>>>> to reserve low memory.
>>>>
>>>> In arm64, to simplify, we call reserve_crashkernel_low() at the beginning 
>>>> of reserve_crashkernel()
>>>> and then relax the arm64_dma32_phys_limit if reserve_crashkernel_low() 
>>>> allocated something.
>>>> In this case, if reserve crashkernel below 4G there will be 256M low 
>>>> memory set automatically
>>>> and this needs extra considerations.
>>
>>> Sorry that I did not read the old thread details and thought that is
>>> arch dependent.  But rethink about that, it would be better that we can
>>> have same semantic about crashkernel parameters across arches.  If we
>>> make them different then it causes confusion, especially for
>>> distributions.
>>
>> Surely distros also want one crashkernel* string they can use on all 
>> platforms without
>> having to detect the kernel version, platform or changeable memory layout...
>>
>>
>>> OTOH, I thought if we reserve high memory then the low memory should be
>>> needed.  There might be some exceptions, but I do not know the exact
>>> one,
>>
>>> can we make the behavior same, and special case those systems which
>>> do not need low memory reservation.
>>
>> Its tricky to work out which systems are the 'normal' ones.
>>
>> We don't have a fixed memory layout for arm64. Some systems have no memory 
>> below 4G.
>> Others have no memory above 4G.
>>
>> Chen Zhou's machine has some memory below 4G, but its too precious to 
>> reserve a large
>> chunk for kdump. Without any memory below 4G some of the drivers won't work.
>>
>> I don't see what distros can set as their default for all platforms if 
>> high/low are
>> mutually exclusive with the 'crashkernel=' in use today. How did x86 
>> navigate this, ... or
>> was it so long ago?
> 
> It is very rare for such machine without any low memory in X86, at least
> from what I know,  so the current way just works fine.
> 
> Since arm64 is quite different, I would agree with current way
> proposed in the patch, but a question is, for those arm64 systems how can
> admin know if low crashkernel memory is needed or not?  and just skip the
> low reservation for machine with high memory installed only?

Specified size low memory is for crash dump kernel devices.
I think admin should know if there are devices needing low memory in crash dump 
kernel.

James, any suggestions?

Thanks,
Chen Zhou

> 
>>
>> No one else has reported a problem with the existing placement logic, hence 
>> treating this
>> 'low' thing as the 'in addition' special case.
>>
>>
>>>> previous discusses:
>>>>https://lkml.org/lkml/2019/6/5/670
>>>>https://lkml.org/lkml/2019/6/13/229
>>>
>>> Another concern from James:
>>> "
>>> With both crashk_low_res and crashk_res, we end up with two entries in 
>>> /proc/iomem called
>>> "Crash kernel". Because its sorted by address, and kexec-tools stops 
>>> searching when it
>>> find "Crash kernel", you are always going to get the kernel placed in the 
>>> lower portion.
>>> "
>>>
>>> The kexec-tools code is iterating all "Crash kernel" ranges and add them
>>> in an array.  In X86 code, it uses the higher range to locate memory.
>>
>> Then my hurried reading of what the user-space code does was wrong!
>>
>> If kexec-tools places the kernel in the low region, there may not be enough 
>> memory left
>> for whatever purpose it was reserved for. This was the motivation for giving 
>> it a
>> different name.
> 
> Agreed,  it is still a potential problem though.  Say we have both low
> and high reserved.  Kdump kernel boots up, the kernel and drivers,
> applications will use memory, I'm not sure if there is a memory
> allocation policy to let them all use high mem first..  Anyway that is
> beyond the kexec-tools and resource name.
> 
> Thanks
> Dave
> 
> 
> .
> 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-04-03 Thread Chen Zhou
Hi Dave,

On 2019/12/31 9:39, Chen Zhou wrote:
> Hi Dave,
> 
> On 2019/12/28 17:32, Dave Young wrote:
>> On 12/27/19 at 07:04pm, Chen Zhou wrote:
>>> Hi Dave
>>>
>>> On 2019/12/27 13:54, Dave Young wrote:
>>>> Hi,
>>>> On 12/23/19 at 11:23pm, Chen Zhou wrote:
>>>>> In preparation for supporting reserve_crashkernel_low in arm64 as
>>>>> x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
>>>>>
>>>>> Note, in arm64, we reserve low memory if and only if crashkernel=X,low
>>>>> is specified. Different with x86_64, don't set low memory automatically.
>>>>
>>>> Do you have any reason for the difference?  I'd expect we have same
>>>> logic if possible and remove some of the ifdefs.
>>>
>>> In x86_64, if we reserve crashkernel above 4G, then we call 
>>> reserve_crashkernel_low()
>>> to reserve low memory.
>>>
>>> In arm64, to simplify, we call reserve_crashkernel_low() at the beginning 
>>> of reserve_crashkernel()
>>> and then relax the arm64_dma32_phys_limit if reserve_crashkernel_low() 
>>> allocated something.
>>> In this case, if reserve crashkernel below 4G there will be 256M low memory 
>>> set automatically
>>> and this needs extra considerations.
>>
>> Sorry that I did not read the old thread details and thought that is
>> arch dependent.  But rethink about that, it would be better that we can
>> have same semantic about crashkernel parameters across arches.  If we
>> make them different then it causes confusion, especially for
>> distributions.
>>
>> OTOH, I thought if we reserve high memory then the low memory should be
>> needed.  There might be some exceptions, but I do not know the exact
>> one, can we make the behavior same, and special case those systems which
>> do not need low memory reservation.
>>
> I thought like this and did implement with crashkernel parameters arch 
> independent.
> This is my v4: https://lkml.org/lkml/2019/5/6/1361, i implemented according 
> to x86_64's
> behavior.
> 
>>>
>>> previous discusses:
>>> https://lkml.org/lkml/2019/6/5/670
>>> https://lkml.org/lkml/2019/6/13/229
>>
>> Another concern from James:
>> "
>> With both crashk_low_res and crashk_res, we end up with two entries in 
>> /proc/iomem called
>> "Crash kernel". Because its sorted by address, and kexec-tools stops 
>> searching when it
>> find "Crash kernel", you are always going to get the kernel placed in the 
>> lower portion.
>> "
>>
>> The kexec-tools code is iterating all "Crash kernel" ranges and add them
>> in an array.  In X86 code, it uses the higher range to locate memory.
> 
> We also discussed about this: https://lkml.org/lkml/2019/6/13/227.
> I guess James's opinion is that kexec-tools should take forward compatibility 
> into account.
> "But we can't rely on people updating user-space when they update the 
> kernel!" -- James
> 
>>
>>>
>>>>
>>>>>
>>>>> Reported-by: kbuild test robot 
>>>>> Signed-off-by: Chen Zhou 
>>>>> ---
>>>>>  arch/x86/kernel/setup.c| 62 -
>>>>>  include/linux/crash_core.h |  3 ++
>>>>>  include/linux/kexec.h  |  2 --
>>>>>  kernel/crash_core.c| 87 
>>>>> ++
>>>>>  kernel/kexec_core.c| 17 -
>>>>>  5 files changed, 96 insertions(+), 75 deletions(-)
>>>>>
>>>>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>>>>> index cedfe20..5f38942 100644
>>>>> --- a/arch/x86/kernel/setup.c
>>>>> +++ b/arch/x86/kernel/setup.c
>>>>> @@ -486,59 +486,6 @@ static void __init 
>>>>> memblock_x86_reserve_range_setup_data(void)
>>>>>  # define CRASH_ADDR_HIGH_MAX SZ_64T
>>>>>  #endif
>>>>>  
>>>>> -static int __init reserve_crashkernel_low(void)
>>>>> -{
>>>>> -#ifdef CONFIG_X86_64
>>>>> - unsigned long long base, low_base = 0, low_size = 0;
>>>>> - unsigned long total_low_mem;
>>>>> - int ret;
>>>>> -
>>>>> - total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
>>>>> -
>>>>> - /* crashkernel=Y,l

Re: [PATCH v7 0/4] support reserving crashkernel above 4G on arm64 kdump

2020-03-25 Thread Chen Zhou
Hi all,

Friendly ping...

On 2019/12/23 23:23, Chen Zhou wrote:
> This patch series enable reserving crashkernel above 4G in arm64.
> 
> There are following issues in arm64 kdump:
> 1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
> when there is no enough low memory.
> 2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
> in this case, if swiotlb or DMA buffers are required, crash dump kernel
> will boot failure because there is no low memory available for allocation.
> 
> To solve these issues, introduce crashkernel=X,low to reserve specified
> size low memory.
> Crashkernel=X tries to reserve memory for the crash dump kernel under
> 4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
> size low memory for crash kdump kernel devices firstly and then reserve
> memory above 4G.
> 
> When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
> is specified simultaneously, kernel should reserve specified size low memory
> for crash dump kernel devices. So there may be two crash kernel regions, one
> is below 4G, the other is above 4G.
> In order to distinct from the high region and make no effect to the use of
> kexec-tools, rename the low region as "Crash kernel (low)", and add DT 
> property
> "linux,low-memory-range" to crash dump kernel's dtb to pass the low region.
> 
> Besides, we need to modify kexec-tools:
> arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])
> 
> The previous changes and discussions can be retrieved from:
> 
> Changes since [v6]
> - Fix build errors reported by kbuild test robot.
> 
> Changes since [v5]
> - Move reserve_crashkernel_low() into kernel/crash_core.c.
> - Delete crashkernel=X,high.
> - Modify crashkernel=X,low.
> If crashkernel=X,low is specified simultaneously, reserve spcified size low
> memory for crash kdump kernel devices firstly and then reserve memory above 
> 4G.
> In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
> pass to crash dump kernel by DT property "linux,low-memory-range".
> - Update Documentation/admin-guide/kdump/kdump.rst.
> 
> Changes since [v4]
> - Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.
> 
> Changes since [v3]
> - Add memblock_cap_memory_ranges back for multiple ranges.
> - Fix some compiling warnings.
> 
> Changes since [v2]
> - Split patch "arm64: kdump: support reserving crashkernel above 4G" as
> two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
> patch.
> 
> Changes since [v1]:
> - Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
> - Remove memblock_cap_memory_ranges() i added in v1 and implement that
> in fdt_enforce_memory_region().
> There are at most two crash kernel regions, for two crash kernel regions
> case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
> and then remove the memory range in the middle.
> 
> [1]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
> [v1]: https://lkml.org/lkml/2019/4/2/1174
> [v2]: https://lkml.org/lkml/2019/4/9/86
> [v3]: https://lkml.org/lkml/2019/4/9/306
> [v4]: https://lkml.org/lkml/2019/4/15/273
> [v5]: https://lkml.org/lkml/2019/5/6/1360
> [v6]: https://lkml.org/lkml/2019/8/30/142
> 
> Chen Zhou (4):
>   x86: kdump: move reserve_crashkernel_low() into crash_core.c
>   arm64: kdump: reserve crashkenel above 4G for crash dump kernel
>   arm64: kdump: add memory for devices by DT property, low-memory-range
>   kdump: update Documentation about crashkernel on arm64
> 
>  Documentation/admin-guide/kdump/kdump.rst   | 13 +++-
>  Documentation/admin-guide/kernel-parameters.txt | 12 +++-
>  arch/arm64/kernel/setup.c   |  8 ++-
>  arch/arm64/mm/init.c| 61 -
>  arch/x86/kernel/setup.c | 62 ++
>  include/linux/crash_core.h  |  3 +
>  include/linux/kexec.h   |  2 -
>  kernel/crash_core.c | 87 
> +
>  kernel/kexec_core.c | 17 -
>  9 files changed, 183 insertions(+), 82 deletions(-)
> 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v7 2/4] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2020-03-07 Thread Chen Zhou



On 2020/3/5 18:13, Prabhakar Kushwaha wrote:
> On Mon, Dec 23, 2019 at 8:57 PM Chen Zhou  wrote:
>>
>> Crashkernel=X tries to reserve memory for the crash dump kernel under
>> 4G. If crashkernel=X,low is specified simultaneously, reserve spcified
>> size low memory for crash kdump kernel devices firstly and then reserve
>> memory above 4G.
>>
>> Signed-off-by: Chen Zhou 
>> ---
>>  arch/arm64/kernel/setup.c |  8 +++-
>>  arch/arm64/mm/init.c  | 31 +--
>>  2 files changed, 36 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 56f6645..04d1c87 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
>> kernel_data.end <= res->end)
>> request_resource(res, _data);
>>  #ifdef CONFIG_KEXEC_CORE
>> -   /* Userspace will find "Crash kernel" region in /proc/iomem. 
>> */
>> +   /*
>> +* Userspace will find "Crash kernel" region in /proc/iomem.
>> +* Note: the low region is renamed as Crash kernel (low).
>> +*/
>> +   if (crashk_low_res.end && crashk_low_res.start >= res->start 
>> &&
>> +   crashk_low_res.end <= res->end)
>> +   request_resource(res, _low_res);
>> if (crashk_res.end && crashk_res.start >= res->start &&
>> crashk_res.end <= res->end)
>> request_resource(res, _res);
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index b65dffd..0d7afd5 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -80,6 +80,7 @@ static void __init reserve_crashkernel(void)
>>  {
>> unsigned long long crash_base, crash_size;
>> int ret;
>> +   phys_addr_t crash_max = arm64_dma32_phys_limit;
>>
>> ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
>> _size, _base);
>> @@ -87,12 +88,38 @@ static void __init reserve_crashkernel(void)
>> if (ret || !crash_size)
>> return;
>>
>> +   ret = reserve_crashkernel_low();
>> +   if (!ret && crashk_low_res.end) {
>> +   /*
>> +* If crashkernel=X,low specified, there may be two regions,
>> +* we need to make some changes as follows:
>> +*
>> +* 1. rename the low region as "Crash kernel (low)"
>> +* In order to distinct from the high region and make no 
>> effect
>> +* to the use of existing kexec-tools, rename the low region 
>> as
>> +* "Crash kernel (low)".
>> +*
>> +* 2. change the upper bound for crash memory
>> +* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash 
>> memory.
>> +*
>> +* 3. mark the low region as "nomap"
>> +* The low region is intended to be used for crash dump 
>> kernel
>> +* devices, just mark the low region as "nomap" simply.
>> +*/
>> +   const char *rename = "Crash kernel (low)";
>> +
>> +   crashk_low_res.name = rename;
>> +   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
>> +   memblock_mark_nomap(crashk_low_res.start,
>> +   resource_size(_low_res));
>> +   }
>> +
>> crash_size = PAGE_ALIGN(crash_size);
>>
>> if (crash_base == 0) {
>> /* Current arm64 boot protocol requires 2MB alignment */
>> -   crash_base = memblock_find_in_range(0, 
>> arm64_dma32_phys_limit,
>> -   crash_size, SZ_2M);
>> +   crash_base = memblock_find_in_range(0, crash_max, crash_size,
>> +   SZ_2M);
>> if (crash_base == 0) {
>> pr_warn("cannot allocate crashkernel 
>> (size:0x%llx)\n",
>> crash_size);
>> --
> 
> I tested this patch series on ARM64-ThunderX2 with no issue with
> bootargs crashkenel=X@Y cras

Re: [PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2020-03-01 Thread Chen Zhou


On 2020/2/24 23:25, John Donnelly wrote:
> 
> 
>> On Jan 16, 2020, at 9:47 AM, John Donnelly  
>> wrote:
>>
>>
>>
>>> On Jan 16, 2020, at 9:17 AM, James Morse  wrote:
>>>
>>> Hi guys,
>>>
>>> On 28/12/2019 09:32, Dave Young wrote:
>>>> On 12/27/19 at 07:04pm, Chen Zhou wrote:
>>>>> On 2019/12/27 13:54, Dave Young wrote:
>>>>>> On 12/23/19 at 11:23pm, Chen Zhou wrote:
>>>>>>> In preparation for supporting reserve_crashkernel_low in arm64 as
>>>>>>> x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
>>>>>>>
>>>>>>> Note, in arm64, we reserve low memory if and only if crashkernel=X,low
>>>>>>> is specified. Different with x86_64, don't set low memory automatically.
>>>>>>
>>>>>> Do you have any reason for the difference?  I'd expect we have same
>>>>>> logic if possible and remove some of the ifdefs.
>>>>>
>>>>> In x86_64, if we reserve crashkernel above 4G, then we call 
>>>>> reserve_crashkernel_low()
>>>>> to reserve low memory.
>>>>>
>>>>> In arm64, to simplify, we call reserve_crashkernel_low() at the beginning 
>>>>> of reserve_crashkernel()
>>>>> and then relax the arm64_dma32_phys_limit if reserve_crashkernel_low() 
>>>>> allocated something.
>>>>> In this case, if reserve crashkernel below 4G there will be 256M low 
>>>>> memory set automatically
>>>>> and this needs extra considerations.
>>>
>>>> Sorry that I did not read the old thread details and thought that is
>>>> arch dependent.  But rethink about that, it would be better that we can
>>>> have same semantic about crashkernel parameters across arches.  If we
>>>> make them different then it causes confusion, especially for
>>>> distributions.
>>>
>>> Surely distros also want one crashkernel* string they can use on all 
>>> platforms without
>>> having to detect the kernel version, platform or changeable memory layout...
>>>
>>>
>>>> OTOH, I thought if we reserve high memory then the low memory should be
>>>> needed.  There might be some exceptions, but I do not know the exact
>>>> one,
>>>
>>>> can we make the behavior same, and special case those systems which
>>>> do not need low memory reservation.
>>>
>>> Its tricky to work out which systems are the 'normal' ones.
>>>
>>> We don't have a fixed memory layout for arm64. Some systems have no memory 
>>> below 4G.
>>> Others have no memory above 4G.
>>>
>>> Chen Zhou's machine has some memory below 4G, but its too precious to 
>>> reserve a large
>>> chunk for kdump. Without any memory below 4G some of the drivers won't work.
>>>
>>> I don't see what distros can set as their default for all platforms if 
>>> high/low are
>>> mutually exclusive with the 'crashkernel=' in use today. How did x86 
>>> navigate this, ... or
>>> was it so long ago?
>>>
>>> No one else has reported a problem with the existing placement logic, hence 
>>> treating this
>>> 'low' thing as the 'in addition' special case.
>>
>>
>> Hi,
>>
>> I am seeing similar  Arm crash dump issues  on  5.4 kernels  where we need  
>> rather large amount of crashkernel memory reserved that is not available 
>> below 4GB ( The maximum reserved size appears to be around 768M ) . When I 
>> pick memory range higher than 4GB , I see  adapters that fail to initialize :
>>
>>
>> There is no low-memory  <4G  memory for DMA ; 
>>
>> [   11.506792] kworker/0:14: page allocation failure: order:0, 
>> mode:0x104(GFP_DMA32|__GFP_ZERO), nodemask=(null),cpuset=/,mems_allowed=0 
>> [   11.518793] CPU: 0 PID: 150 Comm: kworker/0:14 Not tainted 
>> 5.4.0-1948.3.el8uek.aarch64 #1 
>> [   11.526955] Hardware name: To be filled by O.E.M. Saber/Saber, BIOS 
>> 0ACKL025 01/18/2019 
>> [   11.534948] Workqueue: events work_for_cpu_fn 
>> [   11.539291] Call trace: 
>> [   11.541727]  dump_backtrace+0x0/0x18c 
>> [   11.545376]  show_stack+0x24/0x30 
>> [   11.548679]  dump_stack+0xbc/0xe0 
>> [   11.551982]  warn_alloc+0xf0/0x15c 
>> [   11.555370]  __alloc_pages_slowpath+0xb4c/0xb84 
>> [   11.559887]  __alloc_pages_nodemask+0x2d0/0x330 
>> [   11

Re: [PATCH v7 0/4] support reserving crashkernel above 4G on arm64 kdump

2020-02-12 Thread Chen Zhou
Hi John,

On 2020/2/12 21:20, John Donnelly wrote:
> On 12/23/19 9:23 AM, Chen Zhou wrote:
>> This patch series enable reserving crashkernel above 4G in arm64.
>>
>> There are following issues in arm64 kdump:
>> 1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
>> when there is no enough low memory.
>> 2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
>> in this case, if swiotlb or DMA buffers are required, crash dump kernel
>> will boot failure because there is no low memory available for allocation.
>>
>> To solve these issues, introduce crashkernel=X,low to reserve specified
>> size low memory.
>> Crashkernel=X tries to reserve memory for the crash dump kernel under
>> 4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
>> size low memory for crash kdump kernel devices firstly and then reserve
>> memory above 4G.
>>
> 
> 
> Hi Chen,
> 
> 
> I've applied your V7 patches to 5.4.17 test kernel and I am still seeing
> failures when I use a kdump kernel .
> 
> 
> On the kernel boot I see:
> 
>  Reserving 250MB of low memory at 3618MB for crashkernel (System low RAM: 
> 2029MB)
>  crashkernel reserved: 0x0008c000 - 0x00094000 (2048 MB)
> 
> # cat /proc/iomem  | grep -i cras
>   e220-f1bf : Crash kernel (low)
>   8c000-93fff : Crash kernel
> 
> 
> When kdump kernel is started I see what appears to be DMA initialized :
> 
> NUMA: NODE_DATA(1) on node 0
> Zone ranges:
> DMA32[mem 0x802f-0x]
> Normal   [mem 0x0001-0x00093fff]
> 
> But the sas driver still fails :
> 
> 
> [   12.092769] CPU: 0 PID: 149 Comm: kworker/0:13 Not tainted 
> 5.4.17-4-uek6m_ol8-jpdonnel+ #2
> [   12.101019] Hardware name: To be filled by O.E.M. Saber/Saber, BIOS 
> 0ACKL028 09/09/2019
> [   12.109019] Workqueue: events work_for_cpu_fn
> [   12.113363] Call trace:
> [   12.115803]  dump_backtrace+0x0/0x19c
> [   12.119453]  show_stack+0x24/0x2c
> [   12.122769]  dump_stack+0xcc/0xf8
> [   12.126078]  warn_alloc+0x108/0x11c
> [   12.129554]  __alloc_pages_slowpath+0x8fc/0xa10
> [   12.134071]  __alloc_pages_nodemask+0x2ec/0x334
> [   12.138597]  __dma_direct_alloc_pages+0x19c/0x238
> [   12.143288]  dma_direct_alloc_pages+0x48/0xf8
> [   12.147632]  dma_direct_alloc+0x4c/0x6c
> [   12.151455]  dma_alloc_attrs+0x88/0xf4
> [   12.155196]  dma_pool_alloc+0x11c/0x2ec
> [   12.159053]  _base_allocate_memory_pools+0x2ec/0x1078 [mpt3sas]
> [   12.164978]  mpt3sas_base_attach+0x444/0x748 [mpt3sas]
> [   12.170121]  _scsih_probe+0x554/0x848 [mpt3sas]
> [   12.174648]  local_pci_probe+0x4c/0x98
> 
> And the kdump fails to find local storage:
> 
> 
>  mpt3sas_cm0: reply_post_free pool: dma_pool_alloc failed
>  mpt3sas_cm0: failure at 
> ../drivers/scsi/mpt3sas/mpt3sas_scsih.c:10626/_scsih_probe()!
> 
> 
> 
> 
>> When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
>> is specified simultaneously, kernel should reserve specified size low memory
>> for crash dump kernel devices. So there may be two crash kernel regions, one
>> is below 4G, the other is above 4G.
> 
>   Can we consider a different name for "low" -  Like "dma" .. That is what it 
> is intended for :
> 
> Ie: So it shows up as ;
> 
> # cat /proc/iomem  | grep -i cras
>   e220-f1bf : Crash kernel (dma)
>   8c000-93fff : Crash kernel
> 
> 
> 
>> In order to distinct from the high region and make no effect to the use of
>> kexec-tools, rename the low region as "Crash kernel (low)", and add DT 
>> property
>> "linux,low-memory-range" to crash dump kernel's dtb to pass the low region.
>>
>> Besides, we need to modify kexec-tools:
>> arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])
> 
> 
> Can you explain what needs done to kexec tools  in more detail ?
> 
> I'd like to understand why the Arm kdump boot images are so large ( 1024M+ ) 
> as compared to x86 that can take a vmcore using a 512M kdump image .

As i said above, we also need to modify kexec-tools,
arm64: kdump: add another DT property to crash dump kernel's dtb(see [1]) is 
the patch.


Firstly, usable memory of crash dump kernel is passed via DT property, which is 
done by kexec-tools.

Currently, there is only one crash kernel region on arm64, which is passed by 
DT property "linux,usable-memory-range",
We need to add another region "crash kernel low" used for crash dump kernel 
devices, so kexec-tools need to add
another DT property "linux,low-memory-range" and then load crash kernel high.

More details can be retrieved from 
http://lists.infradead.org/pipermail/kexec/2019-August/023569.html.

Thanks,
Chen Zhou

> 
> 
> 
> === ===
> 
> 
> .
> 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2019-12-30 Thread Chen Zhou
Hi Dave,

On 2019/12/28 17:32, Dave Young wrote:
> On 12/27/19 at 07:04pm, Chen Zhou wrote:
>> Hi Dave
>>
>> On 2019/12/27 13:54, Dave Young wrote:
>>> Hi,
>>> On 12/23/19 at 11:23pm, Chen Zhou wrote:
>>>> In preparation for supporting reserve_crashkernel_low in arm64 as
>>>> x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
>>>>
>>>> Note, in arm64, we reserve low memory if and only if crashkernel=X,low
>>>> is specified. Different with x86_64, don't set low memory automatically.
>>>
>>> Do you have any reason for the difference?  I'd expect we have same
>>> logic if possible and remove some of the ifdefs.
>>
>> In x86_64, if we reserve crashkernel above 4G, then we call 
>> reserve_crashkernel_low()
>> to reserve low memory.
>>
>> In arm64, to simplify, we call reserve_crashkernel_low() at the beginning of 
>> reserve_crashkernel()
>> and then relax the arm64_dma32_phys_limit if reserve_crashkernel_low() 
>> allocated something.
>> In this case, if reserve crashkernel below 4G there will be 256M low memory 
>> set automatically
>> and this needs extra considerations.
> 
> Sorry that I did not read the old thread details and thought that is
> arch dependent.  But rethink about that, it would be better that we can
> have same semantic about crashkernel parameters across arches.  If we
> make them different then it causes confusion, especially for
> distributions.
> 
> OTOH, I thought if we reserve high memory then the low memory should be
> needed.  There might be some exceptions, but I do not know the exact
> one, can we make the behavior same, and special case those systems which
> do not need low memory reservation.
> 
I thought like this and did implement with crashkernel parameters arch 
independent.
This is my v4: https://lkml.org/lkml/2019/5/6/1361, i implemented according to 
x86_64's
behavior.

>>
>> previous discusses:
>>  https://lkml.org/lkml/2019/6/5/670
>>  https://lkml.org/lkml/2019/6/13/229
> 
> Another concern from James:
> "
> With both crashk_low_res and crashk_res, we end up with two entries in 
> /proc/iomem called
> "Crash kernel". Because its sorted by address, and kexec-tools stops 
> searching when it
> find "Crash kernel", you are always going to get the kernel placed in the 
> lower portion.
> "
> 
> The kexec-tools code is iterating all "Crash kernel" ranges and add them
> in an array.  In X86 code, it uses the higher range to locate memory.

We also discussed about this: https://lkml.org/lkml/2019/6/13/227.
I guess James's opinion is that kexec-tools should take forward compatibility 
into account.
"But we can't rely on people updating user-space when they update the kernel!" 
-- James

> 
>>
>>>
>>>>
>>>> Reported-by: kbuild test robot 
>>>> Signed-off-by: Chen Zhou 
>>>> ---
>>>>  arch/x86/kernel/setup.c| 62 -
>>>>  include/linux/crash_core.h |  3 ++
>>>>  include/linux/kexec.h  |  2 --
>>>>  kernel/crash_core.c| 87 
>>>> ++
>>>>  kernel/kexec_core.c| 17 -
>>>>  5 files changed, 96 insertions(+), 75 deletions(-)
>>>>
>>>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>>>> index cedfe20..5f38942 100644
>>>> --- a/arch/x86/kernel/setup.c
>>>> +++ b/arch/x86/kernel/setup.c
>>>> @@ -486,59 +486,6 @@ static void __init 
>>>> memblock_x86_reserve_range_setup_data(void)
>>>>  # define CRASH_ADDR_HIGH_MAX  SZ_64T
>>>>  #endif
>>>>  
>>>> -static int __init reserve_crashkernel_low(void)
>>>> -{
>>>> -#ifdef CONFIG_X86_64
>>>> -  unsigned long long base, low_base = 0, low_size = 0;
>>>> -  unsigned long total_low_mem;
>>>> -  int ret;
>>>> -
>>>> -  total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
>>>> -
>>>> -  /* crashkernel=Y,low */
>>>> -  ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
>>>> _size, );
>>>> -  if (ret) {
>>>> -  /*
>>>> -   * two parts from kernel/dma/swiotlb.c:
>>>> -   * -swiotlb size: user-specified with swiotlb= or default.
>>>> -   *
>>>> -   * -swiotlb overflow buffer: now hardcoded to 32k. We round it
>>>&g

Re: [PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2019-12-27 Thread Chen Zhou
Hi Dave

On 2019/12/27 13:54, Dave Young wrote:
> Hi,
> On 12/23/19 at 11:23pm, Chen Zhou wrote:
>> In preparation for supporting reserve_crashkernel_low in arm64 as
>> x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.
>>
>> Note, in arm64, we reserve low memory if and only if crashkernel=X,low
>> is specified. Different with x86_64, don't set low memory automatically.
> 
> Do you have any reason for the difference?  I'd expect we have same
> logic if possible and remove some of the ifdefs.

In x86_64, if we reserve crashkernel above 4G, then we call 
reserve_crashkernel_low()
to reserve low memory.

In arm64, to simplify, we call reserve_crashkernel_low() at the beginning of 
reserve_crashkernel()
and then relax the arm64_dma32_phys_limit if reserve_crashkernel_low() 
allocated something.
In this case, if reserve crashkernel below 4G there will be 256M low memory set 
automatically
and this needs extra considerations.

previous discusses:
https://lkml.org/lkml/2019/6/5/670
https://lkml.org/lkml/2019/6/13/229

> 
>>
>> Reported-by: kbuild test robot 
>> Signed-off-by: Chen Zhou 
>> ---
>>  arch/x86/kernel/setup.c| 62 -
>>  include/linux/crash_core.h |  3 ++
>>  include/linux/kexec.h  |  2 --
>>  kernel/crash_core.c| 87 
>> ++
>>  kernel/kexec_core.c| 17 -
>>  5 files changed, 96 insertions(+), 75 deletions(-)
>>
>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index cedfe20..5f38942 100644
>> --- a/arch/x86/kernel/setup.c
>> +++ b/arch/x86/kernel/setup.c
>> @@ -486,59 +486,6 @@ static void __init 
>> memblock_x86_reserve_range_setup_data(void)
>>  # define CRASH_ADDR_HIGH_MAXSZ_64T
>>  #endif
>>  
>> -static int __init reserve_crashkernel_low(void)
>> -{
>> -#ifdef CONFIG_X86_64
>> -unsigned long long base, low_base = 0, low_size = 0;
>> -unsigned long total_low_mem;
>> -int ret;
>> -
>> -total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
>> -
>> -/* crashkernel=Y,low */
>> -ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
>> _size, );
>> -if (ret) {
>> -/*
>> - * two parts from kernel/dma/swiotlb.c:
>> - * -swiotlb size: user-specified with swiotlb= or default.
>> - *
>> - * -swiotlb overflow buffer: now hardcoded to 32k. We round it
>> - * to 8M for other buffers that may need to stay low too. Also
>> - * make sure we allocate enough extra low memory so that we
>> - * don't run out of DMA buffers for 32-bit devices.
>> - */
>> -low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
>> << 20);
>> -} else {
>> -/* passed with crashkernel=0,low ? */
>> -if (!low_size)
>> -return 0;
>> -}
>> -
>> -low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
>> -if (!low_base) {
>> -pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
>> smaller size.\n",
>> -   (unsigned long)(low_size >> 20));
>> -return -ENOMEM;
>> -}
>> -
>> -ret = memblock_reserve(low_base, low_size);
>> -if (ret) {
>> -pr_err("%s: Error reserving crashkernel low memblock.\n", 
>> __func__);
>> -return ret;
>> -}
>> -
>> -pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
>> low RAM: %ldMB)\n",
>> -(unsigned long)(low_size >> 20),
>> -(unsigned long)(low_base >> 20),
>> -(unsigned long)(total_low_mem >> 20));
>> -
>> -crashk_low_res.start = low_base;
>> -crashk_low_res.end   = low_base + low_size - 1;
>> -insert_resource(_resource, _low_res);
>> -#endif
>> -return 0;
>> -}
>> -
>>  static void __init reserve_crashkernel(void)
>>  {
>>  unsigned long long crash_size, crash_base, total_mem;
>> @@ -602,9 +549,12 @@ static void __init reserve_crashkernel(void)
>>  return;
>>  }
>>  
>> -if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
>> -memblock_free(crash_base, crash_size);
>> -return;
>> +if (crash_base &

[PATCH v7 4/4] kdump: update Documentation about crashkernel on arm64

2019-12-23 Thread Chen Zhou
Now we support crashkernel=X,[low] on arm64, update the Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kdump/kdump.rst   | 13 +++--
 Documentation/admin-guide/kernel-parameters.txt | 12 +++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index ac7e131..e55173e 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,13 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=Y[@X]" to select a region under 4G first, and
+   fall back to reserve region above 4G when '@offset' hasn't been specified.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +322,11 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   On arm64, use "crashkernel=Y[@X]". Note that the start address of
the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   If crashkernel=Z,low is specified simultaneously, reserve spcified size
+   low memory for crash kdump kernel devices firstly and then reserve memory
+   above 4G.
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ade4e6e..bde3ab4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -706,6 +706,9 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] If crashkernel=X,low is specified, reserve
+   spcified size low memory for crash kdump kernel devices
+   firstly, and then reserve memory above 4G.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -730,12 +733,19 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
+   [KNL, arm64] range under 4G.
+   This one let user to specify own low range under 4G
+   for crash dump kernel instead.
+   Different with x86_64, kernel allocates specified size
+   physical memory region only when this parameter is 
specified
+   instead of trying to allocate at least 256M below 4G
+   automatically.
 
cryptomgr.notests
[KNL] Disable crypto self-tests
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 3/4] arm64: kdump: add memory for devices by DT property, low-memory-range

2019-12-23 Thread Chen Zhou
If we want to reserve crashkernel above 4G, we could use parameters
"crashkernel=X crashkernel=Y,low", in this case, specified size low
memory is reserved for crash dump kernel devices and never mapped by
the first kernel. This memory range is advertised to crash dump kernel
via DT property under /chosen,
linux,low-memory-range=

Crash dump kernel reads this property at boot time and call
memblock_add() after memblock_cap_memory_range() has been called.

Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 0d7afd5..1c4a6ad 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -322,6 +322,26 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init early_init_dt_scan_lowmem(unsigned long node,
+   const char *uname, int depth, void *data)
+{
+   struct memblock_region *lowmem = data;
+   const __be32 *reg;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "chosen") != 0)
+   return 0;
+
+   reg = of_get_flat_dt_prop(node, "linux,low-memory-range", );
+   if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
+   return 1;
+
+   lowmem->base = dt_mem_next_cell(dt_root_addr_cells, );
+   lowmem->size = dt_mem_next_cell(dt_root_size_cells, );
+
+   return 1;
+}
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
@@ -352,13 +372,21 @@ static void __init fdt_enforce_memory_region(void)
 
if (reg.size)
memblock_cap_memory_range(reg.base, reg.size);
+
+   of_scan_flat_dt(early_init_dt_scan_lowmem, );
+
+   if (reg.size)
+   memblock_add(reg.base, reg.size);
 }
 
 void __init arm64_memblock_init(void)
 {
const s64 linear_region_size = BIT(vabits_actual - 1);
 
-   /* Handle linux,usable-memory-range property */
+   /*
+* Handle linux,usable-memory-range and linux,low-memory-range
+* properties.
+*/
fdt_enforce_memory_region();
 
/* Remove memory above our supported physical address size */
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2019-12-23 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.

Note, in arm64, we reserve low memory if and only if crashkernel=X,low
is specified. Different with x86_64, don't set low memory automatically.

Reported-by: kbuild test robot 
Signed-off-by: Chen Zhou 
---
 arch/x86/kernel/setup.c| 62 -
 include/linux/crash_core.h |  3 ++
 include/linux/kexec.h  |  2 --
 kernel/crash_core.c| 87 ++
 kernel/kexec_core.c| 17 -
 5 files changed, 96 insertions(+), 75 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cedfe20..5f38942 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -486,59 +486,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   SZ_64T
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -602,9 +549,12 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 525510a..4df8c0b 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -63,6 +63,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 extern unsigned char *vmcoreinfo_data;
 extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
+extern struct resource crashk_res;
+extern struct resource crashk_low_res;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
  void *data, size_t data_len);
@@ -74,5 +76,6 @@ int parse_crashkernel_high(char *cmdline, unsigned long long 
system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
+int __init reserve_crashkernel_low(void);
 
 #endif /* LINUX_CRASH_CORE_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 1776eb2..5d5d963 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -330,8 +330,6 @@ extern int kexec_load_disabled;
 
 /* Locati

[PATCH v7 2/4] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2019-12-23 Thread Chen Zhou
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

Signed-off-by: Chen Zhou 
---
 arch/arm64/kernel/setup.c |  8 +++-
 arch/arm64/mm/init.c  | 31 +--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 56f6645..04d1c87 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index b65dffd..0d7afd5 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -80,6 +80,7 @@ static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
int ret;
+   phys_addr_t crash_max = arm64_dma32_phys_limit;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
@@ -87,12 +88,38 @@ static void __init reserve_crashkernel(void)
if (ret || !crash_size)
return;
 
+   ret = reserve_crashkernel_low();
+   if (!ret && crashk_low_res.end) {
+   /*
+* If crashkernel=X,low specified, there may be two regions,
+* we need to make some changes as follows:
+*
+* 1. rename the low region as "Crash kernel (low)"
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*
+* 2. change the upper bound for crash memory
+* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash memory.
+*
+* 3. mark the low region as "nomap"
+* The low region is intended to be used for crash dump kernel
+* devices, just mark the low region as "nomap" simply.
+*/
+   const char *rename = "Crash kernel (low)";
+
+   crashk_low_res.name = rename;
+   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
+   memblock_mark_nomap(crashk_low_res.start,
+   resource_size(_low_res));
+   }
+
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, crash_max, crash_size,
+   SZ_2M);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-12-23 Thread Chen Zhou
This patch series enable reserving crashkernel above 4G in arm64.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are required, crash dump kernel
will boot failure because there is no low memory available for allocation.

To solve these issues, introduce crashkernel=X,low to reserve specified
size low memory.
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
is specified simultaneously, kernel should reserve specified size low memory
for crash dump kernel devices. So there may be two crash kernel regions, one
is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use of
kexec-tools, rename the low region as "Crash kernel (low)", and add DT property
"linux,low-memory-range" to crash dump kernel's dtb to pass the low region.

Besides, we need to modify kexec-tools:
arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])

The previous changes and discussions can be retrieved from:

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142

Chen Zhou (4):
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reserve crashkenel above 4G for crash dump kernel
  arm64: kdump: add memory for devices by DT property, low-memory-range
  kdump: update Documentation about crashkernel on arm64

 Documentation/admin-guide/kdump/kdump.rst   | 13 +++-
 Documentation/admin-guide/kernel-parameters.txt | 12 +++-
 arch/arm64/kernel/setup.c   |  8 ++-
 arch/arm64/mm/init.c| 61 -
 arch/x86/kernel/setup.c | 62 ++
 include/linux/crash_core.h  |  3 +
 include/linux/kexec.h   |  2 -
 kernel/crash_core.c | 87 +
 kernel/kexec_core.c | 17 -
 9 files changed, 183 insertions(+), 82 deletions(-)

-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: `

2019-12-19 Thread Chen Zhou
Hi John,

On 2019/12/20 2:33, John Donnelly wrote:
> 
> 
>> On Dec 18, 2019, at 8:56 PM, Chen Zhou  wrote:
>>
>> Hi John,
>>
>> On 2019/12/19 1:18, John Donnelly wrote:
>>> HI 
>>>
>>> SEE INLINE ON A QUESTION :
>>>
>>>> On Dec 17, 2019, at 8:07 PM, Chen Zhou  wrote:
>>>>
>>>> Hi all,
>>>>
>>>> Friendly ping...
>>>>
>>>> On 2019/8/30 15:11, Chen Zhou wrote:
>>>>> I am busy with other things, so it was a long time before this version was
>>>>> released.
>>>>>
>>>>> This patch series enable reserving crashkernel above 4G in arm64.
>>>>>
>>>>> There are following issues in arm64 kdump:
>>>>> 1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
>>>>> when there is no enough low memory.
>>>>> 2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
>>>>> in this case, if swiotlb or DMA buffers are requierd, crash dump kernel
>>>>> will boot failure because there is no low memory available for allocation.
>>>
>>>
>>>  Can you elaborate when the boot failures may fail due to lacking  
>>> swiotlb or DMA buffers ? Are these related to certain adapters or specific  
>>> platforms  ? 
>>>
>>> I have not seen this when using   crashkernel=2024M@35GB . 
>>>
>>
>> For example, in my environment "Huawei TaiShan 2280",
>> we need to use mpt3sas driver in crash dump kernel for dumping vmcore.
>>
>> mpt3sas driver needs to call dma_pool_alloc to allocate some pages,
>> if there is no DMA buffer, page allocation will fail, which leads to crash 
>> dump kernel boot failure,
>> like this:
>>
>> [2019/12/19 9:12:41] [   12.403501] mpt3sas_cm0: diag reset: SUCCESS
>> [2019/12/19 9:12:41] [   12.456076] mpt3sas_cm0: reply_post_free pool: 
>> dma_pool_alloc failed
>> [2019/12/19 9:12:41] [   12.462515] pci 0004:48:00.0: can't derive routing 
>> for PCI INT A
>> [2019/12/19 9:12:41] [   12.468761] mpt3sas 0004:49:00.0: PCI INT A: no GSI
>> [2019/12/19 9:12:41] [   12.476348] mpt3sas_cm0: failure at 
>> drivers/scsi/mpt3sas/mpt3sas_scsih.c:10626/_scsih_probe()!
>> [2019/12/19 9:14:38] [ TIME ] Timed out waiting for device 
>> dev-di…b3\x2d890a\x2d2ead7df26f48.device.
>> [2019/12/19 9:14:38] [DEPEND] Dependency failed for Initrd Root Device.
>> [2019/12/19 9:14:38] [DEPEND] Dependency failed for /sysroot.
>> [2019/12/19 9:14:38] [DEPEND] Dependency failed for Initrd Root File System.
>> [2019/12/19 9:14:38] [DEPEND] Dependency failed for Reload Configuration 
>> from the Real Root.
>> [2019/12/19 9:14:38] [DEPEND] Dependency failed for File System 
>> C…40bae-9eb8-46b3-890a-2ead7df26f48.
> 
> 
>  Thank you for sharing .  We are not seeing this issue on a 5.4.0.rc8 ;
> Like I said in a previous email we can  take crash dumps using 
> crashkernel=768M for a  “ standard “ small VMcore to local storage :
> 
> 0004:01:00.0 RAID bus controller: Broadcom / LSI MegaRAID SAS-3 3316 
> [Intruder] (rev 01)
>   Subsystem: Broadcom / LSI MegaRAID SAS 9361-16i
>   Kernel driver in use: megaraid_sas 
> 
> 
> What version of the kernel are you using ?

5.5.0.rc1

As I said in the patch series cover-letter, this patch series address following 
cases/isssues.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are required, crash dump kernel
will boot failure because there is no low memory available for allocation.

From your description, you use crashkernel=768M.
There are enough crashkernel below 4G, so crashkernel will be
reserved successfully and kdump be ok. (This case has no DMA buffers issue.)

or you use crashkernel=2024M@35GB, and this case is ok?
If your driver doesn't need DMA buffers(I am not sure about it), kdump will 
also be ok.


If i understand your question and explain clearly?

Thanks,
Chen Zhou

> 
> 
>>
>> Thanks,
>> Chen Zhou
>>
>>>
>>>>>
>>>>> To solve these issues, introduce crashkernel=X,low to reserve specified
>>>>> size low memory.
>>>>> Crashkernel=X tries to reserve memory for the crash dump kernel under
>>>>> 4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
>>>>> size low memory for crash kdump kernel devices first

Re: [PATCH v6 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-12-18 Thread Chen Zhou
Hi John,

On 2019/12/19 1:18, John Donnelly wrote:
> HI 
> 
> SEE INLINE ON A QUESTION :
> 
>> On Dec 17, 2019, at 8:07 PM, Chen Zhou  wrote:
>>
>> Hi all,
>>
>> Friendly ping...
>>
>> On 2019/8/30 15:11, Chen Zhou wrote:
>>> I am busy with other things, so it was a long time before this version was
>>> released.
>>>
>>> This patch series enable reserving crashkernel above 4G in arm64.
>>>
>>> There are following issues in arm64 kdump:
>>> 1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
>>> when there is no enough low memory.
>>> 2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
>>> in this case, if swiotlb or DMA buffers are requierd, crash dump kernel
>>> will boot failure because there is no low memory available for allocation.
> 
>   
>   Can you elaborate when the boot failures may fail due to lacking  
> swiotlb or DMA buffers ? Are these related to certain adapters or specific  
> platforms  ? 
> 
>  I have not seen this when using   crashkernel=2024M@35GB . 
> 

For example, in my environment "Huawei TaiShan 2280",
we need to use mpt3sas driver in crash dump kernel for dumping vmcore.

mpt3sas driver needs to call dma_pool_alloc to allocate some pages,
if there is no DMA buffer, page allocation will fail, which leads to crash dump 
kernel boot failure,
like this:

[2019/12/19 9:12:41] [   12.403501] mpt3sas_cm0: diag reset: SUCCESS
[2019/12/19 9:12:41] [   12.456076] mpt3sas_cm0: reply_post_free pool: 
dma_pool_alloc failed
[2019/12/19 9:12:41] [   12.462515] pci 0004:48:00.0: can't derive routing for 
PCI INT A
[2019/12/19 9:12:41] [   12.468761] mpt3sas 0004:49:00.0: PCI INT A: no GSI
[2019/12/19 9:12:41] [   12.476348] mpt3sas_cm0: failure at 
drivers/scsi/mpt3sas/mpt3sas_scsih.c:10626/_scsih_probe()!
[2019/12/19 9:14:38] [ TIME ] Timed out waiting for device 
dev-di…b3\x2d890a\x2d2ead7df26f48.device.
[2019/12/19 9:14:38] [DEPEND] Dependency failed for Initrd Root Device.
[2019/12/19 9:14:38] [DEPEND] Dependency failed for /sysroot.
[2019/12/19 9:14:38] [DEPEND] Dependency failed for Initrd Root File System.
[2019/12/19 9:14:38] [DEPEND] Dependency failed for Reload Configuration from 
the Real Root.
[2019/12/19 9:14:38] [DEPEND] Dependency failed for File System 
C…40bae-9eb8-46b3-890a-2ead7df26f48.

Thanks,
Chen Zhou

> 
>>>
>>> To solve these issues, introduce crashkernel=X,low to reserve specified
>>> size low memory.
>>> Crashkernel=X tries to reserve memory for the crash dump kernel under
>>> 4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
>>> size low memory for crash kdump kernel devices firstly and then reserve
>>> memory above 4G.
>>>
>>> When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
>>> is specified simultaneously, kernel should reserve specified size low memory
>>> for crash dump kernel devices. So there may be two crash kernel regions, one
>>> is below 4G, the other is above 4G.
>>> In order to distinct from the high region and make no effect to the use of
>>> kexec-tools, rename the low region as "Crash kernel (low)", and add DT 
>>> property
>>> "linux,low-memory-range" to crash dump kernel's dtb to pass the low region.
>>>
>>> Besides, we need to modify kexec-tools:
>>> arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])
>>>
>>> The previous changes and discussions can be retrieved from:
>>>
>>> Changes since [v5]
>>> - Move reserve_crashkernel_low() into kernel/crash_core.c.
>>> - Delete crashkernel=X,high.
>>> - Modify crashkernel=X,low.
>>> If crashkernel=X,low is specified simultaneously, reserve spcified size low
>>> memory for crash kdump kernel devices firstly and then reserve memory above 
>>> 4G.
>>> In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and 
>>> then
>>> pass to crash dump kernel by DT property "linux,low-memory-range".
>>> - Update Documentation/admin-guide/kdump/kdump.rst.
>>>
>>> Changes since [v4]
>>> - Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.
>>>
>>> Changes since [v3]
>>> - Add memblock_cap_memory_ranges back for multiple ranges.
>>> - Fix some compiling warnings.
>>>
>>> Changes since [v2]
>>> - Split patch "arm64: kdump: support reserving crashkernel above 4G" as
>>> two. Put "move reserve_crashkernel_low() i

Re: [PATCH v6 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-12-18 Thread Chen Zhou
Hi Will

On 2019/12/18 17:09, Will Deacon wrote:
> On Wed, Dec 18, 2019 at 10:07:59AM +0800, Chen Zhou wrote:
>> Friendly ping...
> 
> You broke the build:
> 
> https://lore.kernel.org/lkml/201909010744.cde940pv%...@intel.com
> https://lore.kernel.org/lkml/201909010704.4m9y2sg7%...@intel.com
> 
> So I doubt anybody will seriously look at this.

I was also waiting for other suggestions.
I will fix this in next version.

> 
> Will
> 
> .

Thanks,
Chen Zhou


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-12-17 Thread Chen Zhou
Hi all,

Friendly ping...

On 2019/8/30 15:11, Chen Zhou wrote:
> I am busy with other things, so it was a long time before this version was
> released.
> 
> This patch series enable reserving crashkernel above 4G in arm64.
> 
> There are following issues in arm64 kdump:
> 1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
> when there is no enough low memory.
> 2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
> in this case, if swiotlb or DMA buffers are requierd, crash dump kernel
> will boot failure because there is no low memory available for allocation.
> 
> To solve these issues, introduce crashkernel=X,low to reserve specified
> size low memory.
> Crashkernel=X tries to reserve memory for the crash dump kernel under
> 4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
> size low memory for crash kdump kernel devices firstly and then reserve
> memory above 4G.
> 
> When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
> is specified simultaneously, kernel should reserve specified size low memory
> for crash dump kernel devices. So there may be two crash kernel regions, one
> is below 4G, the other is above 4G.
> In order to distinct from the high region and make no effect to the use of
> kexec-tools, rename the low region as "Crash kernel (low)", and add DT 
> property
> "linux,low-memory-range" to crash dump kernel's dtb to pass the low region.
> 
> Besides, we need to modify kexec-tools:
> arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])
> 
> The previous changes and discussions can be retrieved from:
> 
> Changes since [v5]
> - Move reserve_crashkernel_low() into kernel/crash_core.c.
> - Delete crashkernel=X,high.
> - Modify crashkernel=X,low.
> If crashkernel=X,low is specified simultaneously, reserve spcified size low
> memory for crash kdump kernel devices firstly and then reserve memory above 
> 4G.
> In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
> pass to crash dump kernel by DT property "linux,low-memory-range".
> - Update Documentation/admin-guide/kdump/kdump.rst.
> 
> Changes since [v4]
> - Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.
> 
> Changes since [v3]
> - Add memblock_cap_memory_ranges back for multiple ranges.
> - Fix some compiling warnings.
> 
> Changes since [v2]
> - Split patch "arm64: kdump: support reserving crashkernel above 4G" as
> two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
> patch.
> 
> Changes since [v1]:
> - Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
> - Remove memblock_cap_memory_ranges() i added in v1 and implement that
> in fdt_enforce_memory_region().
> There are at most two crash kernel regions, for two crash kernel regions
> case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
> and then remove the memory range in the middle.
> 
> [1]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
> [v1]: https://lkml.org/lkml/2019/4/2/1174
> [v2]: https://lkml.org/lkml/2019/4/9/86
> [v3]: https://lkml.org/lkml/2019/4/9/306
> [v4]: https://lkml.org/lkml/2019/4/15/273
> [v5]: https://lkml.org/lkml/2019/5/6/1360
> 
> Chen Zhou (4):
>   x86: kdump: move reserve_crashkernel_low() into crash_core.c
>   arm64: kdump: reserve crashkenel above 4G for crash dump kernel
>   arm64: kdump: add memory for devices by DT property, low-memory-range
>   kdump: update Documentation about crashkernel on arm64
> 
>  Documentation/admin-guide/kdump/kdump.rst   | 13 -
>  Documentation/admin-guide/kernel-parameters.txt | 12 -
>  arch/arm64/include/asm/kexec.h  |  3 ++
>  arch/arm64/kernel/setup.c   |  8 ++-
>  arch/arm64/mm/init.c| 61 +--
>  arch/x86/include/asm/kexec.h|  3 ++
>  arch/x86/kernel/setup.c | 65 
> +++--
>  include/linux/crash_core.h  |  4 ++
>  include/linux/kexec.h   |  1 -
>  kernel/crash_core.c | 65 
> +
>  10 files changed, 168 insertions(+), 67 deletions(-)
> 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v6 4/4] kdump: update Documentation about crashkernel on arm64

2019-08-30 Thread Chen Zhou
Now we support crashkernel=X,[low] on arm64, update the Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kdump/kdump.rst   | 13 +++--
 Documentation/admin-guide/kernel-parameters.txt | 12 +++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index ac7e131..e55173e 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,13 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=Y[@X]" to select a region under 4G first, and
+   fall back to reserve region above 4G when '@offset' hasn't been specified.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +322,11 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   On arm64, use "crashkernel=Y[@X]". Note that the start address of
the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   If crashkernel=Z,low is specified simultaneously, reserve spcified size
+   low memory for crash kdump kernel devices firstly and then reserve memory
+   above 4G.
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 4c19719..069a122 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -708,6 +708,9 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] If crashkernel=X,low is specified, reserve
+   spcified size low memory for crash kdump kernel devices
+   firstly, and then reserve memory above 4G.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -732,12 +735,19 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
+   [KNL, arm64] range under 4G.
+   This one let user to specify own low range under 4G
+   for crash dump kernel instead.
+   Different with x86_64, kernel allocates specified size
+   physical memory region only when this parameter is 
specified
+   instead of trying to allocate at least 256M below 4G
+   automatically.
 
cryptomgr.notests
[KNL] Disable crypto self-tests
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v6 3/4] arm64: kdump: add memory for devices by DT property, low-memory-range

2019-08-30 Thread Chen Zhou
If we want to reserve crashkernel above 4G, we could use parameters
"crashkernel=X crashkernel=Y,low", in this case, specified size low
memory is reserved for crash dump kernel devices and never mapped by
the first kernel. This memory range is advertised to crash dump kernel
via DT property under /chosen,
linux,low-memory-range=

Crash dump kernel reads this property at boot time and call
memblock_add() after memblock_cap_memory_range() has been called.

Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index c99f845..a376b18 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -294,6 +294,26 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init early_init_dt_scan_lowmem(unsigned long node,
+   const char *uname, int depth, void *data)
+{
+   struct memblock_region *lowmem = data;
+   const __be32 *reg;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "chosen") != 0)
+   return 0;
+
+   reg = of_get_flat_dt_prop(node, "linux,low-memory-range", );
+   if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
+   return 1;
+
+   lowmem->base = dt_mem_next_cell(dt_root_addr_cells, );
+   lowmem->size = dt_mem_next_cell(dt_root_size_cells, );
+
+   return 1;
+}
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
@@ -324,13 +344,21 @@ static void __init fdt_enforce_memory_region(void)
 
if (reg.size)
memblock_cap_memory_range(reg.base, reg.size);
+
+   of_scan_flat_dt(early_init_dt_scan_lowmem, );
+
+   if (reg.size)
+   memblock_add(reg.base, reg.size);
 }
 
 void __init arm64_memblock_init(void)
 {
const s64 linear_region_size = -(s64)PAGE_OFFSET;
 
-   /* Handle linux,usable-memory-range property */
+   /*
+* Handle linux,usable-memory-range and linux,low-memory-range
+* properties.
+*/
fdt_enforce_memory_region();
 
/* Remove memory above our supported physical address size */
-- 
2.7.4



[PATCH v6 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-08-30 Thread Chen Zhou
I am busy with other things, so it was a long time before this version was
released.

This patch series enable reserving crashkernel above 4G in arm64.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are requierd, crash dump kernel
will boot failure because there is no low memory available for allocation.

To solve these issues, introduce crashkernel=X,low to reserve specified
size low memory.
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
is specified simultaneously, kernel should reserve specified size low memory
for crash dump kernel devices. So there may be two crash kernel regions, one
is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use of
kexec-tools, rename the low region as "Crash kernel (low)", and add DT property
"linux,low-memory-range" to crash dump kernel's dtb to pass the low region.

Besides, we need to modify kexec-tools:
arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])

The previous changes and discussions can be retrieved from:

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360

Chen Zhou (4):
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reserve crashkenel above 4G for crash dump kernel
  arm64: kdump: add memory for devices by DT property, low-memory-range
  kdump: update Documentation about crashkernel on arm64

 Documentation/admin-guide/kdump/kdump.rst   | 13 -
 Documentation/admin-guide/kernel-parameters.txt | 12 -
 arch/arm64/include/asm/kexec.h  |  3 ++
 arch/arm64/kernel/setup.c   |  8 ++-
 arch/arm64/mm/init.c| 61 +--
 arch/x86/include/asm/kexec.h|  3 ++
 arch/x86/kernel/setup.c | 65 +++--
 include/linux/crash_core.h  |  4 ++
 include/linux/kexec.h   |  1 -
 kernel/crash_core.c | 65 +
 10 files changed, 168 insertions(+), 67 deletions(-)

-- 
2.7.4



[PATCH v6 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2019-08-30 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.

Note, in arm64, we reserve low memory if and only if crashkernel=X,low
is specified. Different with x86_64, don't set low memory automatically.

Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/kexec.h |  3 ++
 arch/x86/kernel/setup.c  | 65 
 include/linux/crash_core.h   |  4 +++
 include/linux/kexec.h|  1 -
 kernel/crash_core.c  | 65 
 5 files changed, 78 insertions(+), 60 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 5e7d6b4..bf21d6c 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,9 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_16M
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index bbe35bf..2b437c4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -449,9 +449,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_16M
-
 /*
  * Keep the crash kernel below this limit.
  *
@@ -473,59 +470,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   SZ_64T
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from lib/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -589,9 +533,12 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 525510a..9192e43 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -6,6 +6,8 @@
 #include 
 #include 
 
+#include 
+
 #define CRASH_CORE_NOTE_NAME  "CORE"
 #define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
 #define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
@@ -63,6 +65,7 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 extern unsigned char *vmcoreinfo_data;
 extern size_t vmcoreinfo_size;
 extern u32 *vmcore

[PATCH v6 2/4] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2019-08-30 Thread Chen Zhou
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h |  3 +++
 arch/arm64/kernel/setup.c  |  8 +++-
 arch/arm64/mm/init.c   | 31 +--
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 12a561a..88279a9 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -25,6 +25,9 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 9c4bad7..2ead608 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -231,7 +231,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f3c7952..c99f845 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -64,6 +64,7 @@ static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
int ret;
+   phys_addr_t crash_max = ARCH_LOW_ADDRESS_LIMIT;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
@@ -71,12 +72,38 @@ static void __init reserve_crashkernel(void)
if (ret || !crash_size)
return;
 
+   ret = reserve_crashkernel_low();
+   if (!ret && crashk_low_res.end) {
+   /*
+* If crashkernel=X,low specified, there may be two regions,
+* we need to make some changes as follows:
+*
+* 1. rename the low region as "Crash kernel (low)"
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*
+* 2. change the upper bound for crash memory
+* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash memory.
+*
+* 3. mark the low region as "nomap"
+* The low region is intended to be used for crash dump kernel
+* devices, just mark the low region as "nomap" simply.
+*/
+   const char *rename = "Crash kernel (low)";
+
+   crashk_low_res.name = rename;
+   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
+   memblock_mark_nomap(crashk_low_res.start,
+   resource_size(_low_res));
+   }
+
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, crash_max, crash_size,
+   SZ_2M);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
-- 
2.7.4



[PATCH v2] arm64: kdump: add another DT property to crash dump kernel's dtb

2019-08-30 Thread Chen Zhou
Currently, there is only one crash kernel region on arm64, we add
another region "crash kernel low" used for crash dump kernel devices.

To do this, we add DT property "linux,low-memory-range" to crash
dump kernel's dtb to pass the low region.

Signed-off-by: Chen Zhou 
---
For "support reserving crashkernel above 4G on arm64 kdump", we need to
modify the kexec-tools.

I will post patch series "[PATCH v6 0/4] support reserving crashkernel
above 4G on arm64 kdump". This version is much different from the previous
one and the kexec-tools part neeed to be modified.

Changes since [v1]:
- Add another DT property "linux,low-memory-range" to crash dump kernel's
dtb to pass the low region instead of reusing "linux,usable-memory-range".

[1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
---
 kexec/arch/arm64/crashdump-arm64.c | 29 +++--
 kexec/arch/arm64/crashdump-arm64.h |  2 ++
 kexec/arch/arm64/iomem.h   |  1 +
 kexec/arch/arm64/kexec-arm64.c | 27 +++
 4 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/kexec/arch/arm64/crashdump-arm64.c 
b/kexec/arch/arm64/crashdump-arm64.c
index 4fd7aa8..a8be036 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -39,6 +39,14 @@ struct memory_ranges usablemem_rgns = {
.ranges = _reserved_mem,
 };
 
+/* memory range reserved for crashkernel low, optional */
+struct memory_range crash_reserved_low_mem;
+struct memory_ranges lowmem_rgns = {
+   .size = 0,
+   .max_size = 1,
+   .ranges = _reserved_low_mem,
+};
+
 struct memory_range elfcorehdr_mem;
 
 static struct crash_elf_info elf_info = {
@@ -89,7 +97,10 @@ static int iomem_range_callback(void *UNUSED(data), int 
UNUSED(nr),
char *str, unsigned long long base,
unsigned long long length)
 {
-   if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
+   if (strncmp(str, CRASH_KERNEL_LOW, strlen(CRASH_KERNEL_LOW)) == 0)
+   return mem_regions_add(_rgns,
+   base, length, RANGE_RAM);
+   else if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
return mem_regions_add(_rgns,
   base, length, RANGE_RAM);
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
@@ -129,7 +140,7 @@ static int crash_get_memory_ranges(void)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-   /* allow only a single region for crash dump kernel */
+   /* allow only a single usablemem region for crash dump kernel */
if (usablemem_rgns.size != 1)
return -EINVAL;
 
@@ -141,6 +152,20 @@ static int crash_get_memory_ranges(void)
return -ENOMEM;
}
 
+   /* lowmem region for crash dump kernel is optional, at most one region 
*/
+   if (lowmem_rgns.size > 1)
+   return -EINVAL;
+
+   if (lowmem_rgns.size) {
+   dbgprint_mem_range("Reserved low memory range", 
_reserved_low_mem,
+   1);
+
+   if (mem_regions_exclude(_memory_rgns, 
_reserved_low_mem)) {
+   fprintf(stderr,
+   "Error: Number of crash memory ranges 
excedeed the max limit\n");
+   return -ENOMEM;
+   }
+   }
/*
 * Make sure that the memory regions are sorted.
 */
diff --git a/kexec/arch/arm64/crashdump-arm64.h 
b/kexec/arch/arm64/crashdump-arm64.h
index 880b83a..f185534 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -18,6 +18,8 @@
 
 extern struct memory_ranges usablemem_rgns;
 extern struct memory_range crash_reserved_mem;
+extern struct memory_ranges lowmem_rgns;
+extern struct memory_range crash_reserved_low_mem;
 extern struct memory_range elfcorehdr_mem;
 
 extern int load_crashdump_segments(struct kexec_info *info);
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
index d4864bb..45d7953 100644
--- a/kexec/arch/arm64/iomem.h
+++ b/kexec/arch/arm64/iomem.h
@@ -4,6 +4,7 @@
 #define SYSTEM_RAM "System RAM\n"
 #define KERNEL_CODE"Kernel code\n"
 #define KERNEL_DATA"Kernel data\n"
+#define CRASH_KERNEL_LOW   "Crash kernel (low)\n"
 #define CRASH_KERNEL   "Crash kernel\n"
 #define IOMEM_RESERVED "reserved\n"
 
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index eb3a3a3..dddec23 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -38,6 +38,7 @@
 #define PROP_SIZE_CELLS "#size-cells"
 #define PROP_ELFCOREHDR &qu

Re: [PATCH 1/4] x86: kdump: move reserve_crashkernel_low() into kexec_core.c

2019-06-13 Thread Chen Zhou
Hi Dave,

On 2019/6/12 16:45, Dave Young wrote:
> Other than the comments from James, can you move the function into
> kernel/crash_core.c, we already have some functions moved there for
> sharing.

Sure.

Thanks,
Chen Zhou


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-06-13 Thread Chen Zhou



On 2019/6/6 0:32, James Morse wrote:
> Hi!
> 
> On 07/05/2019 04:50, Chen Zhou wrote:
>> We use crashkernel=X to reserve crashkernel below 4G, which will fail
>> when there is no enough memory. Currently, crashkernel=Y@X can be used
>> to reserve crashkernel above 4G, in this case, if swiotlb or DMA buffers
>> are requierd, capture kernel will boot failure because of no low memory.
> 
>> When crashkernel is reserved above 4G in memory, kernel should reserve
>> some amount of low memory for swiotlb and some DMA buffers. So there may
>> be two crash kernel regions, one is below 4G, the other is above 4G.
> 
> This is a good argument for supporting the 'crashkernel=...,low' version.
> What is the 'crashkernel=...,high' version for?
> 
> Wouldn't it be simpler to relax the ARCH_LOW_ADDRESS_LIMIT if we see 
> 'crashkernel=...,low'
> in the kernel cmdline?
> 
> I don't see what the 'crashkernel=...,high' variant is giving us, it just 
> complicates the
> flow of reserve_crashkernel().
> 
> If we called reserve_crashkernel_low() at the beginning of 
> reserve_crashkernel() we could
> use crashk_low_res.end to change some limit variable from 
> ARCH_LOW_ADDRESS_LIMIT to
> memblock_end_of_DRAM().
> I think this is a simpler change that gives you what you want.

According to your suggestions, we should do like this:
1. call reserve_crashkernel_low() at the beginning of reserve_crashkernel()
2. mark the low region as 'nomap'
3. use crashk_low_res.end to change some limit variable from 
ARCH_LOW_ADDRESS_LIMIT to
memblock_end_of_DRAM()
4. rename crashk_low_res as "Crash kernel (low)" for arm64
5. add an 'linux,low-memory-range' node in DT

Do i understand correctly?

> 
> 
>> Then
>> Crash dump kernel reads more than one crash kernel regions via a dtb
>> property under node /chosen,
>> linux,usable-memory-range = .
> 
> Won't this break if your kdump kernel doesn't know what the extra parameters 
> are?
> Or if it expects two ranges, but only gets one? These DT properties should be 
> treated as
> ABI between kernel versions, we can't really change it like this.
> 
> I think the 'low' region is an optional-extra, that is never mapped by the 
> first kernel. I
> think the simplest thing to do is to add an 'linux,low-memory-range' that we
> memblock_add() after memblock_cap_memory_range() has been called.
> If its missing, or the new kernel doesn't know what its for, everything keeps 
> working.
> 
> 
>> Besides, we need to modify kexec-tools:
>>   arm64: support more than one crash kernel regions(see [1])
> 
>> I post this patch series about one month ago. The previous changes and
>> discussions can be retrived from:
> 
> Ah, this wasn't obvious as you've stopped numbering the series. Please label 
> the next one
> 'v6' so that we can describe this as 'v5'. (duplicate numbering would be even 
> more confusing!)
> 
ok.

> 
> Thanks,
> 
> James
> 
> .
> 

Thanks,
Chen Zhou


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH 2/4] arm64: kdump: support reserving crashkernel above 4G

2019-06-13 Thread Chen Zhou
Hi James,

On 2019/6/6 0:29, James Morse wrote:
> Hello,
> 
> On 07/05/2019 04:50, Chen Zhou wrote:
>> When crashkernel is reserved above 4G in memory, kernel should
>> reserve some amount of low memory for swiotlb and some DMA buffers.
> 
>> Meanwhile, support crashkernel=X,[high,low] in arm64. When use
>> crashkernel=X parameter, try low memory first and fall back to high
>> memory unless "crashkernel=X,high" is specified.
> 
> What is the 'unless crashkernel=...,high' for? I think it would be simpler to 
> relax the
> ARCH_LOW_ADDRESS_LIMIT if reserve_crashkernel_low() allocated something.
> 
> This way "crashkernel=1G" tries to allocate 1G below 4G, but fails if there 
> isn't enough
> memory. "crashkernel=1G crashkernel=16M,low" allocates 16M below 4G, which is 
> more likely
> to succeed, if it does it can then place the 1G block anywhere.
> 
Yeah, this is much simpler.

> 
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 413d566..82cd9a0 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -243,6 +243,9 @@ static void __init request_standard_resources(void)
>>  request_resource(res, _data);
>>  #ifdef CONFIG_KEXEC_CORE
>>  /* Userspace will find "Crash kernel" region in /proc/iomem. */
>> +if (crashk_low_res.end && crashk_low_res.start >= res->start &&
>> +crashk_low_res.end <= res->end)
>> +request_resource(res, _low_res);
>>  if (crashk_res.end && crashk_res.start >= res->start &&
>>  crashk_res.end <= res->end)
>>  request_resource(res, _res);
> 
> With both crashk_low_res and crashk_res, we end up with two entries in 
> /proc/iomem called
> "Crash kernel". Because its sorted by address, and kexec-tools stops 
> searching when it
> find "Crash kernel", you are always going to get the kernel placed in the 
> lower portion.
> 
> I suspect this isn't what you want, can we rename crashk_low_res for arm64 so 
> that
> existing kexec-tools doesn't use it?
>

In my patchset, in addition to the kernel patches, i also modify the 
kexec-tools.
  arm64: support more than one crash kernel 
regions(http://lists.infradead.org/pipermail/kexec/2019-April/022792.html).
In kexec-tools patch, we read all the "Crash kernel" entry and load crash 
kernel high.

> 
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index d2adffb..3fcd739 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -74,20 +74,37 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>>  static void __init reserve_crashkernel(void)
>>  {
>>  unsigned long long crash_base, crash_size;
>> +bool high = false;
>>  int ret;
>>  
>>  ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
>>  _size, _base);
>>  /* no crashkernel= or invalid value specified */
>> -if (ret || !crash_size)
>> -return;
>> +if (ret || !crash_size) {
>> +/* crashkernel=X,high */
>> +ret = parse_crashkernel_high(boot_command_line,
>> +memblock_phys_mem_size(),
>> +_size, _base);
>> +if (ret || !crash_size)
>> +return;
>> +high = true;
>> +}
>>  
>>  crash_size = PAGE_ALIGN(crash_size);
>>  
>>  if (crash_base == 0) {
>> -/* Current arm64 boot protocol requires 2MB alignment */
>> -crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
>> -crash_size, SZ_2M);
>> +/*
>> + * Try low memory first and fall back to high memory
>> + * unless "crashkernel=size[KMG],high" is specified.
>> + */
>> +if (!high)
>> +crash_base = memblock_find_in_range(0,
>> +ARCH_LOW_ADDRESS_LIMIT,
>> +crash_size, CRASH_ALIGN);
>> +if (!crash_base)
>> +crash_base = memblock_find_in_range(0,
>> +memblock_end_of_DRAM(),
>> +crash_size, CRASH_ALIGN);
>>  if (crash_base == 0) {
>>  pr_warn("cannot allocate crashkernel (size

Re: [PATCH 1/4] x86: kdump: move reserve_crashkernel_low() into kexec_core.c

2019-06-13 Thread Chen Zhou
Hi James,

Thanks for your review.

On 2019/6/6 0:29, James Morse wrote:
> Hello,
> 
> On 07/05/2019 04:50, Chen Zhou wrote:
>> In preparation for supporting reserving crashkernel above 4G
>> in arm64 as x86_64 does, move reserve_crashkernel_low() into
>> kexec/kexec_core.c.
> 
> 
>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index 905dae8..9ee33b6 100644
>> --- a/arch/x86/kernel/setup.c
>> +++ b/arch/x86/kernel/setup.c
>> @@ -463,59 +460,6 @@ static void __init 
>> memblock_x86_reserve_range_setup_data(void)
>>  # define CRASH_ADDR_HIGH_MAXMAXMEM
>>  #endif
>>  
>> -static int __init reserve_crashkernel_low(void)
>> -{
>> -#ifdef CONFIG_X86_64
> 
> The behaviour of this #ifdef has disappeared, won't 32bit x86 now try and 
> reserve a chunk
> of unnecessary 'low' memory?
> 
> [...]

At present, reserve_crashkernel_low() is called only when reserving crashkernel 
above 4G, so i deleted
this #ifdef.
If we called reserve_crashkernel_low() at the beginning of 
reserve_crashkernel(), i need to add it back.

> 
> 
>> @@ -579,9 +523,13 @@ static void __init reserve_crashkernel(void)
>>  return;
>>  }
>>  
>> -if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
>> -memblock_free(crash_base, crash_size);
>> -return;
>> +if (crash_base >= (1ULL << 32)) {
>> +if (reserve_crashkernel_low()) {
>> +memblock_free(crash_base, crash_size);
>> +return;
>> +}
>> +
>> +insert_resource(_resource, _low_res);
> 
> 
> Previously reserve_crashkernel_low() was #ifdefed to do nothing if 
> !CONFIG_X86_64, I don't
> see how 32bit is skipping this reservation...
> 
> 
>>  }
>>  
>>  pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
>> RAM: %ldMB)\n",
>> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
>> index b9b1bc5..096ad63 100644
>> --- a/include/linux/kexec.h
>> +++ b/include/linux/kexec.h
>> @@ -63,6 +63,10 @@
>>  
>>  #define KEXEC_CORE_NOTE_NAMECRASH_CORE_NOTE_NAME
>>  
>> +#ifndef CRASH_ALIGN
>> +#define CRASH_ALIGN SZ_128M
>> +#endif
> 
> Why 128M? Wouldn't we rather each architecture tells us its minimum alignment?

Yeah, each architecture should tells us its minimum alignment. I added this 
default size to
fix compiling error on some architecture which didn't define it. I will add 
x86_64 and arm64
restriction on reserve_crashkernel_low() and delete this define.

> 
> 
>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>> index d714044..3492abd 100644
>> --- a/kernel/kexec_core.c
>> +++ b/kernel/kexec_core.c
>> @@ -39,6 +39,8 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>> +#include 
>>  
>>  #include 
>>  #include 
>> @@ -96,6 +98,60 @@ int kexec_crash_loaded(void)
>>  }
>>  EXPORT_SYMBOL_GPL(kexec_crash_loaded);
>>  
>> +int __init reserve_crashkernel_low(void)
>> +{
>> +unsigned long long base, low_base = 0, low_size = 0;
>> +unsigned long total_low_mem;
>> +int ret;
>> +
>> +total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
>> +
>> +/* crashkernel=Y,low */
>> +ret = parse_crashkernel_low(boot_command_line, total_low_mem,
>> +_size, );
>> +if (ret) {
>> +/*
>> + * two parts from lib/swiotlb.c:
>> + * -swiotlb size: user-specified with swiotlb= or default.
>> + *
>> + * -swiotlb overflow buffer: now hardcoded to 32k. We round it
>> + * to 8M for other buffers that may need to stay low too. Also
>> + * make sure we allocate enough extra low memory so that we
>> + * don't run out of DMA buffers for 32-bit devices.
>> + */
>> +low_size = max(swiotlb_size_or_default() + (8UL << 20),
> 
> SZ_8M?
> 
>> +256UL << 20);
> 
> SZ_256M?
> 

There is compiling warning "warning: comparison of distinct pointer types lacks 
a cast" if just use
SZ_8M or SZ_256M. We need cast swiotlb_size_or_default() to type int,so i kept 
the old as in x86_64.

> 
>> +} else {
>> +/* passed with crashkernel=0,low ? */
>> +if (!low_size)
>> +return 0;
>> +}
>> +
>> +low_base =

Re: [PATCH 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-06-02 Thread Chen Zhou
Hi Catalin,

Sorry to ping you.
What's your suggestion about this patch series? I am looking forward to your 
replay.

Thanks,
Chen Zhou


On 2019/5/16 11:19, Chen Zhou wrote:
> Hi Bhupesh,
> 
> On 2019/5/15 13:06, Bhupesh Sharma wrote:
>> +Cc kexec-list.
>>
>> Hi Chen,
>>
>> I think we are still in the quiet period of the merge cycle, but this is a 
>> change which will be useful for systems like HPE Apollo where we are looking 
>> at reserving crashkernel across a larger range.
>>
>> Some comments inline and in respective patch threads..
>>
>> On 05/07/2019 09:20 AM, Chen Zhou wrote:
>>> This patch series enable reserving crashkernel on high memory in arm64.
>>
>> Please fix the patch subject, it should be v5.
>> Also please Cc the kexec-list (kexec@lists.infradead.org) for future 
>> versions to allow wider review of the patchset.
>>
>>> We use crashkernel=X to reserve crashkernel below 4G, which will fail
>>> when there is no enough memory. Currently, crashkernel=Y@X can be used
>>> to reserve crashkernel above 4G, in this case, if swiotlb or DMA buffers
>>> are requierd, capture kernel will boot failure because of no low memory.
>>
>> ... ^^ required
>>
>> s/capture kernel will boot failure because of no low memory./capture kernel 
>> boot will fail because there is no low memory available for allocation.
>>
>>> When crashkernel is reserved above 4G in memory, kernel should reserve
>>> some amount of low memory for swiotlb and some DMA buffers. So there may
>>> be two crash kernel regions, one is below 4G, the other is above 4G. Then
>>> Crash dump kernel reads more than one crash kernel regions via a dtb
>>> property under node /chosen,
>>> linux,usable-memory-range = .
>>
>> Please use consistent naming for the second kernel, better to use crash dump 
>> kernel.
>>
>> I have tested this on my HPE Apollo machine and with crashkernel=886M,high 
>> syntax, I can get the board to reserve a larger memory range for the 
>> crashkernel (i.e. 886M):
>>
>> # dmesg | grep -i crash
>> [0.00] kexec_core: Reserving 256MB of low memory at 3560MB for 
>> crashkernel (System low RAM: 2029MB)
>> [0.00] crashkernel reserved: 0x000bc5a0 - 0x000bfd00 
>> (886 MB)
>>
>> kexec/kdump can also work also work fine on the board.
>>
>> So, with the changes suggested in this cover letter and individual patches, 
>> please feel free to add:
>>
>> Reviewed-and-Tested-by: Bhupesh Sharma 
>>
>> Thanks,
>> Bhupesh
>>
> 
> Thanks for you review and test. I will fix these later.
> 
> Thanks,
> Chen Zhou
> 
>>> Besides, we need to modify kexec-tools:
>>>arm64: support more than one crash kernel regions(see [1])
>>>
>>> I post this patch series about one month ago. The previous changes and
>>> discussions can be retrived from:
>>>
>>> Changes since [v4]
>>> - reimplement memblock_cap_memory_ranges for multiple ranges by Mike.
>>>
>>> Changes since [v3]
>>> - Add memblock_cap_memory_ranges back for multiple ranges.
>>> - Fix some compiling warnings.
>>>
>>> Changes since [v2]
>>> - Split patch "arm64: kdump: support reserving crashkernel above 4G" as
>>>two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
>>>patch.
>>>
>>> Changes since [v1]:
>>> - Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
>>> - Remove memblock_cap_memory_ranges() i added in v1 and implement that
>>>in fdt_enforce_memory_region().
>>>There are at most two crash kernel regions, for two crash kernel regions
>>>case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
>>>and then remove the memory range in the middle.
>>>
>>> [1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
>>> [v1]: https://lkml.org/lkml/2019/4/2/1174
>>> [v2]: https://lkml.org/lkml/2019/4/9/86
>>> [v3]: https://lkml.org/lkml/2019/4/9/306
>>> [v4]: https://lkml.org/lkml/2019/4/15/273
>>>
>>> Chen Zhou (3):
>>>x86: kdump: move reserve_crashkernel_low() into kexec_core.c
>>>arm64: kdump: support reserving crashkernel above 4G
>>>kdump: update Documentation about crashkernel on arm64
>>>
>>> Mike Rapoport (1):
>>>memblock: extend memblock_cap_memory_range to multiple ranges
>>>
>>>   Documentation/admin-guide/kernel-parameters.txt |  6 +--
>>>   arch/arm64/include/asm/kexec.h  |  3 ++
>>>   arch/arm64/kernel/setup.c   |  3 ++
>>>   arch/arm64/mm/init.c| 72 
>>> +++--
>>>   arch/x86/include/asm/kexec.h|  3 ++
>>>   arch/x86/kernel/setup.c | 66 
>>> +++
>>>   include/linux/kexec.h   |  5 ++
>>>   include/linux/memblock.h|  2 +-
>>>   kernel/kexec_core.c | 56 +++
>>>   mm/memblock.c   | 44 +++
>>>   10 files changed, 157 insertions(+), 103 deletions(-)
>>>
>>
>>
>> .
>>
> 
> 
> .
> 



Re: [PATCH] arm64: support more than one crash kernel regions

2019-06-02 Thread Chen Zhou
Hi Simon,

On 2019/5/31 17:28, Simon Horman wrote:
> On Wed, Apr 03, 2019 at 10:55:04AM +0800, Chen Zhou wrote:
>> When crashkernel is reserved above 4G in memory, kernel should
>> reserve some amount of low memory for swiotlb and some DMA buffers.
>> So there may be two crash kernel regions, one is below 4G, the other
>> is above 4G.
>>
>> Currently, there is only one crash kernel region on arm64, and pass
>> "linux,usable-memory-range = " property to crash dump
>> kernel. Now, we pass
>> "linux,usable-memory-range = " to crash
>> dump kernel to support two crash kernel regions and load crash
>> kernel high.
>>
>> Signed-off-by: Chen Zhou 
> 
> Sorry for letting this slip through the cracks.
> Please let me know if this is still relevant.
> 

This is still relevant and the kernel patches are still under discussion.

Thanks,
Chen Zhou


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH 4/4] kdump: update Documentation about crashkernel on arm64

2019-05-15 Thread Chen Zhou
On 2019/5/15 13:16, Bhupesh Sharma wrote:
> On 05/07/2019 09:20 AM, Chen Zhou wrote:
>> Now we support crashkernel=X,[high,low] on arm64, update the
>> Documentation.
>>
>> Signed-off-by: Chen Zhou 
>> ---
>>   Documentation/admin-guide/kernel-parameters.txt | 6 +++---
>>   1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt 
>> b/Documentation/admin-guide/kernel-parameters.txt
>> index 268b10a..03a08aa 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -705,7 +705,7 @@
>>   memory region [offset, offset + size] for that kernel
>>   image. If '@offset' is omitted, then a suitable offset
>>   is selected automatically.
>> -[KNL, x86_64] select a region under 4G first, and
>> +[KNL, x86_64, arm64] 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.
>> @@ -718,14 +718,14 @@
>>   Documentation/kdump/kdump.txt for an example.
>> crashkernel=size[KMG],high
>> -[KNL, x86_64] range could be above 4G. Allow kernel
>> +[KNL, x86_64, arm64] range could be above 4G. Allow kernel
>>   to allocate physical memory region from top, so could
>>   be above 4G if system have more than 4G ram installed.
>>   Otherwise memory region will be allocated below 4G, if
>>   available.
>>   It will be ignored if crashkernel=X is specified.
>>   crashkernel=size[KMG],low
>> -[KNL, x86_64] range under 4G. When crashkernel=X,high
>> +[KNL, x86_64, arm64] range under 4G. When crashkernel=X,high
>>   is passed, kernel could allocate physical memory region
>>   above 4G, that cause second kernel crash on system
>>   that require some amount of low memory, e.g. swiotlb
>>
> 
> IMO, it is a good time to update 'Documentation/kdump/kdump.txt' with this 
> patchset itself for both x86_64 and arm64, where we still specify only the 
> old format for 'crashkernel' boot-argument:
> 
> Section: Boot into System Kernel
>  ===
> 
> On arm64, use "crashkernel=Y[@X]".  Note that the start address of
> the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
> ...
> 
> We can update this to add the new crashkernel=size[KMG],low or 
> crashkernel=size[KMG],high format as well.
> 
> Thanks,
> Bhupesh
> 
> .

Sure, we can also update here.

Thanks,
Chen Zhou





Re: [PATCH 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-05-15 Thread Chen Zhou
Hi Bhupesh,

On 2019/5/15 13:06, Bhupesh Sharma wrote:
> +Cc kexec-list.
> 
> Hi Chen,
> 
> I think we are still in the quiet period of the merge cycle, but this is a 
> change which will be useful for systems like HPE Apollo where we are looking 
> at reserving crashkernel across a larger range.
> 
> Some comments inline and in respective patch threads..
> 
> On 05/07/2019 09:20 AM, Chen Zhou wrote:
>> This patch series enable reserving crashkernel on high memory in arm64.
> 
> Please fix the patch subject, it should be v5.
> Also please Cc the kexec-list (kexec@lists.infradead.org) for future versions 
> to allow wider review of the patchset.
> 
>> We use crashkernel=X to reserve crashkernel below 4G, which will fail
>> when there is no enough memory. Currently, crashkernel=Y@X can be used
>> to reserve crashkernel above 4G, in this case, if swiotlb or DMA buffers
>> are requierd, capture kernel will boot failure because of no low memory.
> 
> ... ^^ required
> 
> s/capture kernel will boot failure because of no low memory./capture kernel 
> boot will fail because there is no low memory available for allocation.
> 
>> When crashkernel is reserved above 4G in memory, kernel should reserve
>> some amount of low memory for swiotlb and some DMA buffers. So there may
>> be two crash kernel regions, one is below 4G, the other is above 4G. Then
>> Crash dump kernel reads more than one crash kernel regions via a dtb
>> property under node /chosen,
>> linux,usable-memory-range = .
> 
> Please use consistent naming for the second kernel, better to use crash dump 
> kernel.
> 
> I have tested this on my HPE Apollo machine and with crashkernel=886M,high 
> syntax, I can get the board to reserve a larger memory range for the 
> crashkernel (i.e. 886M):
> 
> # dmesg | grep -i crash
> [0.00] kexec_core: Reserving 256MB of low memory at 3560MB for 
> crashkernel (System low RAM: 2029MB)
> [0.00] crashkernel reserved: 0x000bc5a0 - 0x000bfd00 
> (886 MB)
> 
> kexec/kdump can also work also work fine on the board.
> 
> So, with the changes suggested in this cover letter and individual patches, 
> please feel free to add:
> 
> Reviewed-and-Tested-by: Bhupesh Sharma 
> 
> Thanks,
> Bhupesh
> 

Thanks for you review and test. I will fix these later.

Thanks,
Chen Zhou

>> Besides, we need to modify kexec-tools:
>>arm64: support more than one crash kernel regions(see [1])
>>
>> I post this patch series about one month ago. The previous changes and
>> discussions can be retrived from:
>>
>> Changes since [v4]
>> - reimplement memblock_cap_memory_ranges for multiple ranges by Mike.
>>
>> Changes since [v3]
>> - Add memblock_cap_memory_ranges back for multiple ranges.
>> - Fix some compiling warnings.
>>
>> Changes since [v2]
>> - Split patch "arm64: kdump: support reserving crashkernel above 4G" as
>>two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
>>patch.
>>
>> Changes since [v1]:
>> - Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
>> - Remove memblock_cap_memory_ranges() i added in v1 and implement that
>>in fdt_enforce_memory_region().
>>There are at most two crash kernel regions, for two crash kernel regions
>>case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
>>and then remove the memory range in the middle.
>>
>> [1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
>> [v1]: https://lkml.org/lkml/2019/4/2/1174
>> [v2]: https://lkml.org/lkml/2019/4/9/86
>> [v3]: https://lkml.org/lkml/2019/4/9/306
>> [v4]: https://lkml.org/lkml/2019/4/15/273
>>
>> Chen Zhou (3):
>>x86: kdump: move reserve_crashkernel_low() into kexec_core.c
>>arm64: kdump: support reserving crashkernel above 4G
>>kdump: update Documentation about crashkernel on arm64
>>
>> Mike Rapoport (1):
>>memblock: extend memblock_cap_memory_range to multiple ranges
>>
>>   Documentation/admin-guide/kernel-parameters.txt |  6 +--
>>   arch/arm64/include/asm/kexec.h  |  3 ++
>>   arch/arm64/kernel/setup.c   |  3 ++
>>   arch/arm64/mm/init.c| 72 
>> +++--
>>   arch/x86/include/asm/kexec.h|  3 ++
>>   arch/x86/kernel/setup.c | 66 
>> +++
>>   include/linux/kexec.h   |  5 ++
>>   include/linux/memblock.h|  2 +-
>>   kernel/kexec_core.c | 56 +++
>>   mm/memblock.c   | 44 +++
>>   10 files changed, 157 insertions(+), 103 deletions(-)
>>
> 
> 
> .
> 


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH 2/4] arm64: kdump: support reserving crashkernel above 4G

2019-05-06 Thread Chen Zhou
When crashkernel is reserved above 4G in memory, kernel should
reserve some amount of low memory for swiotlb and some DMA buffers.

Meanwhile, support crashkernel=X,[high,low] in arm64. When use
crashkernel=X parameter, try low memory first and fall back to high
memory unless "crashkernel=X,high" is specified.

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h |  3 +++
 arch/arm64/kernel/setup.c  |  3 +++
 arch/arm64/mm/init.c   | 34 --
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 67e4cb7..32949bf 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -28,6 +28,9 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 413d566..82cd9a0 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -243,6 +243,9 @@ static void __init request_standard_resources(void)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
/* Userspace will find "Crash kernel" region in /proc/iomem. */
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d2adffb..3fcd739 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,20 +74,37 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
+   bool high = false;
int ret;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
/* no crashkernel= or invalid value specified */
-   if (ret || !crash_size)
-   return;
+   if (ret || !crash_size) {
+   /* crashkernel=X,high */
+   ret = parse_crashkernel_high(boot_command_line,
+   memblock_phys_mem_size(),
+   _size, _base);
+   if (ret || !crash_size)
+   return;
+   high = true;
+   }
 
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
-   /* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
-   crash_size, SZ_2M);
+   /*
+* Try low memory first and fall back to high memory
+* unless "crashkernel=size[KMG],high" is specified.
+*/
+   if (!high)
+   crash_base = memblock_find_in_range(0,
+   ARCH_LOW_ADDRESS_LIMIT,
+   crash_size, CRASH_ALIGN);
+   if (!crash_base)
+   crash_base = memblock_find_in_range(0,
+   memblock_end_of_DRAM(),
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -105,13 +122,18 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
}
memblock_reserve(crash_base, crash_size);
 
+   if (crash_base >= SZ_4G && reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+
pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
crash_base, crash_base + crash_size, crash_size >> 20);
 
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH 3/4] memblock: extend memblock_cap_memory_range to multiple ranges

2019-05-06 Thread Chen Zhou
From: Mike Rapoport 

The memblock_cap_memory_range() removes all the memory except the
range passed to it. Extend this function to receive an array of
memblock_regions that should be kept. This allows switching to
simple iteration over memblock arrays with 'for_each_mem_range_rev'
to remove the unneeded memory.

Enable use of this function in arm64 for reservation of multiple
regions for the crash kernel.

Signed-off-by: Mike Rapoport 
Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 38 --
 include/linux/memblock.h |  2 +-
 mm/memblock.c| 44 
 3 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 3fcd739..2d8f302 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -63,6 +63,13 @@ EXPORT_SYMBOL(memstart_addr);
 
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
+/* The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now crash dump
+ * kernel support at most two crash kernel regions, low_region and high
+ * region.
+ */
+#define MAX_USABLE_RANGES  2
+
 #ifdef CONFIG_KEXEC_CORE
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
@@ -302,9 +309,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_type *usablemem = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -313,22 +320,33 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   unsigned long base = dt_mem_next_cell(dt_root_addr_cells, );
+   unsigned long size = dt_mem_next_cell(dt_root_size_cells, );
+
+   if (memblock_add_range(usablemem, base, size, NUMA_NO_NODE,
+  MEMBLOCK_NONE))
+   return 0;
+   if (++nr >= MAX_USABLE_RANGES)
+   break;
+   }
 
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_regions[MAX_USABLE_RANGES];
+   struct memblock_type usablemem = {
+   .max = MAX_USABLE_RANGES,
+   .regions = usable_regions,
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, );
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   if (usablemem.cnt)
+   memblock_cap_memory_ranges(usablemem.regions, usablemem.cnt);
 }
 
 void __init arm64_memblock_init(void)
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 676d390..526e279 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -446,7 +446,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
 phys_addr_t memblock_start_of_DRAM(void);
 phys_addr_t memblock_end_of_DRAM(void);
 void memblock_enforce_memory_limit(phys_addr_t memory_limit);
-void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
+void memblock_cap_memory_ranges(struct memblock_region *regions, int count);
 void memblock_mem_limit_remove_map(phys_addr_t limit);
 bool memblock_is_memory(phys_addr_t addr);
 bool memblock_is_map_memory(phys_addr_t addr);
diff --git a/mm/memblock.c b/mm/memblock.c
index 6bbad46..ecdf8a9 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1669,36 +1669,31 @@ void __init memblock_enforce_memory_limit(phys_addr_t 
limit)
  PHYS_ADDR_MAX);
 }
 
-void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
-{
-   int start_rgn, end_rgn;
-   int i, ret;
-
-   if (!size)
-   return;
-
-   ret = memblock_isolate_range(, base, size,
-   _rgn, _rgn);
-   if (ret)
-   return;
-
-   /* remove all the MAP regions */
-   for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
-   if (!memblock_is_nomap([i]))
-   memblock_remove_region(, i);
+void __init memblock_cap_memory_ranges(struct memblock_region *regions,
+  int count)
+{
+   struct memblock_type regions_to

[PATCH 1/4] x86: kdump: move reserve_crashkernel_low() into kexec_core.c

2019-05-06 Thread Chen Zhou
In preparation for supporting reserving crashkernel above 4G
in arm64 as x86_64 does, move reserve_crashkernel_low() into
kexec/kexec_core.c.

Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/kexec.h |  3 ++
 arch/x86/kernel/setup.c  | 66 +---
 include/linux/kexec.h|  5 
 kernel/kexec_core.c  | 56 +
 4 files changed, 71 insertions(+), 59 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 003f2da..c51f293 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,9 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_16M
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 905dae8..9ee33b6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -448,9 +448,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 
 #ifdef CONFIG_KEXEC_CORE
 
-/* 16M alignment for crash kernel regions */
-#define CRASH_ALIGNSZ_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.
@@ -463,59 +460,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   MAXMEM
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from lib/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -579,9 +523,13 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index b9b1bc5..096ad63 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -63,6 +63,10 @@
 
 #define KEXEC_CORE_NOTE_NAME   CRASH_CORE_NOTE_NAME
 
+#ifndef CRASH_ALIGN
+#define CRASH_ALIGN SZ_128M
+#endif
+
 /*
  * This structure is used to hold the arguments that are used when loading
  * kernel binaries.
@@ -281,6 +285,7 @@ extern void __crash_kexec(struct pt_regs *);
 extern void crash_kexec(struct pt_regs *);
 int kexec_should_crash(struct task_struct *);
 int kexec_crash_loaded(void);
+int __init reserve_crashkernel_low(void);
 void crash_save_cpu(struct pt_regs *re

[PATCH 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-05-06 Thread Chen Zhou
This patch series enable reserving crashkernel on high memory in arm64.

We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough memory. Currently, crashkernel=Y@X can be used
to reserve crashkernel above 4G, in this case, if swiotlb or DMA buffers
are requierd, capture kernel will boot failure because of no low memory.

When crashkernel is reserved above 4G in memory, kernel should reserve
some amount of low memory for swiotlb and some DMA buffers. So there may
be two crash kernel regions, one is below 4G, the other is above 4G. Then
Crash dump kernel reads more than one crash kernel regions via a dtb
property under node /chosen,
linux,usable-memory-range = .

Besides, we need to modify kexec-tools:
  arm64: support more than one crash kernel regions(see [1])

I post this patch series about one month ago. The previous changes and
discussions can be retrived from:

Changes since [v4]
- reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
  two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
  patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
  in fdt_enforce_memory_region().
  There are at most two crash kernel regions, for two crash kernel regions
  case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
  and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273

Chen Zhou (3):
  x86: kdump: move reserve_crashkernel_low() into kexec_core.c
  arm64: kdump: support reserving crashkernel above 4G
  kdump: update Documentation about crashkernel on arm64

Mike Rapoport (1):
  memblock: extend memblock_cap_memory_range to multiple ranges

 Documentation/admin-guide/kernel-parameters.txt |  6 +--
 arch/arm64/include/asm/kexec.h  |  3 ++
 arch/arm64/kernel/setup.c   |  3 ++
 arch/arm64/mm/init.c| 72 +++--
 arch/x86/include/asm/kexec.h|  3 ++
 arch/x86/kernel/setup.c | 66 +++
 include/linux/kexec.h   |  5 ++
 include/linux/memblock.h|  2 +-
 kernel/kexec_core.c | 56 +++
 mm/memblock.c   | 44 +++
 10 files changed, 157 insertions(+), 103 deletions(-)

-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH 4/4] kdump: update Documentation about crashkernel on arm64

2019-05-06 Thread Chen Zhou
Now we support crashkernel=X,[high,low] on arm64, update the
Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kernel-parameters.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 268b10a..03a08aa 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -705,7 +705,7 @@
memory region [offset, offset + size] for that kernel
image. If '@offset' is omitted, then a suitable offset
is selected automatically.
-   [KNL, x86_64] select a region under 4G first, and
+   [KNL, x86_64, arm64] 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.
@@ -718,14 +718,14 @@
Documentation/kdump/kdump.txt for an example.
 
crashkernel=size[KMG],high
-   [KNL, x86_64] range could be above 4G. Allow kernel
+   [KNL, x86_64, arm64] range could be above 4G. Allow 
kernel
to allocate physical memory region from top, so could
be above 4G if system have more than 4G ram installed.
Otherwise memory region will be allocated below 4G, if
available.
It will be ignored if crashkernel=X is specified.
crashkernel=size[KMG],low
-   [KNL, x86_64] range under 4G. When crashkernel=X,high
+   [KNL, x86_64, arm64] range under 4G. When 
crashkernel=X,high
is passed, kernel could allocate physical memory region
above 4G, that cause second kernel crash on system
that require some amount of low memory, e.g. swiotlb
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[RESEND PATCH v5 4/4] kdump: update Documentation about crashkernel on arm64

2019-04-16 Thread Chen Zhou
Now we support crashkernel=X,[high,low] on arm64, update the
Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kernel-parameters.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 308af3b..a055983 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -715,14 +715,14 @@
Documentation/kdump/kdump.txt for an example.
 
crashkernel=size[KMG],high
-   [KNL, x86_64] range could be above 4G. Allow kernel
+   [KNL, x86_64, arm64] range could be above 4G. Allow 
kernel
to allocate physical memory region from top, so could
be above 4G if system have more than 4G ram installed.
Otherwise memory region will be allocated below 4G, if
available.
It will be ignored if crashkernel=X is specified.
crashkernel=size[KMG],low
-   [KNL, x86_64] range under 4G. When crashkernel=X,high
+   [KNL, x86_64, arm64] range under 4G. When 
crashkernel=X,high
is passed, kernel could allocate physical memory region
above 4G, that cause second kernel crash on system
that require some amount of low memory, e.g. swiotlb
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[RESEND PATCH v5 2/4] arm64: kdump: support reserving crashkernel above 4G

2019-04-16 Thread Chen Zhou
When crashkernel is reserved above 4G in memory, kernel should
reserve some amount of low memory for swiotlb and some DMA buffers.

Kernel would try to allocate at least 256M below 4G automatically
as x86_64 if crashkernel is above 4G. Meanwhile, support
crashkernel=X,[high,low] in arm64.

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h |  3 +++
 arch/arm64/kernel/setup.c  |  3 +++
 arch/arm64/mm/init.c   | 25 -
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 67e4cb7..32949bf 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -28,6 +28,9 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 413d566..82cd9a0 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -243,6 +243,9 @@ static void __init request_standard_resources(void)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
/* Userspace will find "Crash kernel" region in /proc/iomem. */
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 972bf43..f5dde73 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,20 +74,30 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
+   bool high = false;
int ret;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
/* no crashkernel= or invalid value specified */
-   if (ret || !crash_size)
-   return;
+   if (ret || !crash_size) {
+   /* crashkernel=X,high */
+   ret = parse_crashkernel_high(boot_command_line,
+   memblock_phys_mem_size(),
+   _size, _base);
+   if (ret || !crash_size)
+   return;
+   high = true;
+   }
 
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0,
+   high ? memblock_end_of_DRAM()
+   : ARCH_LOW_ADDRESS_LIMIT,
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -105,13 +115,18 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
}
memblock_reserve(crash_base, crash_size);
 
+   if (crash_base >= SZ_4G && reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+
pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
crash_base, crash_base + crash_size, crash_size >> 20);
 
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[RESEND PATCH v5 3/4] memblock: extend memblock_cap_memory_range to multiple ranges

2019-04-16 Thread Chen Zhou
From: Mike Rapoport 

The memblock_cap_memory_range() removes all the memory except the
range passed to it. Extend this function to receive an array of
memblock_regions that should be kept. This allows switching to
simple iteration over memblock arrays with 'for_each_mem_range_rev'
to remove the unneeded memory.

Enable use of this function in arm64 for reservation of multiple
regions for the crash kernel.

Signed-off-by: Mike Rapoport 
Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 34 --
 include/linux/memblock.h |  2 +-
 mm/memblock.c| 44 
 3 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f5dde73..7f999bf 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -64,6 +64,10 @@ EXPORT_SYMBOL(memstart_addr);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
+
+/* at most two crash kernel regions, low_region and high_region */
+#define CRASH_MAX_USABLE_RANGES2
+
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -295,9 +299,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_type *usablemem = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -306,22 +310,32 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   unsigned long base = dt_mem_next_cell(dt_root_addr_cells, );
+   unsigned long size = dt_mem_next_cell(dt_root_size_cells, );
 
+   if (memblock_add_range(usablemem, base, size, NUMA_NO_NODE,
+  MEMBLOCK_NONE))
+   return 0;
+   if (++nr >= CRASH_MAX_USABLE_RANGES)
+   break;
+   }
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_regions[CRASH_MAX_USABLE_RANGES];
+   struct memblock_type usablemem = {
+   .max = CRASH_MAX_USABLE_RANGES,
+   .regions = usable_regions,
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, );
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   if (usablemem.cnt)
+   memblock_cap_memory_ranges(usablemem.regions, usablemem.cnt);
 }
 
 void __init arm64_memblock_init(void)
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 47e3c06..e490a73 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -445,7 +445,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
 phys_addr_t memblock_start_of_DRAM(void);
 phys_addr_t memblock_end_of_DRAM(void);
 void memblock_enforce_memory_limit(phys_addr_t memory_limit);
-void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
+void memblock_cap_memory_ranges(struct memblock_region *regions, int count);
 void memblock_mem_limit_remove_map(phys_addr_t limit);
 bool memblock_is_memory(phys_addr_t addr);
 bool memblock_is_map_memory(phys_addr_t addr);
diff --git a/mm/memblock.c b/mm/memblock.c
index f315eca..08581b1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1669,36 +1669,31 @@ void __init memblock_enforce_memory_limit(phys_addr_t 
limit)
  PHYS_ADDR_MAX);
 }
 
-void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
-{
-   int start_rgn, end_rgn;
-   int i, ret;
-
-   if (!size)
-   return;
-
-   ret = memblock_isolate_range(, base, size,
-   _rgn, _rgn);
-   if (ret)
-   return;
-
-   /* remove all the MAP regions */
-   for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
-   if (!memblock_is_nomap([i]))
-   memblock_remove_region(, i);
+void __init memblock_cap_memory_ranges(struct memblock_region *regions,
+  int count)
+{
+   struct memblock_type regions_to_keep = {
+   .max = count,
+   .cnt = count,
+   .regions = regions,
+   };
+   phys_addr_t start

[RESEND PATCH v5 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-04-16 Thread Chen Zhou
When crashkernel is reserved above 4G in memory, kernel should reserve
some amount of low memory for swiotlb and some DMA buffers. So there may
be two crash kernel regions, one is below 4G, the other is above 4G.

Crash dump kernel reads more than one crash kernel regions via a dtb
property under node /chosen,
linux,usable-memory-range = .

Besides, we need to modify kexec-tools:
  arm64: support more than one crash kernel regions(see [1])

Changes since [v4]
- reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges for multiple ranges.
- Split patch "arm64: kdump: support more than one crash kernel regions"
as two. One is above "Add memblock_cap_memory_ranges", the other is using
memblock_cap_memory_ranges to support multiple crash kernel regions.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
  two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
  patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
  in fdt_enforce_memory_region().
  There are at most two crash kernel regions, for two crash kernel regions
  case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
  and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2019-April/022792.html
[v1]: https://lkml.org/lkml/2019/4/8/628
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/15/6
[v4]: https://lkml.org/lkml/2019/4/15/273

Chen Zhou (3):
  x86: kdump: move reserve_crashkernel_low() into kexec_core.c
  arm64: kdump: support reserving crashkernel above 4G
  kdump: update Documentation about crashkernel on arm64

Mike Rapoport (1):
  memblock: extend memblock_cap_memory_range to multiple ranges

 Documentation/admin-guide/kernel-parameters.txt |  4 +-
 arch/arm64/include/asm/kexec.h  |  3 ++
 arch/arm64/kernel/setup.c   |  3 ++
 arch/arm64/mm/init.c| 59 --
 arch/x86/include/asm/kexec.h|  3 ++
 arch/x86/kernel/setup.c | 66 +++--
 include/linux/kexec.h   |  5 ++
 include/linux/memblock.h|  2 +-
 kernel/kexec_core.c | 56 +
 mm/memblock.c   | 44 -
 10 files changed, 144 insertions(+), 101 deletions(-)

-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[RESEND PATCH v5 1/4] x86: kdump: move reserve_crashkernel_low() into kexec_core.c

2019-04-16 Thread Chen Zhou
In preparation for supporting more than one crash kernel regions
in arm64 as x86_64 does, move reserve_crashkernel_low() into
kexec/kexec_core.c.

Signed-off-by: Chen Zhou 
---
 arch/x86/include/asm/kexec.h |  3 ++
 arch/x86/kernel/setup.c  | 66 +---
 include/linux/kexec.h|  5 
 kernel/kexec_core.c  | 56 +
 4 files changed, 71 insertions(+), 59 deletions(-)

diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 003f2da..485a514 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -18,6 +18,9 @@
 
 # define KEXEC_CONTROL_CODE_MAX_SIZE   2048
 
+/* 16M alignment for crash kernel regions */
+#define CRASH_ALIGN(16 << 20)
+
 #ifndef __ASSEMBLY__
 
 #include 
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 3773905..4182035 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,9 +447,6 @@ 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)
-
 /*
  * 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.
@@ -463,59 +460,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   MAXMEM
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from lib/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -573,9 +517,13 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index b9b1bc5..096ad63 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -63,6 +63,10 @@
 
 #define KEXEC_CORE_NOTE_NAME   CRASH_CORE_NOTE_NAME
 
+#ifndef CRASH_ALIGN
+#define CRASH_ALIGN SZ_128M
+#endif
+
 /*
  * This structure is used to hold the arguments that are used when loading
  * kernel binaries.
@@ -281,6 +285,7 @@ extern void __crash_kexec(struct pt_regs *);
 extern void crash_kexec(struct pt_regs *);
 int kexec_should_crash(struct task_struct *);
 int kexec_crash_loaded(void);
+int __init reserve_crashkernel_low(void);
 void crash_

[PATCH v5 3/4] memblock: extend memblock_cap_memory_range to multiple ranges

2019-04-16 Thread Chen Zhou
The memblock_cap_memory_range() removes all the memory except the
range passed to it. Extend this function to receive an array of
memblock_regions that should be kept. This allows switching to
simple iteration over memblock arrays with 'for_each_mem_range_rev'
to remove the unneeded memory.

Enable use of this function in arm64 for reservation of multiple
regions for the crash kernel.

Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 34 --
 include/linux/memblock.h |  2 +-
 mm/memblock.c| 44 
 3 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f5dde73..7f999bf 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -64,6 +64,10 @@ EXPORT_SYMBOL(memstart_addr);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
+
+/* at most two crash kernel regions, low_region and high_region */
+#define CRASH_MAX_USABLE_RANGES2
+
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -295,9 +299,9 @@ early_param("mem", early_mem);
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
-   struct memblock_region *usablemem = data;
-   const __be32 *reg;
-   int len;
+   struct memblock_type *usablemem = data;
+   const __be32 *reg, *endp;
+   int len, nr = 0;
 
if (depth != 1 || strcmp(uname, "chosen") != 0)
return 0;
@@ -306,22 +310,32 @@ static int __init early_init_dt_scan_usablemem(unsigned 
long node,
if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
return 1;
 
-   usablemem->base = dt_mem_next_cell(dt_root_addr_cells, );
-   usablemem->size = dt_mem_next_cell(dt_root_size_cells, );
+   endp = reg + (len / sizeof(__be32));
+   while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+   unsigned long base = dt_mem_next_cell(dt_root_addr_cells, );
+   unsigned long size = dt_mem_next_cell(dt_root_size_cells, );
 
+   if (memblock_add_range(usablemem, base, size, NUMA_NO_NODE,
+  MEMBLOCK_NONE))
+   return 0;
+   if (++nr >= CRASH_MAX_USABLE_RANGES)
+   break;
+   }
return 1;
 }
 
 static void __init fdt_enforce_memory_region(void)
 {
-   struct memblock_region reg = {
-   .size = 0,
+   struct memblock_region usable_regions[CRASH_MAX_USABLE_RANGES];
+   struct memblock_type usablemem = {
+   .max = CRASH_MAX_USABLE_RANGES,
+   .regions = usable_regions,
};
 
-   of_scan_flat_dt(early_init_dt_scan_usablemem, );
+   of_scan_flat_dt(early_init_dt_scan_usablemem, );
 
-   if (reg.size)
-   memblock_cap_memory_range(reg.base, reg.size);
+   if (usablemem.cnt)
+   memblock_cap_memory_ranges(usablemem.regions, usablemem.cnt);
 }
 
 void __init arm64_memblock_init(void)
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 47e3c06..e490a73 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -445,7 +445,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
 phys_addr_t memblock_start_of_DRAM(void);
 phys_addr_t memblock_end_of_DRAM(void);
 void memblock_enforce_memory_limit(phys_addr_t memory_limit);
-void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
+void memblock_cap_memory_ranges(struct memblock_region *regions, int count);
 void memblock_mem_limit_remove_map(phys_addr_t limit);
 bool memblock_is_memory(phys_addr_t addr);
 bool memblock_is_map_memory(phys_addr_t addr);
diff --git a/mm/memblock.c b/mm/memblock.c
index f315eca..08581b1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1669,36 +1669,31 @@ void __init memblock_enforce_memory_limit(phys_addr_t 
limit)
  PHYS_ADDR_MAX);
 }
 
-void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
-{
-   int start_rgn, end_rgn;
-   int i, ret;
-
-   if (!size)
-   return;
-
-   ret = memblock_isolate_range(, base, size,
-   _rgn, _rgn);
-   if (ret)
-   return;
-
-   /* remove all the MAP regions */
-   for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
-   if (!memblock_is_nomap([i]))
-   memblock_remove_region(, i);
+void __init memblock_cap_memory_ranges(struct memblock_region *regions,
+  int count)
+{
+   struct memblock_type regions_to_keep = {
+   .max = count,
+   .cnt = count,
+   .regions = regions,
+   };
+   phys_addr_t start, end;
+   u64 i;
 
-  

[PATCH v5 2/4] arm64: kdump: support reserving crashkernel above 4G

2019-04-16 Thread Chen Zhou
When crashkernel is reserved above 4G in memory, kernel should
reserve some amount of low memory for swiotlb and some DMA buffers.

Kernel would try to allocate at least 256M below 4G automatically
as x86_64 if crashkernel is above 4G. Meanwhile, support
crashkernel=X,[high,low] in arm64.

Signed-off-by: Chen Zhou 
---
 arch/arm64/include/asm/kexec.h |  3 +++
 arch/arm64/kernel/setup.c  |  3 +++
 arch/arm64/mm/init.c   | 25 -
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 67e4cb7..32949bf 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -28,6 +28,9 @@
 
 #define KEXEC_ARCH KEXEC_ARCH_AARCH64
 
+/* 2M alignment for crash kernel regions */
+#define CRASH_ALIGNSZ_2M
+
 #ifndef __ASSEMBLY__
 
 /**
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 413d566..82cd9a0 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -243,6 +243,9 @@ static void __init request_standard_resources(void)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
/* Userspace will find "Crash kernel" region in /proc/iomem. */
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 972bf43..f5dde73 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,20 +74,30 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
+   bool high = false;
int ret;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
/* no crashkernel= or invalid value specified */
-   if (ret || !crash_size)
-   return;
+   if (ret || !crash_size) {
+   /* crashkernel=X,high */
+   ret = parse_crashkernel_high(boot_command_line,
+   memblock_phys_mem_size(),
+   _size, _base);
+   if (ret || !crash_size)
+   return;
+   high = true;
+   }
 
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0,
+   high ? memblock_end_of_DRAM()
+   : ARCH_LOW_ADDRESS_LIMIT,
+   crash_size, CRASH_ALIGN);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
@@ -105,13 +115,18 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (!IS_ALIGNED(crash_base, SZ_2M)) {
+   if (!IS_ALIGNED(crash_base, CRASH_ALIGN)) {
pr_warn("cannot reserve crashkernel: base address is 
not 2MB aligned\n");
return;
}
}
memblock_reserve(crash_base, crash_size);
 
+   if (crash_base >= SZ_4G && reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+
pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
crash_base, crash_base + crash_size, crash_size >> 20);
 
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


  1   2   >