2023-03-24 13:20:29

by Baoquan He

[permalink] [raw]
Subject: [PATCH 0/3] arm64: kdump : take off the protection on crashkernel memory region

Problem:
=======
On arm64, block and section mapping is supported to build page tables.
However, currently it enforces to take base page mapping for the whole
linear mapping if CONFIG_ZONE_DMA or CONFIG_ZONE_DMA32 is enabled and
crashkernel kernel parameter is set. This will cause longer time of the
linear mapping process during bootup and severe performance degradation
during running time.

Root cause:
==========
On arm64, crashkernel reservation relies on knowing the upper limit of
low memory zone because it needs to reserve memory in the zone so that
devices' DMA addressing in kdump kernel can be satisfied. However, the
upper limit of low memory on arm64 is variant. And the upper limit can
only be decided late till bootmem_init() is called [1].

And we need to map the crashkernel region with base page granularity when
doing linear mapping, because kdump needs to protect the crashkernel region
via set_memory_valid(,0) after kdump kernel loading. However, arm64 doesn't
support well on splitting the built block or section mapping due to some
cpu reststriction [2]. And unfortunately, the linear mapping is done before
bootmem_init().

To resolve the above conflict on arm64, the compromise is enforcing to
take base page mapping for the entire linear mapping if crashkernel is
set, and CONFIG_ZONE_DMA or CONFIG_ZONE_DMA32 is enabed. Hence
performance is sacrificed.

Solution:
=========
Comparing with the always encountered base page mapping for the whole
linear region, it's better to take off the protection on crashkernel memory
region for now because the protection can only happen in a chance in one
million, while the base page mapping for the whole linear mapping is
always mitigating arm64 systems with crashkernel set.

This can let distros have chance to back port this patchset to fix the
performance issue caused by the base page mapping in the whole linear
region.

Extra words
===========
I personally expect that we can add these back in the near future
when arm64_dma_phys_limit is fixed, e.g Raspberry Pi enlarges the device
addressing limit to 32bit; or Arm64 can support splitting built block or
section mapping. Like this, the code is the simplest and clearest.

Or as Catalin suggested, for below 4 cases we currently defer to handle
in bootme_init(), we can try to handle case 3) in advance so that memory
above 4G can avoid base page mapping wholly. This will complicate the
already complex code, let's see how it looks if people interested post patch.

crashkernel=size
1)first attempt: low memory under arm64_dma_phys_limit
2)fallback: finding memory above 4G

crashkernel=size,high
3)first attempt: finding memory above 4G
4)fallback: low memory under arm64_dma_phys_limit


[1]
https://lore.kernel.org/all/[email protected]/T/#u

[2]
https://lore.kernel.org/linux-arm-kernel/[email protected]/T/

Baoquan He (3):
arm64: kdump : take off the protection on crashkernel memory region
arm64: kdump: do not map crashkernel region specifically
arm64: kdump: defer the crashkernel reservation for platforms with no
DMA memory zones

arch/arm64/include/asm/kexec.h | 6 -----
arch/arm64/include/asm/memory.h | 5 ----
arch/arm64/kernel/machine_kexec.c | 20 --------------
arch/arm64/mm/init.c | 6 +----
arch/arm64/mm/mmu.c | 43 -------------------------------
5 files changed, 1 insertion(+), 79 deletions(-)

--
2.34.1


2023-03-24 13:21:00

by Baoquan He

[permalink] [raw]
Subject: [PATCH 2/3] arm64: kdump: do not map crashkernel region specifically

After taking off the protection functions on crashkernel memory region,
there's no need to map crashkernel region with page granularity during
linear mapping.

With this change, the system can make use of block or section mapping
on linear region to largely improve perforcemence during system bootup
and running.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm64/mm/mmu.c | 43 -------------------------------------------
1 file changed, 43 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 6f9d8898a025..7556020a27b7 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -510,21 +510,6 @@ void __init mark_linear_text_alias_ro(void)
PAGE_KERNEL_RO);
}

-static bool crash_mem_map __initdata;
-
-static int __init enable_crash_mem_map(char *arg)
-{
- /*
- * Proper parameter parsing is done by reserve_crashkernel(). We only
- * need to know if the linear map has to avoid block mappings so that
- * the crashkernel reservations can be unmapped later.
- */
- crash_mem_map = true;
-
- return 0;
-}
-early_param("crashkernel", enable_crash_mem_map);
-
static void __init map_mem(pgd_t *pgdp)
{
static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN);
@@ -554,16 +539,6 @@ static void __init map_mem(pgd_t *pgdp)
*/
memblock_mark_nomap(kernel_start, kernel_end - kernel_start);

-#ifdef CONFIG_KEXEC_CORE
- if (crash_mem_map) {
- if (defer_reserve_crashkernel())
- flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
- else if (crashk_res.end)
- memblock_mark_nomap(crashk_res.start,
- resource_size(&crashk_res));
- }
-#endif
-
/* map all the memory banks */
for_each_mem_range(i, &start, &end) {
if (start >= end)
@@ -590,24 +565,6 @@ static void __init map_mem(pgd_t *pgdp)
__map_memblock(pgdp, kernel_start, kernel_end,
PAGE_KERNEL, NO_CONT_MAPPINGS);
memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
-
- /*
- * Use page-level mappings here so that we can shrink the region
- * in page granularity and put back unused memory to buddy system
- * through /sys/kernel/kexec_crash_size interface.
- */
-#ifdef CONFIG_KEXEC_CORE
- if (crash_mem_map && !defer_reserve_crashkernel()) {
- if (crashk_res.end) {
- __map_memblock(pgdp, crashk_res.start,
- crashk_res.end + 1,
- PAGE_KERNEL,
- NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
- memblock_clear_nomap(crashk_res.start,
- resource_size(&crashk_res));
- }
- }
-#endif
}

void mark_rodata_ro(void)
--
2.34.1

2023-03-24 13:21:48

by Baoquan He

[permalink] [raw]
Subject: [PATCH 3/3] arm64: kdump: defer the crashkernel reservation for platforms with no DMA memory zones

In commit 031495635b46 ("arm64: Do not defer reserve_crashkernel() for
platforms with no DMA memory zones"), reserve_crashkernel() is called
much earlier in arm64_memblock_init() to avoid causing base apge
mapping on platforms with no DMA meomry zones.

With taking off protection on crashkernel memory region, no need to call
reserve_crashkernel() specially in advance. The deferred invocation of
reserve_crashkernel() in bootmem_init() can cover all cases.

Signed-off-by: Baoquan He <[email protected]>
---
arch/arm64/include/asm/memory.h | 5 -----
arch/arm64/mm/init.c | 6 +-----
2 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 78e5163836a0..efcd68154a3a 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -374,11 +374,6 @@ static inline void *phys_to_virt(phys_addr_t x)
})

void dump_mem_limit(void);
-
-static inline bool defer_reserve_crashkernel(void)
-{
- return IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32);
-}
#endif /* !ASSEMBLY */

/*
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 58a0bb2c17f1..b888de59e0b7 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -408,9 +408,6 @@ void __init arm64_memblock_init(void)

early_init_fdt_scan_reserved_mem();

- if (!defer_reserve_crashkernel())
- reserve_crashkernel();
-
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
}

@@ -457,8 +454,7 @@ void __init bootmem_init(void)
* request_standard_resources() depends on crashkernel's memory being
* reserved, so do it here.
*/
- if (defer_reserve_crashkernel())
- reserve_crashkernel();
+ reserve_crashkernel();

memblock_dump_all();
}
--
2.34.1

2023-03-24 17:15:22

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH 0/3] arm64: kdump : take off the protection on crashkernel memory region

On Fri, Mar 24, 2023 at 09:18:35PM +0800, Baoquan He wrote:
> Baoquan He (3):
> arm64: kdump : take off the protection on crashkernel memory region
> arm64: kdump: do not map crashkernel region specifically
> arm64: kdump: defer the crashkernel reservation for platforms with no
> DMA memory zones
>
> arch/arm64/include/asm/kexec.h | 6 -----
> arch/arm64/include/asm/memory.h | 5 ----
> arch/arm64/kernel/machine_kexec.c | 20 --------------
> arch/arm64/mm/init.c | 6 +----
> arch/arm64/mm/mmu.c | 43 -------------------------------
> 5 files changed, 1 insertion(+), 79 deletions(-)

This series works for me and it has a negative diffstat as well (though
I'm sure people will try to bring it back ;)).

Acked-by: Catalin Marinas <[email protected]>

2023-03-25 02:13:22

by Zhen Lei

[permalink] [raw]
Subject: Re: [PATCH 2/3] arm64: kdump: do not map crashkernel region specifically



On 2023/3/24 21:18, Baoquan He wrote:
> After taking off the protection functions on crashkernel memory region,
> there's no need to map crashkernel region with page granularity during
> linear mapping.
>
> With this change, the system can make use of block or section mapping
> on linear region to largely improve perforcemence during system bootup
> and running.
>
> Signed-off-by: Baoquan He <[email protected]>
> ---
> arch/arm64/mm/mmu.c | 43 -------------------------------------------
> 1 file changed, 43 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 6f9d8898a025..7556020a27b7 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -510,21 +510,6 @@ void __init mark_linear_text_alias_ro(void)
> PAGE_KERNEL_RO);
> }
>
> -static bool crash_mem_map __initdata;
> -
> -static int __init enable_crash_mem_map(char *arg)
> -{
> - /*
> - * Proper parameter parsing is done by reserve_crashkernel(). We only
> - * need to know if the linear map has to avoid block mappings so that
> - * the crashkernel reservations can be unmapped later.
> - */
> - crash_mem_map = true;
> -
> - return 0;
> -}
> -early_param("crashkernel", enable_crash_mem_map);
> -
> static void __init map_mem(pgd_t *pgdp)
> {
> static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN);
> @@ -554,16 +539,6 @@ static void __init map_mem(pgd_t *pgdp)
> */
> memblock_mark_nomap(kernel_start, kernel_end - kernel_start);
>
> -#ifdef CONFIG_KEXEC_CORE
> - if (crash_mem_map) {
> - if (defer_reserve_crashkernel())
> - flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
> - else if (crashk_res.end)
> - memblock_mark_nomap(crashk_res.start,
> - resource_size(&crashk_res));
> - }
> -#endif
> -
> /* map all the memory banks */
> for_each_mem_range(i, &start, &end) {
> if (start >= end)
> @@ -590,24 +565,6 @@ static void __init map_mem(pgd_t *pgdp)
> __map_memblock(pgdp, kernel_start, kernel_end,
> PAGE_KERNEL, NO_CONT_MAPPINGS);
> memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
> -
> - /*
> - * Use page-level mappings here so that we can shrink the region
> - * in page granularity and put back unused memory to buddy system
> - * through /sys/kernel/kexec_crash_size interface.
> - */
> -#ifdef CONFIG_KEXEC_CORE
> - if (crash_mem_map && !defer_reserve_crashkernel()) {
> - if (crashk_res.end) {
> - __map_memblock(pgdp, crashk_res.start,
> - crashk_res.end + 1,
> - PAGE_KERNEL,
> - NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
> - memblock_clear_nomap(crashk_res.start,
> - resource_size(&crashk_res));
> - }
> - }
> -#endif
> }
>
> void mark_rodata_ro(void)
>

Reviewed-by: Zhen Lei <[email protected]>

--
Regards,
Zhen Lei

2023-03-25 02:15:27

by Zhen Lei

[permalink] [raw]
Subject: Re: [PATCH 3/3] arm64: kdump: defer the crashkernel reservation for platforms with no DMA memory zones



On 2023/3/24 21:18, Baoquan He wrote:
> In commit 031495635b46 ("arm64: Do not defer reserve_crashkernel() for
> platforms with no DMA memory zones"), reserve_crashkernel() is called
> much earlier in arm64_memblock_init() to avoid causing base apge
> mapping on platforms with no DMA meomry zones.
>
> With taking off protection on crashkernel memory region, no need to call
> reserve_crashkernel() specially in advance. The deferred invocation of
> reserve_crashkernel() in bootmem_init() can cover all cases.
>
> Signed-off-by: Baoquan He <[email protected]>
> ---
> arch/arm64/include/asm/memory.h | 5 -----
> arch/arm64/mm/init.c | 6 +-----
> 2 files changed, 1 insertion(+), 10 deletions(-)
>
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 78e5163836a0..efcd68154a3a 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -374,11 +374,6 @@ static inline void *phys_to_virt(phys_addr_t x)
> })
>
> void dump_mem_limit(void);
> -
> -static inline bool defer_reserve_crashkernel(void)
> -{
> - return IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32);
> -}
> #endif /* !ASSEMBLY */
>
> /*
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 58a0bb2c17f1..b888de59e0b7 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -408,9 +408,6 @@ void __init arm64_memblock_init(void)
>
> early_init_fdt_scan_reserved_mem();
>
> - if (!defer_reserve_crashkernel())
> - reserve_crashkernel();
> -
> high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
> }
>
> @@ -457,8 +454,7 @@ void __init bootmem_init(void)
> * request_standard_resources() depends on crashkernel's memory being
> * reserved, so do it here.
> */
> - if (defer_reserve_crashkernel())
> - reserve_crashkernel();
> + reserve_crashkernel();
>
> memblock_dump_all();
> }

Some comments also need to be deleted, above the definition of arm64_dma_phys_limit
in arch/arm64/mm/init.c

>

--
Regards,
Zhen Lei

2023-03-25 02:20:48

by Zhen Lei

[permalink] [raw]
Subject: Re: [PATCH 0/3] arm64: kdump : take off the protection on crashkernel memory region



On 2023/3/25 1:11, Catalin Marinas wrote:
> On Fri, Mar 24, 2023 at 09:18:35PM +0800, Baoquan He wrote:
>> Baoquan He (3):
>> arm64: kdump : take off the protection on crashkernel memory region
>> arm64: kdump: do not map crashkernel region specifically
>> arm64: kdump: defer the crashkernel reservation for platforms with no
>> DMA memory zones
>>
>> arch/arm64/include/asm/kexec.h | 6 -----
>> arch/arm64/include/asm/memory.h | 5 ----
>> arch/arm64/kernel/machine_kexec.c | 20 --------------
>> arch/arm64/mm/init.c | 6 +----
>> arch/arm64/mm/mmu.c | 43 -------------------------------
>> 5 files changed, 1 insertion(+), 79 deletions(-)
>
> This series works for me and it has a negative diffstat as well (though
> I'm sure people will try to bring it back ;)).

After the write protection is removed, it is recommended that crc32 check
be added. However, it can be added later.

>
> Acked-by: Catalin Marinas <[email protected]>
>
> .
>

--
Regards,
Zhen Lei

2023-03-25 03:05:01

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH 0/3] arm64: kdump : take off the protection on crashkernel memory region

On 03/25/23 at 10:14am, Leizhen (ThunderTown) wrote:
>
>
> On 2023/3/25 1:11, Catalin Marinas wrote:
> > On Fri, Mar 24, 2023 at 09:18:35PM +0800, Baoquan He wrote:
> >> Baoquan He (3):
> >> arm64: kdump : take off the protection on crashkernel memory region
> >> arm64: kdump: do not map crashkernel region specifically
> >> arm64: kdump: defer the crashkernel reservation for platforms with no
> >> DMA memory zones
> >>
> >> arch/arm64/include/asm/kexec.h | 6 -----
> >> arch/arm64/include/asm/memory.h | 5 ----
> >> arch/arm64/kernel/machine_kexec.c | 20 --------------
> >> arch/arm64/mm/init.c | 6 +----
> >> arch/arm64/mm/mmu.c | 43 -------------------------------
> >> 5 files changed, 1 insertion(+), 79 deletions(-)
> >
> > This series works for me and it has a negative diffstat as well (though
> > I'm sure people will try to bring it back ;)).
>
> After the write protection is removed, it is recommended that crc32 check
> be added. However, it can be added later.

That's a great catch. We have calculated the checusum with sha256 in
user space and kernel, and verify it in purgatory in user space.
However, arm64 seems to not do the verifying in kernel if
kexec_file_load is used. Please see kexec_calculate_store_digests().

If stamping happened, the checksum verification can help us spot it.
Yes, this can be added later. Thanks for raising that.

2023-03-25 06:05:10

by Mike Rapoport

[permalink] [raw]
Subject: Re: [PATCH 0/3] arm64: kdump : take off the protection on crashkernel memory region

On Fri, Mar 24, 2023 at 09:18:35PM +0800, Baoquan He wrote:
> Problem:
> =======
> On arm64, block and section mapping is supported to build page tables.
> However, currently it enforces to take base page mapping for the whole
> linear mapping if CONFIG_ZONE_DMA or CONFIG_ZONE_DMA32 is enabled and
> crashkernel kernel parameter is set. This will cause longer time of the
> linear mapping process during bootup and severe performance degradation
> during running time.
>
> Root cause:
> ==========
> On arm64, crashkernel reservation relies on knowing the upper limit of
> low memory zone because it needs to reserve memory in the zone so that
> devices' DMA addressing in kdump kernel can be satisfied. However, the
> upper limit of low memory on arm64 is variant. And the upper limit can
> only be decided late till bootmem_init() is called [1].
>
> And we need to map the crashkernel region with base page granularity when
> doing linear mapping, because kdump needs to protect the crashkernel region
> via set_memory_valid(,0) after kdump kernel loading. However, arm64 doesn't
> support well on splitting the built block or section mapping due to some
> cpu reststriction [2]. And unfortunately, the linear mapping is done before
> bootmem_init().
>
> To resolve the above conflict on arm64, the compromise is enforcing to
> take base page mapping for the entire linear mapping if crashkernel is
> set, and CONFIG_ZONE_DMA or CONFIG_ZONE_DMA32 is enabed. Hence
> performance is sacrificed.
>
> Solution:
> =========
> Comparing with the always encountered base page mapping for the whole
> linear region, it's better to take off the protection on crashkernel memory
> region for now because the protection can only happen in a chance in one
> million, while the base page mapping for the whole linear mapping is
> always mitigating arm64 systems with crashkernel set.
>
> This can let distros have chance to back port this patchset to fix the
> performance issue caused by the base page mapping in the whole linear
> region.
>
> Extra words
> ===========
> I personally expect that we can add these back in the near future
> when arm64_dma_phys_limit is fixed, e.g Raspberry Pi enlarges the device
> addressing limit to 32bit; or Arm64 can support splitting built block or
> section mapping. Like this, the code is the simplest and clearest.
>
> Or as Catalin suggested, for below 4 cases we currently defer to handle
> in bootme_init(), we can try to handle case 3) in advance so that memory
> above 4G can avoid base page mapping wholly. This will complicate the
> already complex code, let's see how it looks if people interested post patch.
>
> crashkernel=size
> 1)first attempt: low memory under arm64_dma_phys_limit
> 2)fallback: finding memory above 4G
>
> crashkernel=size,high
> 3)first attempt: finding memory above 4G
> 4)fallback: low memory under arm64_dma_phys_limit
>
>
> [1]
> https://lore.kernel.org/all/[email protected]/T/#u
>
> [2]
> https://lore.kernel.org/linux-arm-kernel/[email protected]/T/
>
> Baoquan He (3):
> arm64: kdump : take off the protection on crashkernel memory region
> arm64: kdump: do not map crashkernel region specifically
> arm64: kdump: defer the crashkernel reservation for platforms with no
> DMA memory zones
>
> arch/arm64/include/asm/kexec.h | 6 -----
> arch/arm64/include/asm/memory.h | 5 ----
> arch/arm64/kernel/machine_kexec.c | 20 --------------
> arch/arm64/mm/init.c | 6 +----
> arch/arm64/mm/mmu.c | 43 -------------------------------
> 5 files changed, 1 insertion(+), 79 deletions(-)

Acked-by: Mike Rapoport (IBM) <[email protected]>

> --
> 2.34.1
>

--
Sincerely yours,
Mike.

2023-03-26 13:17:02

by Baoquan He

[permalink] [raw]
Subject: [PATCH v2 3/3] arm64: kdump: defer the crashkernel reservation for platforms with no DMA memory zones

In commit 031495635b46 ("arm64: Do not defer reserve_crashkernel() for
platforms with no DMA memory zones"), reserve_crashkernel() is called
much earlier in arm64_memblock_init() to avoid causing base apge
mapping on platforms with no DMA meomry zones.

With taking off protection on crashkernel memory region, no need to call
reserve_crashkernel() specially in advance. The deferred invocation of
reserve_crashkernel() in bootmem_init() can cover all cases. So revert
the commit 031495635b46 now.

Signed-off-by: Baoquan He <[email protected]>
---
v1->v2:
- When trying to revert commit 031495635b46, two hunks were missed in v1
post. Remove them in v2. Thanks to Leizhen for pointing out this.
- Remove code comment above arm64_dma_phys_limit definition added
in commit 031495635b46;
- Move the arm64_dma_phys_limit assignment back into zone_sizes_init()
when both CONFIG_ZONE_DMA and CONFIG_ZONE_DMA32 are not enabled.

arch/arm64/include/asm/memory.h | 5 -----
arch/arm64/mm/init.c | 34 +++------------------------------
2 files changed, 3 insertions(+), 36 deletions(-)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 78e5163836a0..efcd68154a3a 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -374,11 +374,6 @@ static inline void *phys_to_virt(phys_addr_t x)
})

void dump_mem_limit(void);
-
-static inline bool defer_reserve_crashkernel(void)
-{
- return IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32);
-}
#endif /* !ASSEMBLY */

/*
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 58a0bb2c17f1..66e70ca47680 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -61,34 +61,8 @@ EXPORT_SYMBOL(memstart_addr);
* unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4).
* In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory,
* otherwise it is empty.
- *
- * Memory reservation for crash kernel either done early or deferred
- * depending on DMA memory zones configs (ZONE_DMA) --
- *
- * In absence of ZONE_DMA configs arm64_dma_phys_limit initialized
- * here instead of max_zone_phys(). This lets early reservation of
- * crash kernel memory which has a dependency on arm64_dma_phys_limit.
- * Reserving memory early for crash kernel allows linear creation of block
- * mappings (greater than page-granularity) for all the memory bank rangs.
- * In this scheme a comparatively quicker boot is observed.
- *
- * If ZONE_DMA configs are defined, crash kernel memory reservation
- * is delayed until DMA zone memory range size initialization performed in
- * zone_sizes_init(). The defer is necessary to steer clear of DMA zone
- * memory range to avoid overlap allocation. So crash kernel memory boundaries
- * are not known when mapping all bank memory ranges, which otherwise means
- * not possible to exclude crash kernel range from creating block mappings
- * so page-granularity mappings are created for the entire memory range.
- * Hence a slightly slower boot is observed.
- *
- * Note: Page-granularity mappings are necessary for crash kernel memory
- * range for shrinking its size via /sys/kernel/kexec_crash_size interface.
*/
-#if IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32)
phys_addr_t __ro_after_init arm64_dma_phys_limit;
-#else
-phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
-#endif

/* Current arm64 boot protocol requires 2MB alignment */
#define CRASH_ALIGN SZ_2M
@@ -248,6 +222,8 @@ static void __init zone_sizes_init(void)
if (!arm64_dma_phys_limit)
arm64_dma_phys_limit = dma32_phys_limit;
#endif
+ if (!arm64_dma_phys_limit)
+ arm64_dma_phys_limit = PHYS_MASK + 1;
max_zone_pfns[ZONE_NORMAL] = max_pfn;

free_area_init(max_zone_pfns);
@@ -408,9 +384,6 @@ void __init arm64_memblock_init(void)

early_init_fdt_scan_reserved_mem();

- if (!defer_reserve_crashkernel())
- reserve_crashkernel();
-
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
}

@@ -457,8 +430,7 @@ void __init bootmem_init(void)
* request_standard_resources() depends on crashkernel's memory being
* reserved, so do it here.
*/
- if (defer_reserve_crashkernel())
- reserve_crashkernel();
+ reserve_crashkernel();

memblock_dump_all();
}
--
2.34.1

2023-03-26 13:44:19

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH 3/3] arm64: kdump: defer the crashkernel reservation for platforms with no DMA memory zones

On 03/25/23 at 10:04am, Leizhen (ThunderTown) wrote:
>
>
> On 2023/3/24 21:18, Baoquan He wrote:
> > In commit 031495635b46 ("arm64: Do not defer reserve_crashkernel() for
> > platforms with no DMA memory zones"), reserve_crashkernel() is called
> > much earlier in arm64_memblock_init() to avoid causing base apge
> > mapping on platforms with no DMA meomry zones.
> >
> > With taking off protection on crashkernel memory region, no need to call
> > reserve_crashkernel() specially in advance. The deferred invocation of
> > reserve_crashkernel() in bootmem_init() can cover all cases.
> >
> > Signed-off-by: Baoquan He <[email protected]>
> > ---
> > arch/arm64/include/asm/memory.h | 5 -----
> > arch/arm64/mm/init.c | 6 +-----
> > 2 files changed, 1 insertion(+), 10 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> > index 78e5163836a0..efcd68154a3a 100644
> > --- a/arch/arm64/include/asm/memory.h
> > +++ b/arch/arm64/include/asm/memory.h
> > @@ -374,11 +374,6 @@ static inline void *phys_to_virt(phys_addr_t x)
> > })
> >
> > void dump_mem_limit(void);
> > -
> > -static inline bool defer_reserve_crashkernel(void)
> > -{
> > - return IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32);
> > -}
> > #endif /* !ASSEMBLY */
> >
> > /*
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 58a0bb2c17f1..b888de59e0b7 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -408,9 +408,6 @@ void __init arm64_memblock_init(void)
> >
> > early_init_fdt_scan_reserved_mem();
> >
> > - if (!defer_reserve_crashkernel())
> > - reserve_crashkernel();
> > -
> > high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
> > }
> >
> > @@ -457,8 +454,7 @@ void __init bootmem_init(void)
> > * request_standard_resources() depends on crashkernel's memory being
> > * reserved, so do it here.
> > */
> > - if (defer_reserve_crashkernel())
> > - reserve_crashkernel();
> > + reserve_crashkernel();
> >
> > memblock_dump_all();
> > }
>
> Some comments also need to be deleted, above the definition of arm64_dma_phys_limit
> in arch/arm64/mm/init.c

Thanks, have posted v2 of patch 3 to remove the code comment, and move
back the arm64_dma_phys_limit assignmet as 'PHYS_MASK + 1;' into
zone_sizes_init(). These should be part of the reverting commit
031495635b46, I missed that.

2023-03-27 01:30:44

by Zhen Lei

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] arm64: kdump: defer the crashkernel reservation for platforms with no DMA memory zones



On 2023/3/26 21:02, Baoquan He wrote:
> In commit 031495635b46 ("arm64: Do not defer reserve_crashkernel() for
> platforms with no DMA memory zones"), reserve_crashkernel() is called
> much earlier in arm64_memblock_init() to avoid causing base apge
> mapping on platforms with no DMA meomry zones.
>
> With taking off protection on crashkernel memory region, no need to call
> reserve_crashkernel() specially in advance. The deferred invocation of
> reserve_crashkernel() in bootmem_init() can cover all cases. So revert
> the commit 031495635b46 now.
>
> Signed-off-by: Baoquan He <[email protected]>
> ---
> v1->v2:
> - When trying to revert commit 031495635b46, two hunks were missed in v1
> post. Remove them in v2. Thanks to Leizhen for pointing out this.
> - Remove code comment above arm64_dma_phys_limit definition added
> in commit 031495635b46;
> - Move the arm64_dma_phys_limit assignment back into zone_sizes_init()
> when both CONFIG_ZONE_DMA and CONFIG_ZONE_DMA32 are not enabled.

Reviewed-by: Zhen Lei <[email protected]>

>
> arch/arm64/include/asm/memory.h | 5 -----
> arch/arm64/mm/init.c | 34 +++------------------------------
> 2 files changed, 3 insertions(+), 36 deletions(-)
>
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 78e5163836a0..efcd68154a3a 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -374,11 +374,6 @@ static inline void *phys_to_virt(phys_addr_t x)
> })
>
> void dump_mem_limit(void);
> -
> -static inline bool defer_reserve_crashkernel(void)
> -{
> - return IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32);
> -}
> #endif /* !ASSEMBLY */
>
> /*
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 58a0bb2c17f1..66e70ca47680 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -61,34 +61,8 @@ EXPORT_SYMBOL(memstart_addr);
> * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4).
> * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory,
> * otherwise it is empty.
> - *
> - * Memory reservation for crash kernel either done early or deferred
> - * depending on DMA memory zones configs (ZONE_DMA) --
> - *
> - * In absence of ZONE_DMA configs arm64_dma_phys_limit initialized
> - * here instead of max_zone_phys(). This lets early reservation of
> - * crash kernel memory which has a dependency on arm64_dma_phys_limit.
> - * Reserving memory early for crash kernel allows linear creation of block
> - * mappings (greater than page-granularity) for all the memory bank rangs.
> - * In this scheme a comparatively quicker boot is observed.
> - *
> - * If ZONE_DMA configs are defined, crash kernel memory reservation
> - * is delayed until DMA zone memory range size initialization performed in
> - * zone_sizes_init(). The defer is necessary to steer clear of DMA zone
> - * memory range to avoid overlap allocation. So crash kernel memory boundaries
> - * are not known when mapping all bank memory ranges, which otherwise means
> - * not possible to exclude crash kernel range from creating block mappings
> - * so page-granularity mappings are created for the entire memory range.
> - * Hence a slightly slower boot is observed.
> - *
> - * Note: Page-granularity mappings are necessary for crash kernel memory
> - * range for shrinking its size via /sys/kernel/kexec_crash_size interface.
> */
> -#if IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32)
> phys_addr_t __ro_after_init arm64_dma_phys_limit;
> -#else
> -phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
> -#endif
>
> /* Current arm64 boot protocol requires 2MB alignment */
> #define CRASH_ALIGN SZ_2M
> @@ -248,6 +222,8 @@ static void __init zone_sizes_init(void)
> if (!arm64_dma_phys_limit)
> arm64_dma_phys_limit = dma32_phys_limit;
> #endif
> + if (!arm64_dma_phys_limit)
> + arm64_dma_phys_limit = PHYS_MASK + 1;
> max_zone_pfns[ZONE_NORMAL] = max_pfn;
>
> free_area_init(max_zone_pfns);
> @@ -408,9 +384,6 @@ void __init arm64_memblock_init(void)
>
> early_init_fdt_scan_reserved_mem();
>
> - if (!defer_reserve_crashkernel())
> - reserve_crashkernel();
> -
> high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
> }
>
> @@ -457,8 +430,7 @@ void __init bootmem_init(void)
> * request_standard_resources() depends on crashkernel's memory being
> * reserved, so do it here.
> */
> - if (defer_reserve_crashkernel())
> - reserve_crashkernel();
> + reserve_crashkernel();
>
> memblock_dump_all();
> }
>

--
Regards,
Zhen Lei