[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, &kernel_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, &crashk_low_res);
+   }
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, &crashk_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(),
-   &crash_size, &crash_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_ba

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

2020-10-05 Thread Catalin Marinas
On Mon, Sep 07, 2020 at 09:47:42PM +0800, Chen Zhou wrote:
> 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, &kernel_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, &crashk_low_res);
> + }

With the changes in this series (including the above), how do the
current kexec-tools behave? Do they pick just the high region and the
loaded kernel will subsequently fail to boot?

-- 
Catalin

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


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

2020-10-05 Thread chenzhou


On 2020/10/6 1:16, Catalin Marinas wrote:
> On Mon, Sep 07, 2020 at 09:47:42PM +0800, Chen Zhou wrote:
>> 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, &kernel_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, &crashk_low_res);
>> +}
> With the changes in this series (including the above), how do the
> current kexec-tools behave? Do they pick just the high region and the
> loaded kernel will subsequently fail to boot?
Yes,just pick the high region and will boot fail if low memory is needed.

Thanks,
Chen Zhou
>


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