All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kefeng Wang <wangkefeng.wang@huawei.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>
Cc: <vijayb@linux.microsoft.com>, <f.fainelli@gmail.com>,
	Kefeng Wang <wangkefeng.wang@huawei.com>
Subject: [PATCH v3 2/3] arm64: mm: Don't defer reserve_crashkernel() with dma_force_32bit
Date: Mon, 11 Apr 2022 17:24:54 +0800	[thread overview]
Message-ID: <20220411092455.1461-3-wangkefeng.wang@huawei.com> (raw)
In-Reply-To: <20220411092455.1461-1-wangkefeng.wang@huawei.com>

ARM64 enable ZONE_DMA by default, and with ZONE_DMA crash kernel
memory reservation is delayed until DMA zone memory range size
initilazation performed in zone_sizes_init(), but for most platforms
use 32bit dma_zone_bits, so add dma_force_32bit kernel parameter
if ZONE_DMA enabled, and initialize arm64_dma_phys_limit to
max_zone_phys(32) in arm64_memblock_init() if dma_force_32bit
is setup, this could let the crash kernel reservation earlier,
and allows linear creation with block mapping.

Reviewed-by: Vijay Balakrishna <vijayb@linux.microsoft.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 arch/arm64/include/asm/kexec.h |  1 +
 arch/arm64/mm/init.c           | 43 +++++++++++++++++++++++++++-------
 arch/arm64/mm/mmu.c            |  4 ++--
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 9839bfc163d7..624865d1cc71 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -95,6 +95,7 @@ void cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
 		      unsigned long arg0, unsigned long arg1,
 		      unsigned long arg2);
 #endif
+bool crashkernel_early_reserve(void);
 
 #define ARCH_HAS_KIMAGE_ARCH
 
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 897de41102d9..18b0031eadd0 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@
 #include <asm/boot.h>
 #include <asm/fixmap.h>
 #include <asm/kasan.h>
+#include <asm/kexec.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/kvm_host.h>
 #include <asm/memory.h>
@@ -66,7 +67,8 @@ EXPORT_SYMBOL(memstart_addr);
  * depending on DMA memory zones configs (ZONE_DMA) --
  *
  * In absence of ZONE_DMA and ZONE_DMA32 configs arm64_dma_phys_limit
- * initialized here and if only with ZONE_DMA32 arm64_dma_phys_limit
+ * initialized here, and if only with ZONE_DMA32 or if with ZONE_DMA
+ * and dma_force_32bit kernel parameter, the arm64_dma_phys_limit is
  * initialised to max_zone_phys(32). 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
@@ -91,6 +93,27 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit;
 phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
 #endif
 
+static bool __ro_after_init arm64_dma_force_32bit;
+#ifdef CONFIG_ZONE_DMA
+static int __init arm64_dma_force_32bit_setup(char *p)
+{
+	zone_dma_bits = 32;
+	arm64_dma_force_32bit = true;
+
+	return 0;
+}
+early_param("dma_force_32bit", arm64_dma_force_32bit_setup);
+#endif
+
+bool __init crashkernel_early_reserve(void)
+{
+	if (!IS_ENABLED(CONFIG_ZONE_DMA))
+		return true;
+	if (arm64_dma_force_32bit)
+		return true;
+	return false;
+}
+
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -162,12 +185,14 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES]  = {0};
 #ifdef CONFIG_ZONE_DMA
-	unsigned int acpi_zone_dma_bits;
-	unsigned int dt_zone_dma_bits;
+	if (!arm64_dma_force_32bit) {
+		unsigned int acpi_zone_dma_bits;
+		unsigned int dt_zone_dma_bits;
 
-	acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address());
-	dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL));
-	zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits);
+		acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address());
+		dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL));
+		zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits);
+	}
 	arm64_dma_phys_limit = max_zone_phys(zone_dma_bits);
 	max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
 #endif
@@ -334,8 +359,8 @@ void __init arm64_memblock_init(void)
 
 	early_init_fdt_scan_reserved_mem();
 
-	if (!IS_ENABLED(CONFIG_ZONE_DMA)) {
-		if (IS_ENABLED(CONFIG_ZONE_DMA32))
+	if (crashkernel_early_reserve()) {
+		if (IS_ENABLED(CONFIG_ZONE_DMA32) || arm64_dma_force_32bit)
 			arm64_dma_phys_limit = max_zone_phys(32);
 		reserve_crashkernel();
 	}
@@ -386,7 +411,7 @@ void __init bootmem_init(void)
 	 * request_standard_resources() depends on crashkernel's memory being
 	 * reserved, so do it here.
 	 */
-	if (IS_ENABLED(CONFIG_ZONE_DMA))
+	if (!crashkernel_early_reserve())
 		reserve_crashkernel();
 
 	memblock_dump_all();
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 23734481318a..46b626025b78 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -529,7 +529,7 @@ static void __init map_mem(pgd_t *pgdp)
 
 #ifdef CONFIG_KEXEC_CORE
 	if (crash_mem_map) {
-		if (IS_ENABLED(CONFIG_ZONE_DMA))
+		if (!crashkernel_early_reserve())
 			flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
 		else if (crashk_res.end)
 			memblock_mark_nomap(crashk_res.start,
@@ -570,7 +570,7 @@ static void __init map_mem(pgd_t *pgdp)
 	 * through /sys/kernel/kexec_crash_size interface.
 	 */
 #ifdef CONFIG_KEXEC_CORE
-	if (crash_mem_map && !IS_ENABLED(CONFIG_ZONE_DMA)) {
+	if (crash_mem_map && crashkernel_early_reserve()) {
 		if (crashk_res.end) {
 			__map_memblock(pgdp, crashk_res.start,
 				       crashk_res.end + 1,
-- 
2.26.2


WARNING: multiple messages have this Message-ID (diff)
From: Kefeng Wang <wangkefeng.wang@huawei.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>
Cc: <vijayb@linux.microsoft.com>, <f.fainelli@gmail.com>,
	Kefeng Wang <wangkefeng.wang@huawei.com>
Subject: [PATCH v3 2/3] arm64: mm: Don't defer reserve_crashkernel() with dma_force_32bit
Date: Mon, 11 Apr 2022 17:24:54 +0800	[thread overview]
Message-ID: <20220411092455.1461-3-wangkefeng.wang@huawei.com> (raw)
In-Reply-To: <20220411092455.1461-1-wangkefeng.wang@huawei.com>

ARM64 enable ZONE_DMA by default, and with ZONE_DMA crash kernel
memory reservation is delayed until DMA zone memory range size
initilazation performed in zone_sizes_init(), but for most platforms
use 32bit dma_zone_bits, so add dma_force_32bit kernel parameter
if ZONE_DMA enabled, and initialize arm64_dma_phys_limit to
max_zone_phys(32) in arm64_memblock_init() if dma_force_32bit
is setup, this could let the crash kernel reservation earlier,
and allows linear creation with block mapping.

Reviewed-by: Vijay Balakrishna <vijayb@linux.microsoft.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 arch/arm64/include/asm/kexec.h |  1 +
 arch/arm64/mm/init.c           | 43 +++++++++++++++++++++++++++-------
 arch/arm64/mm/mmu.c            |  4 ++--
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 9839bfc163d7..624865d1cc71 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -95,6 +95,7 @@ void cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
 		      unsigned long arg0, unsigned long arg1,
 		      unsigned long arg2);
 #endif
+bool crashkernel_early_reserve(void);
 
 #define ARCH_HAS_KIMAGE_ARCH
 
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 897de41102d9..18b0031eadd0 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -35,6 +35,7 @@
 #include <asm/boot.h>
 #include <asm/fixmap.h>
 #include <asm/kasan.h>
+#include <asm/kexec.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/kvm_host.h>
 #include <asm/memory.h>
@@ -66,7 +67,8 @@ EXPORT_SYMBOL(memstart_addr);
  * depending on DMA memory zones configs (ZONE_DMA) --
  *
  * In absence of ZONE_DMA and ZONE_DMA32 configs arm64_dma_phys_limit
- * initialized here and if only with ZONE_DMA32 arm64_dma_phys_limit
+ * initialized here, and if only with ZONE_DMA32 or if with ZONE_DMA
+ * and dma_force_32bit kernel parameter, the arm64_dma_phys_limit is
  * initialised to max_zone_phys(32). 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
@@ -91,6 +93,27 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit;
 phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
 #endif
 
+static bool __ro_after_init arm64_dma_force_32bit;
+#ifdef CONFIG_ZONE_DMA
+static int __init arm64_dma_force_32bit_setup(char *p)
+{
+	zone_dma_bits = 32;
+	arm64_dma_force_32bit = true;
+
+	return 0;
+}
+early_param("dma_force_32bit", arm64_dma_force_32bit_setup);
+#endif
+
+bool __init crashkernel_early_reserve(void)
+{
+	if (!IS_ENABLED(CONFIG_ZONE_DMA))
+		return true;
+	if (arm64_dma_force_32bit)
+		return true;
+	return false;
+}
+
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -162,12 +185,14 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES]  = {0};
 #ifdef CONFIG_ZONE_DMA
-	unsigned int acpi_zone_dma_bits;
-	unsigned int dt_zone_dma_bits;
+	if (!arm64_dma_force_32bit) {
+		unsigned int acpi_zone_dma_bits;
+		unsigned int dt_zone_dma_bits;
 
-	acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address());
-	dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL));
-	zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits);
+		acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address());
+		dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL));
+		zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits);
+	}
 	arm64_dma_phys_limit = max_zone_phys(zone_dma_bits);
 	max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
 #endif
@@ -334,8 +359,8 @@ void __init arm64_memblock_init(void)
 
 	early_init_fdt_scan_reserved_mem();
 
-	if (!IS_ENABLED(CONFIG_ZONE_DMA)) {
-		if (IS_ENABLED(CONFIG_ZONE_DMA32))
+	if (crashkernel_early_reserve()) {
+		if (IS_ENABLED(CONFIG_ZONE_DMA32) || arm64_dma_force_32bit)
 			arm64_dma_phys_limit = max_zone_phys(32);
 		reserve_crashkernel();
 	}
@@ -386,7 +411,7 @@ void __init bootmem_init(void)
 	 * request_standard_resources() depends on crashkernel's memory being
 	 * reserved, so do it here.
 	 */
-	if (IS_ENABLED(CONFIG_ZONE_DMA))
+	if (!crashkernel_early_reserve())
 		reserve_crashkernel();
 
 	memblock_dump_all();
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 23734481318a..46b626025b78 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -529,7 +529,7 @@ static void __init map_mem(pgd_t *pgdp)
 
 #ifdef CONFIG_KEXEC_CORE
 	if (crash_mem_map) {
-		if (IS_ENABLED(CONFIG_ZONE_DMA))
+		if (!crashkernel_early_reserve())
 			flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
 		else if (crashk_res.end)
 			memblock_mark_nomap(crashk_res.start,
@@ -570,7 +570,7 @@ static void __init map_mem(pgd_t *pgdp)
 	 * through /sys/kernel/kexec_crash_size interface.
 	 */
 #ifdef CONFIG_KEXEC_CORE
-	if (crash_mem_map && !IS_ENABLED(CONFIG_ZONE_DMA)) {
+	if (crash_mem_map && crashkernel_early_reserve()) {
 		if (crashk_res.end) {
 			__map_memblock(pgdp, crashk_res.start,
 				       crashk_res.end + 1,
-- 
2.26.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2022-04-11  9:12 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-11  9:24 [PATCH v3 0/3] arm64: mm: Do not defer reserve_crashkernel() Kefeng Wang
2022-04-11  9:24 ` Kefeng Wang
2022-04-11  9:24 ` [PATCH v3 1/3] arm64: mm: Do not defer reserve_crashkernel() if only ZONE_DMA32 Kefeng Wang
2022-04-11  9:24   ` Kefeng Wang
2022-04-11  9:24 ` Kefeng Wang [this message]
2022-04-11  9:24   ` [PATCH v3 2/3] arm64: mm: Don't defer reserve_crashkernel() with dma_force_32bit Kefeng Wang
2022-04-11  9:24 ` [PATCH v3 3/3] arm64: mm: Cleanup useless parameters in zone_sizes_init() Kefeng Wang
2022-04-11  9:24   ` Kefeng Wang
2022-04-27 12:41 ` [PATCH v3 0/3] arm64: mm: Do not defer reserve_crashkernel() Kefeng Wang
2022-04-27 12:41   ` Kefeng Wang
2022-05-03 18:20 ` Catalin Marinas
2022-05-03 18:20   ` Catalin Marinas
2022-05-05  3:04   ` Kefeng Wang
2022-05-05  3:04     ` Kefeng Wang
2022-05-05  8:26 ` (subset) " Catalin Marinas
2022-05-05  8:26   ` Catalin Marinas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220411092455.1461-3-wangkefeng.wang@huawei.com \
    --to=wangkefeng.wang@huawei.com \
    --cc=catalin.marinas@arm.com \
    --cc=f.fainelli@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vijayb@linux.microsoft.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.