linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
@ 2020-09-15 15:08 Phil Chang
  2020-09-15 16:13 ` Catalin Marinas
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Phil Chang @ 2020-09-15 15:08 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan Corbet, Catalin Marinas, Will Deacon,
	Mauro Carvalho Chehab, Mark Rutland, Anshuman Khandual,
	Phil Chang, YJ Chiang, Alix Wu, Mike Rapoport, linux-doc,
	linux-kernel, linux-mediatek

Allowing the DMA32 zone be configurable in ARM64 but at most 4Gb.

Signed-off-by: Alix Wu <alix.wu@mediatek.com>
Signed-off-by: YJ Chiang <yj.chiang@mediatek.com>
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---

 .../admin-guide/kernel-parameters.txt         |  3 ++
 arch/arm64/include/asm/memory.h               |  2 +
 arch/arm64/mm/init.c                          | 39 +++++++++++++++++--
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index bdc1f33fd3d1..5be6259e9ba8 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -980,6 +980,9 @@
 			The filter can be disabled or changed to another
 			driver later using sysfs.
 
+	dma32_size=nn[MG]  [KNL,BOOT,ARM64]
+			Forces the DMA32 zone size of <nn> in MB.
+
 	driver_async_probe=  [KNL]
 			List of driver names to be probed asynchronously.
 			Format: <driver_name1>,<driver_name2>...
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index afa722504bfd..710de08ae8ae 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -175,6 +175,8 @@ extern u64			kimage_vaddr;
 /* the offset between the kernel virtual and physical mappings */
 extern u64			kimage_voffset;
 
+extern phys_addr_t		dma32_zone_size;
+
 static inline unsigned long kaslr_offset(void)
 {
 	return kimage_vaddr - KIMAGE_VADDR;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 481d22c32a2e..c8af53680d46 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -60,6 +60,9 @@ EXPORT_SYMBOL(physvirt_offset);
 struct page *vmemmap __ro_after_init;
 EXPORT_SYMBOL(vmemmap);
 
+phys_addr_t dma32_zone_size __ro_after_init;
+EXPORT_SYMBOL(dma32_zone_size);
+
 /*
  * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
  * memory as some devices, namely the Raspberry Pi 4, have peripherals with
@@ -242,6 +245,29 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init setup_dma32_zone(char *p)
+{
+	u64 size;
+
+	if (!p)
+		return -EINVAL;
+
+	if (kstrtoull(p, 0, &size))
+		return -EINVAL;
+
+	/* DMA32 zone size should never grater than 4G */
+	if (size > max_zone_phys(32) / SZ_1M)
+		return -EINVAL;
+
+	pr_notice("Setup dma32 zone size to %llu Mb\n", size);
+
+	dma32_zone_size = size * SZ_1M;
+
+	return 0;
+}
+
+early_param("dma32_size", setup_dma32_zone);
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
 		const char *uname, int depth, void *data)
 {
@@ -392,10 +418,17 @@ void __init arm64_memblock_init(void)
 		arm64_dma_phys_limit = max_zone_phys(ARM64_ZONE_DMA_BITS);
 	}
 
-	if (IS_ENABLED(CONFIG_ZONE_DMA32))
-		arm64_dma32_phys_limit = max_zone_phys(32);
-	else
+	if (IS_ENABLED(CONFIG_ZONE_DMA32)) {
+		if (dma32_zone_size) {
+			arm64_dma32_phys_limit = min(max_zone_phys(32),
+				dma32_zone_size + memblock_start_of_DRAM());
+		} else {
+			arm64_dma32_phys_limit = max_zone_phys(32);
+			dma32_zone_size = arm64_dma32_phys_limit;
+		}
+	} else {
 		arm64_dma32_phys_limit = PHYS_MASK + 1;
+	}
 
 	reserve_crashkernel();
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-15 15:08 [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs Phil Chang
@ 2020-09-15 16:13 ` Catalin Marinas
  2020-09-15 16:18 ` Mike Rapoport
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Catalin Marinas @ 2020-09-15 16:13 UTC (permalink / raw)
  To: Phil Chang
  Cc: linux-arm-kernel, Jonathan Corbet, Will Deacon,
	Mauro Carvalho Chehab, Mark Rutland, Anshuman Khandual,
	YJ Chiang, Alix Wu, Mike Rapoport, linux-doc, linux-kernel,
	linux-mediatek

On Tue, Sep 15, 2020 at 11:08:55PM +0800, Phil Chang wrote:
> Allowing the DMA32 zone be configurable in ARM64 but at most 4Gb.

Why? What is your use-case?

-- 
Catalin

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-15 15:08 [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs Phil Chang
  2020-09-15 16:13 ` Catalin Marinas
@ 2020-09-15 16:18 ` Mike Rapoport
  2020-09-15 17:48 ` David Woodhouse
  2020-09-16  7:22 ` Phil Chang
  3 siblings, 0 replies; 10+ messages in thread
From: Mike Rapoport @ 2020-09-15 16:18 UTC (permalink / raw)
  To: Phil Chang
  Cc: linux-arm-kernel, Jonathan Corbet, Catalin Marinas, Will Deacon,
	Mauro Carvalho Chehab, Mark Rutland, Anshuman Khandual,
	YJ Chiang, Alix Wu, linux-doc, linux-kernel, linux-mediatek

On Tue, Sep 15, 2020 at 11:08:55PM +0800, Phil Chang wrote:
> Allowing the DMA32 zone be configurable in ARM64 but at most 4Gb.

Please add more details why would you like to limit the DMA32 zone.

> Signed-off-by: Alix Wu <alix.wu@mediatek.com>
> Signed-off-by: YJ Chiang <yj.chiang@mediatek.com>
> Signed-off-by: Phil Chang <phil.chang@mediatek.com>
> ---
> 
>  .../admin-guide/kernel-parameters.txt         |  3 ++
>  arch/arm64/include/asm/memory.h               |  2 +
>  arch/arm64/mm/init.c                          | 39 +++++++++++++++++--
>  3 files changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index bdc1f33fd3d1..5be6259e9ba8 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -980,6 +980,9 @@
>  			The filter can be disabled or changed to another
>  			driver later using sysfs.
>  
> +	dma32_size=nn[MG]  [KNL,BOOT,ARM64]
> +			Forces the DMA32 zone size of <nn> in MB.

Most of the kernel parameters that deal with memory sizes allow either
of [KMG] suffixes.

> +
>  	driver_async_probe=  [KNL]
>  			List of driver names to be probed asynchronously.
>  			Format: <driver_name1>,<driver_name2>...
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index afa722504bfd..710de08ae8ae 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -175,6 +175,8 @@ extern u64			kimage_vaddr;
>  /* the offset between the kernel virtual and physical mappings */
>  extern u64			kimage_voffset;
>  
> +extern phys_addr_t		dma32_zone_size;
> +
>  static inline unsigned long kaslr_offset(void)
>  {
>  	return kimage_vaddr - KIMAGE_VADDR;
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 481d22c32a2e..c8af53680d46 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -60,6 +60,9 @@ EXPORT_SYMBOL(physvirt_offset);
>  struct page *vmemmap __ro_after_init;
>  EXPORT_SYMBOL(vmemmap);
>  
> +phys_addr_t dma32_zone_size __ro_after_init;
> +EXPORT_SYMBOL(dma32_zone_size);
> +
>  /*
>   * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
>   * memory as some devices, namely the Raspberry Pi 4, have peripherals with
> @@ -242,6 +245,29 @@ static int __init early_mem(char *p)
>  }
>  early_param("mem", early_mem);
>  
> +static int __init setup_dma32_zone(char *p)
> +{
> +	u64 size;
> +
> +	if (!p)
> +		return -EINVAL;
> +
> +	if (kstrtoull(p, 0, &size))
> +		return -EINVAL;

Better to use memparse() here.

> +
> +	/* DMA32 zone size should never grater than 4G */
> +	if (size > max_zone_phys(32) / SZ_1M)
> +		return -EINVAL;
> +
> +	pr_notice("Setup dma32 zone size to %llu Mb\n", size);
> +
> +	dma32_zone_size = size * SZ_1M;
> +
> +	return 0;
> +}
> +
> +early_param("dma32_size", setup_dma32_zone);
> +
>  static int __init early_init_dt_scan_usablemem(unsigned long node,
>  		const char *uname, int depth, void *data)
>  {
> @@ -392,10 +418,17 @@ void __init arm64_memblock_init(void)
>  		arm64_dma_phys_limit = max_zone_phys(ARM64_ZONE_DMA_BITS);
>  	}
>  
> -	if (IS_ENABLED(CONFIG_ZONE_DMA32))
> -		arm64_dma32_phys_limit = max_zone_phys(32);
> -	else
> +	if (IS_ENABLED(CONFIG_ZONE_DMA32)) {
> +		if (dma32_zone_size) {
> +			arm64_dma32_phys_limit = min(max_zone_phys(32),
> +				dma32_zone_size + memblock_start_of_DRAM());
> +		} else {
> +			arm64_dma32_phys_limit = max_zone_phys(32);
> +			dma32_zone_size = arm64_dma32_phys_limit;
> +		}

I think this calculations can be hidden in max_zone_phys(), e.g.

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 481d22c32a2e..be3fdfb35a56 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -189,7 +189,12 @@ static void __init reserve_elfcorehdr(void)
 static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
 {
 	phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
-	return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
+	phys_addr_t zone_size = (1ULL << zone_bits);
+
+	if (IS_ENABLED(CONFIG_ZONE_DMA32) && zone_bits == 32 && dma32_zone_size)
+		zone_bits = min(zone_size,dma32_zone_size);
+
+	return min(offset + zone_size, memblock_end_of_DRAM());
 }
 
 static void __init zone_sizes_init(unsigned long min, unsigned long max)

> +	} else {
>  		arm64_dma32_phys_limit = PHYS_MASK + 1;
> +	}
>  
>  	reserve_crashkernel();
>  
> -- 
> 2.18.0

-- 
Sincerely yours,
Mike.

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-15 15:08 [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs Phil Chang
  2020-09-15 16:13 ` Catalin Marinas
  2020-09-15 16:18 ` Mike Rapoport
@ 2020-09-15 17:48 ` David Woodhouse
  2020-09-16  7:22 ` Phil Chang
  3 siblings, 0 replies; 10+ messages in thread
From: David Woodhouse @ 2020-09-15 17:48 UTC (permalink / raw)
  To: linux-mediatek, Phil Chang, linux-arm-kernel
  Cc: Mark Rutland, Alix Wu, linux-doc, Anshuman Khandual,
	Mauro Carvalho Chehab, Catalin Marinas, YJ Chiang,
	Jonathan Corbet, linux-kernel, Will Deacon, Mike Rapoport



On 15 September 2020 16:08:55 BST, Phil Chang <phil.chang@mediatek.com> wrote:
>Allowing the DMA32 zone be configurable in ARM64 but at most 4Gb.

I don't think 4,000,000 bits is a particularly sensible limit.

Perhaps you meant bytes, and perhaps you meant 4*1024*1024? That would be "4 GiB".

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-15 15:08 [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs Phil Chang
                   ` (2 preceding siblings ...)
  2020-09-15 17:48 ` David Woodhouse
@ 2020-09-16  7:22 ` Phil Chang
  2020-09-16  8:37   ` Christoph Hellwig
  3 siblings, 1 reply; 10+ messages in thread
From: Phil Chang @ 2020-09-16  7:22 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan Corbet, Catalin Marinas, Will Deacon,
	Mauro Carvalho Chehab, Mark Rutland, Anshuman Khandual,
	Phil Chang, YJ Chiang, Alix Wu, Mike Rapoport, linux-doc,
	linux-kernel, linux-mediatek

this patch allowing the DMA32 zone be configurable in ARM64.

Signed-off-by: Alix Wu <alix.wu@mediatek.com>
Signed-off-by: YJ Chiang <yj.chiang@mediatek.com>
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---
For some devices, the main memory split into 2 part due to the memory
architecture, the efficient and less inefficient part.
One of the use case is fine-tune the dma32 size to contain all the
efficient part of memory block on this kind of architecture

 .../admin-guide/kernel-parameters.txt         |  3 +++
 arch/arm64/include/asm/memory.h               |  2 ++
 arch/arm64/mm/init.c                          | 26 ++++++++++++++++++-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index bdc1f33fd3d1..ef3bc3d4931a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -980,6 +980,9 @@
 			The filter can be disabled or changed to another
 			driver later using sysfs.
 
+	dma32_size=nn[KMG]  [KNL,BOOT,ARM64]
+			Forces the DMA32 zone size of <nn> in MB.
+
 	driver_async_probe=  [KNL]
 			List of driver names to be probed asynchronously.
 			Format: <driver_name1>,<driver_name2>...
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index afa722504bfd..710de08ae8ae 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -175,6 +175,8 @@ extern u64			kimage_vaddr;
 /* the offset between the kernel virtual and physical mappings */
 extern u64			kimage_voffset;
 
+extern phys_addr_t		dma32_zone_size;
+
 static inline unsigned long kaslr_offset(void)
 {
 	return kimage_vaddr - KIMAGE_VADDR;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 481d22c32a2e..fd1b85e131cc 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -60,6 +60,9 @@ EXPORT_SYMBOL(physvirt_offset);
 struct page *vmemmap __ro_after_init;
 EXPORT_SYMBOL(vmemmap);
 
+phys_addr_t dma32_zone_size __ro_after_init;
+EXPORT_SYMBOL(dma32_zone_size);
+
 /*
  * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
  * memory as some devices, namely the Raspberry Pi 4, have peripherals with
@@ -189,7 +192,12 @@ static void __init reserve_elfcorehdr(void)
 static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
 {
 	phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
-	return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
+	phys_addr_t zone_size = (1ULL << zone_bits);
+
+	if (IS_ENABLED(CONFIG_ZONE_DMA32) && zone_bits == 32 && dma32_zone_size)
+		zone_size = min(zone_size, dma32_zone_size);
+
+	return min(offset + zone_size, memblock_end_of_DRAM());
 }
 
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
@@ -242,6 +250,22 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init setup_dma32_zone(char *p)
+{
+	unsigned long long size = memparse(p, NULL);
+
+	/* DMA32 zone size should never grater than 4G */
+	if (size > SZ_4G)
+		return -EINVAL;
+
+	pr_notice("Setup dma32 zone size to %llu Mb\n", size >> 20);
+	dma32_zone_size = size;
+
+	return 0;
+}
+
+early_param("dma32_size", setup_dma32_zone);
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
 		const char *uname, int depth, void *data)
 {
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-16  7:22 ` Phil Chang
@ 2020-09-16  8:37   ` Christoph Hellwig
  2020-09-16 13:33     ` Phil Chang
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2020-09-16  8:37 UTC (permalink / raw)
  To: Phil Chang
  Cc: linux-arm-kernel, Mark Rutland, Alix Wu, linux-doc,
	Anshuman Khandual, Mauro Carvalho Chehab, Catalin Marinas,
	YJ Chiang, Jonathan Corbet, linux-kernel, linux-mediatek,
	Will Deacon, Mike Rapoport

On Wed, Sep 16, 2020 at 03:22:06PM +0800, Phil Chang wrote:
> this patch allowing the DMA32 zone be configurable in ARM64.

Hell no.  The point of the DMA32 zone is that it is exactly the first
4GiG, and not some random size someone decided without explaining why.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-16  8:37   ` Christoph Hellwig
@ 2020-09-16 13:33     ` Phil Chang
  2020-09-16 14:56       ` Catalin Marinas
  2020-09-24 14:15       ` Phil Chang
  0 siblings, 2 replies; 10+ messages in thread
From: Phil Chang @ 2020-09-16 13:33 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan Corbet, Catalin Marinas, Will Deacon,
	Mauro Carvalho Chehab, Mark Rutland, Anshuman Khandual,
	Phil Chang, YJ Chiang, Alix Wu, Mike Rapoport, linux-doc,
	linux-kernel, linux-mediatek

this patch allowing the DMA32 zone be configurable in ARM64.
For some devices, the main memory split into 2 part due to the memory
architecture, the efficient and less inefficient part.
One of the use case is fine-tune the dma32 size to contain all the
efficient part of memory block on this kind of architecture

Signed-off-by: Alix Wu <alix.wu@mediatek.com>
Signed-off-by: YJ Chiang <yj.chiang@mediatek.com>
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---
Hi

supplement the reason of this usage.

Thanks.

 .../admin-guide/kernel-parameters.txt         |  3 +++
 arch/arm64/include/asm/memory.h               |  2 ++
 arch/arm64/mm/init.c                          | 26 ++++++++++++++++++-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index bdc1f33fd3d1..ef3bc3d4931a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -980,6 +980,9 @@
 			The filter can be disabled or changed to another
 			driver later using sysfs.
 
+	dma32_size=nn[KMG]  [KNL,BOOT,ARM64]
+			Forces the DMA32 zone size of <nn> in MB.
+
 	driver_async_probe=  [KNL]
 			List of driver names to be probed asynchronously.
 			Format: <driver_name1>,<driver_name2>...
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index afa722504bfd..710de08ae8ae 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -175,6 +175,8 @@ extern u64			kimage_vaddr;
 /* the offset between the kernel virtual and physical mappings */
 extern u64			kimage_voffset;
 
+extern phys_addr_t		dma32_zone_size;
+
 static inline unsigned long kaslr_offset(void)
 {
 	return kimage_vaddr - KIMAGE_VADDR;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 481d22c32a2e..fd1b85e131cc 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -60,6 +60,9 @@ EXPORT_SYMBOL(physvirt_offset);
 struct page *vmemmap __ro_after_init;
 EXPORT_SYMBOL(vmemmap);
 
+phys_addr_t dma32_zone_size __ro_after_init;
+EXPORT_SYMBOL(dma32_zone_size);
+
 /*
  * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
  * memory as some devices, namely the Raspberry Pi 4, have peripherals with
@@ -189,7 +192,12 @@ static void __init reserve_elfcorehdr(void)
 static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
 {
 	phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
-	return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
+	phys_addr_t zone_size = (1ULL << zone_bits);
+
+	if (IS_ENABLED(CONFIG_ZONE_DMA32) && zone_bits == 32 && dma32_zone_size)
+		zone_size = min(zone_size, dma32_zone_size);
+
+	return min(offset + zone_size, memblock_end_of_DRAM());
 }
 
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
@@ -242,6 +250,22 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init setup_dma32_zone(char *p)
+{
+	unsigned long long size = memparse(p, NULL);
+
+	/* DMA32 zone size should never grater than 4G */
+	if (size > SZ_4G)
+		return -EINVAL;
+
+	pr_notice("Setup dma32 zone size to %llu Mb\n", size >> 20);
+	dma32_zone_size = size;
+
+	return 0;
+}
+
+early_param("dma32_size", setup_dma32_zone);
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
 		const char *uname, int depth, void *data)
 {
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-16 13:33     ` Phil Chang
@ 2020-09-16 14:56       ` Catalin Marinas
  2020-09-24 14:15       ` Phil Chang
  1 sibling, 0 replies; 10+ messages in thread
From: Catalin Marinas @ 2020-09-16 14:56 UTC (permalink / raw)
  To: Phil Chang
  Cc: linux-arm-kernel, Jonathan Corbet, Will Deacon,
	Mauro Carvalho Chehab, Mark Rutland, Anshuman Khandual,
	YJ Chiang, Alix Wu, Mike Rapoport, linux-doc, linux-kernel,
	linux-mediatek

On Wed, Sep 16, 2020 at 09:33:24PM +0800, Phil Chang wrote:
> this patch allowing the DMA32 zone be configurable in ARM64.
> For some devices, the main memory split into 2 part due to the memory
> architecture, the efficient and less inefficient part.
> One of the use case is fine-tune the dma32 size to contain all the
> efficient part of memory block on this kind of architecture
> 
> Signed-off-by: Alix Wu <alix.wu@mediatek.com>
> Signed-off-by: YJ Chiang <yj.chiang@mediatek.com>
> Signed-off-by: Phil Chang <phil.chang@mediatek.com>
> ---
> Hi
> 
> supplement the reason of this usage.

That's really not a good enough justification to merge such patch. As
Christoph said, DMA32 is defined as addressing the first 4GB of RAM.

Is the memory inefficient (presumably slow) for device or for the CPU?
Maybe you can pretend it's a separate NUMA node for the CPU.
Alternatively, change your device DMA coherent mask and allocate only
from ZONE_DMA (currently first 1GB on arm64).

-- 
Catalin

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-16 13:33     ` Phil Chang
  2020-09-16 14:56       ` Catalin Marinas
@ 2020-09-24 14:15       ` Phil Chang
  2020-09-25  9:11         ` Catalin Marinas
  1 sibling, 1 reply; 10+ messages in thread
From: Phil Chang @ 2020-09-24 14:15 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, Phil Chang, YJ Chiang, Alix Wu, linux-kernel,
	linux-mediatek

Actually, In a embedded system with 3GB memory, the memory bus width is not the same among the 3GB.
(The first 2GB is 48-bit wide, and the latter 1GB is 16-bit wide.)
For memory throughput reason of hardware IPs, we need allocate memory from the first 2GB for
the hardware IPs. And that is why we setup the first 2GB as DMA_ZONE, and use GFP_DMA to allocate
memory from the range.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Re: [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs
  2020-09-24 14:15       ` Phil Chang
@ 2020-09-25  9:11         ` Catalin Marinas
  0 siblings, 0 replies; 10+ messages in thread
From: Catalin Marinas @ 2020-09-25  9:11 UTC (permalink / raw)
  To: Phil Chang
  Cc: linux-arm-kernel, YJ Chiang, Alix Wu, linux-kernel, linux-mediatek

On Thu, Sep 24, 2020 at 10:15:14PM +0800, Phil Chang wrote:
> Actually, In a embedded system with 3GB memory, the memory bus width is not the same among the 3GB.
> (The first 2GB is 48-bit wide, and the latter 1GB is 16-bit wide.)

So I guess that's the data bus width. Devices can still access the whole
memory, though at different throughputs.

Does this narrow data bus apply only to devices or the CPUs are affected
as well?

> For memory throughput reason of hardware IPs, we need allocate memory from the first 2GB for
> the hardware IPs. And that is why we setup the first 2GB as DMA_ZONE, and use GFP_DMA to allocate
> memory from the range.

If it's only a throughput problem, it looks to me more like a NUMA
configuration. I think you can add the first 2GB and the last GB in
separate nodes and define a "numa-node-id" property per device in DT.

-- 
Catalin

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-09-25  9:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-15 15:08 [PATCH] [PATCH] ARM64: Setup DMA32 zone size by bootargs Phil Chang
2020-09-15 16:13 ` Catalin Marinas
2020-09-15 16:18 ` Mike Rapoport
2020-09-15 17:48 ` David Woodhouse
2020-09-16  7:22 ` Phil Chang
2020-09-16  8:37   ` Christoph Hellwig
2020-09-16 13:33     ` Phil Chang
2020-09-16 14:56       ` Catalin Marinas
2020-09-24 14:15       ` Phil Chang
2020-09-25  9:11         ` Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).