iommu.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA
@ 2020-10-14 19:12 Nicolas Saenz Julienne
  2020-10-14 19:12 ` [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init() Nicolas Saenz Julienne
                   ` (7 more replies)
  0 siblings, 8 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel
  Cc: devicetree, linux-acpi, jeremy.linton, linux-mm, iommu,
	linux-rpi-kernel, robin.murphy, linux-arm-kernel

Using two distinct DMA zones turned out to be problematic. Here's an
attempt go back to a saner default.

I tested this on both a RPi4 and QEMU.

---

Changes since v2:
 - Introduce Ard's patch
 - Improve OF dma-ranges parsing function
 - Add unit test for OF function
 - Address small changes
 - Move crashkernel reservation later in boot process

Changes since v1:
 - Parse dma-ranges instead of using machine compatible string

Ard Biesheuvel (1):
  arm64: mm: Set ZONE_DMA size based on early IORT scan

Nicolas Saenz Julienne (7):
  arm64: mm: Move reserve_crashkernel() into mem_init()
  arm64: mm: Move zone_dma_bits initialization into zone_sizes_init()
  of/address: Introduce of_dma_get_max_cpu_address()
  of: unittest: Add test for of_dma_get_max_cpu_address()
  dma-direct: Turn zone_dma_bits default value into a define
  arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges
  mm: Update DMA zones description

 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/mm/init.c               | 20 ++++++------
 drivers/acpi/arm64/iort.c          | 51 ++++++++++++++++++++++++++++++
 drivers/of/address.c               | 42 ++++++++++++++++++++++++
 drivers/of/unittest.c              | 20 ++++++++++++
 include/linux/acpi_iort.h          |  4 +++
 include/linux/dma-direct.h         |  3 ++
 include/linux/mmzone.h             |  5 +--
 include/linux/of.h                 |  7 ++++
 kernel/dma/direct.c                |  2 +-
 10 files changed, 143 insertions(+), 12 deletions(-)

-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init()
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-15  8:40   ` Will Deacon
  2020-10-14 19:12 ` [PATCH v3 2/8] arm64: mm: Move zone_dma_bits initialization into zone_sizes_init() Nicolas Saenz Julienne
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel
  Cc: devicetree, Will Deacon, jeremy.linton, iommu, linux-rpi-kernel,
	robin.murphy, linux-arm-kernel

crashkernel might reserve memory located in ZONE_DMA. We plan to delay
ZONE_DMA's initialization after unflattening the devicetree and ACPI's
boot table initialization, so move it later in the boot process.
Specifically into mem_init(), this is the last place crashkernel will be
able to reserve the memory before the page allocator kicks in and there is
no need to do it earlier.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 arch/arm64/mm/init.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index a53c1e0fb017..1d29f2ca81c7 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -396,8 +396,6 @@ void __init arm64_memblock_init(void)
 	else
 		arm64_dma32_phys_limit = PHYS_MASK + 1;
 
-	reserve_crashkernel();
-
 	reserve_elfcorehdr();
 
 	high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
@@ -518,6 +516,8 @@ void __init mem_init(void)
 	else
 		swiotlb_force = SWIOTLB_NO_FORCE;
 
+	reserve_crashkernel();
+
 	set_max_mapnr(max_pfn - PHYS_PFN_OFFSET);
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 2/8] arm64: mm: Move zone_dma_bits initialization into zone_sizes_init()
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
  2020-10-14 19:12 ` [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init() Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-14 19:12 ` [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address() Nicolas Saenz Julienne
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel
  Cc: devicetree, Will Deacon, jeremy.linton, iommu, linux-rpi-kernel,
	robin.murphy, linux-arm-kernel

zone_dma_bits's initialization happens earlier that it's actually
needed, in arm64_memblock_init(). So move it into the more suitable
zone_sizes_init().

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 arch/arm64/mm/init.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1d29f2ca81c7..ef0ef0087e2c 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -196,6 +196,8 @@ 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
+	zone_dma_bits = ARM64_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
 #ifdef CONFIG_ZONE_DMA32
@@ -386,11 +388,6 @@ void __init arm64_memblock_init(void)
 
 	early_init_fdt_scan_reserved_mem();
 
-	if (IS_ENABLED(CONFIG_ZONE_DMA)) {
-		zone_dma_bits = ARM64_ZONE_DMA_BITS;
-		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
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
  2020-10-14 19:12 ` [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init() Nicolas Saenz Julienne
  2020-10-14 19:12 ` [PATCH v3 2/8] arm64: mm: Move zone_dma_bits initialization into zone_sizes_init() Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-14 22:02   ` Rob Herring
  2020-10-15  5:42   ` Christoph Hellwig
  2020-10-14 19:12 ` [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address() Nicolas Saenz Julienne
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel, Frank Rowand
  Cc: devicetree, jeremy.linton, iommu, linux-rpi-kernel, robin.murphy,
	linux-arm-kernel

Introduce of_dma_get_max_cpu_address(), which provides the highest CPU
physical address addressable by all DMA masters in the system. It's
specially useful for setting memory zones sizes at early boot time.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>

---

Changes since v2:
 - Use PHYS_ADDR_MAX
 - return phys_dma_t
 - Rename function
 - Correct subject
 - Add support to start parsing from an arbitrary device node in order
   for the function to work with unit tests

 drivers/of/address.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/of.h   |  7 +++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index eb9ab4f1e80b..b5a9695aaf82 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -1024,6 +1024,48 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
 }
 #endif /* CONFIG_HAS_DMA */
 
+/**
+ * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA
+ * @np: The node to start searching from or NULL to start from the root
+ *
+ * Gets the highest CPU physical address that is addressable by all DMA masters
+ * in the system (or subtree when np is non-NULL). If no DMA constrained device
+ * is found, it returns PHYS_ADDR_MAX.
+ */
+phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
+{
+	phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
+	struct of_range_parser parser;
+	phys_addr_t subtree_max_addr;
+	struct device_node *child;
+	phys_addr_t cpu_end = 0;
+	struct of_range range;
+	const __be32 *ranges;
+	int len;
+
+	if (!np)
+		np = of_root;
+
+	ranges = of_get_property(np, "dma-ranges", &len);
+	if (ranges && len) {
+		of_dma_range_parser_init(&parser, np);
+		for_each_of_range(&parser, &range)
+			if (range.cpu_addr + range.size > cpu_end)
+				cpu_end = range.cpu_addr + range.size;
+
+		if (max_cpu_addr > cpu_end)
+			max_cpu_addr = cpu_end;
+	}
+
+	for_each_available_child_of_node(np, child) {
+		subtree_max_addr = of_dma_get_max_cpu_address(child);
+		if (max_cpu_addr > subtree_max_addr)
+			max_cpu_addr = subtree_max_addr;
+	}
+
+	return max_cpu_addr;
+}
+
 /**
  * of_dma_is_coherent - Check if device is coherent
  * @np:	device node
diff --git a/include/linux/of.h b/include/linux/of.h
index 481ec0467285..db8db8f2c967 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -558,6 +558,8 @@ int of_map_id(struct device_node *np, u32 id,
 	       const char *map_name, const char *map_mask_name,
 	       struct device_node **target, u32 *id_out);
 
+phys_addr_t of_dma_get_max_cpu_address(struct device_node *np);
+
 #else /* CONFIG_OF */
 
 static inline void of_core_init(void)
@@ -995,6 +997,11 @@ static inline int of_map_id(struct device_node *np, u32 id,
 	return -EINVAL;
 }
 
+static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np)
+{
+	return PHYS_ADDR_MAX;
+}
+
 #define of_match_ptr(_ptr)	NULL
 #define of_match_node(_matches, _node)	NULL
 #endif /* CONFIG_OF */
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address()
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
                   ` (2 preceding siblings ...)
  2020-10-14 19:12 ` [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address() Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-14 22:04   ` Rob Herring
  2020-10-14 19:12 ` [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define Nicolas Saenz Julienne
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel, Frank Rowand
  Cc: devicetree, jeremy.linton, iommu, linux-rpi-kernel, robin.murphy,
	linux-arm-kernel

Introduce a test for of_dma_get_max_cup_address(), it uses the same DT
data as the rest of dma-ranges unit tests.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 drivers/of/unittest.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 06cc988faf78..2cbf2a585c9f 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -869,6 +869,25 @@ static void __init of_unittest_changeset(void)
 #endif
 }
 
+static void __init of_unittest_dma_get_max_cpu_address(void)
+{
+#ifdef CONFIG_HAS_DMA
+	struct device_node *np;
+	phys_addr_t cpu_addr;
+
+	np = of_find_node_by_path("/testcase-data/address-tests");
+	if (!np) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	cpu_addr = of_dma_get_max_cpu_address(np);
+	unittest(cpu_addr == 0x50000000ULL,
+		 "of_dma_get_max_cpu_address: wrong CPU addr %pad (expecting %llx)\n",
+		 &cpu_addr, 0x50000000ULL);
+#endif
+}
+
 static void __init of_unittest_dma_ranges_one(const char *path,
 		u64 expect_dma_addr, u64 expect_paddr)
 {
@@ -3266,6 +3285,7 @@ static int __init of_unittest(void)
 	of_unittest_changeset();
 	of_unittest_parse_interrupts();
 	of_unittest_parse_interrupts_extended();
+	of_unittest_dma_get_max_cpu_address();
 	of_unittest_parse_dma_ranges();
 	of_unittest_pci_dma_ranges();
 	of_unittest_match_node();
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
                   ` (3 preceding siblings ...)
  2020-10-14 19:12 ` [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address() Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-15  5:38   ` Christoph Hellwig
  2020-10-14 19:12 ` [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges Nicolas Saenz Julienne
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel,
	Marek Szyprowski, Robin Murphy
  Cc: linux-arm-kernel, devicetree, jeremy.linton, iommu, linux-rpi-kernel

Set zone_dma_bits default value through a define so as for architectures
to be able to override it with their default value.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 include/linux/dma-direct.h | 3 +++
 kernel/dma/direct.c        | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 18aade195884..e433d90cbacf 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -12,6 +12,9 @@
 #include <linux/mem_encrypt.h>
 #include <linux/swiotlb.h>
 
+#ifndef ZONE_DMA_BITS_DEFAULT
+#define ZONE_DMA_BITS_DEFAULT	24
+#endif
 extern unsigned int zone_dma_bits;
 
 /*
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 06c111544f61..c0d97f536e93 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -20,7 +20,7 @@
  * it for entirely different regions. In that case the arch code needs to
  * override the variable below for dma-direct to work properly.
  */
-unsigned int zone_dma_bits __ro_after_init = 24;
+unsigned int zone_dma_bits __ro_after_init = ZONE_DMA_BITS_DEFAULT;
 
 static inline dma_addr_t phys_to_dma_direct(struct device *dev,
 		phys_addr_t phys)
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
                   ` (4 preceding siblings ...)
  2020-10-14 19:12 ` [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-15  5:39   ` Christoph Hellwig
  2020-10-14 19:12 ` [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan Nicolas Saenz Julienne
  2020-10-14 19:12 ` [PATCH v3 8/8] mm: Update DMA zones description Nicolas Saenz Julienne
  7 siblings, 1 reply; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel
  Cc: devicetree, Will Deacon, jeremy.linton, iommu, linux-rpi-kernel,
	robin.murphy, linux-arm-kernel

We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
incorporating masters that can address less than 32 bits of DMA, in
particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
peripherals that can only address up to 1 GB (and its PCIe host
bridge can only access the bottom 3 GB)

The DMA layer also needs to be able to allocate memory that is
guaranteed to meet those DMA constraints, for bounce buffering as well
as allocating the backing for consistent mappings. This is why the 1 GB
ZONE_DMA was introduced recently. Unfortunately, it turns out the having
a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes problems with kdump, and
potentially in other places where allocations cannot cross zone
boundaries. Therefore, we should avoid having two separate DMA zones
when possible.

So, with the help of of_dma_get_max_cpu_address() get the topmost
physical address accessible to all DMA masters in system and use that
information to fine-tune ZONE_DMA's size. In the absence of addressing
limited masters ZONE_DMA will span the whole 32-bit address space,
otherwise, in the case of the Raspberry Pi 4 it'll only span the 30-bit
address space, and have ZONE_DMA32 cover the rest of the 32-bit address
space.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>

---

Changes since v2:
 - Updated commit log by shamelessly copying Ard's ACPI counterpart commit log

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

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index fce8cbecd6bc..c09d3f1a9a6b 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -97,6 +97,7 @@
 
 extern phys_addr_t arm64_dma_phys_limit;
 #define ARCH_LOW_ADDRESS_LIMIT	(arm64_dma_phys_limit - 1)
+#define ZONE_DMA_BITS_DEFAULT	32
 
 struct debug_info {
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ef0ef0087e2c..97b0d2768349 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -42,8 +42,6 @@
 #include <asm/tlb.h>
 #include <asm/alternative.h>
 
-#define ARM64_ZONE_DMA_BITS	30
-
 /*
  * We need to be able to catch inadvertent references to memstart_addr
  * that occur (potentially in generic code) before arm64_memblock_init()
@@ -196,7 +194,8 @@ 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
-	zone_dma_bits = ARM64_ZONE_DMA_BITS;
+	zone_dma_bits = min(zone_dma_bits,
+			    (unsigned int)ilog2(of_dma_get_max_cpu_address(NULL)));
 	arm64_dma_phys_limit = max_zone_phys(zone_dma_bits);
 	max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
 #endif
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
                   ` (5 preceding siblings ...)
  2020-10-14 19:12 ` [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-15 10:31   ` Lorenzo Pieralisi
  2020-10-15 14:26   ` Hanjun Guo
  2020-10-14 19:12 ` [PATCH v3 8/8] mm: Update DMA zones description Nicolas Saenz Julienne
  7 siblings, 2 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel,
	Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla
  Cc: devicetree, linux-acpi, Anshuman Khandual, Will Deacon,
	Rafael J. Wysocki, jeremy.linton, iommu, linux-rpi-kernel,
	robin.murphy, linux-arm-kernel, Len Brown

From: Ard Biesheuvel <ardb@kernel.org>

We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
incorporating masters that can address less than 32 bits of DMA, in
particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
peripherals that can only address up to 1 GB (and its PCIe host
bridge can only access the bottom 3 GB)

Instructing the DMA layer about these limitations is straight-forward,
even though we had to fix some issues regarding memory limits set in
the IORT for named components, and regarding the handling of ACPI _DMA
methods. However, the DMA layer also needs to be able to allocate
memory that is guaranteed to meet those DMA constraints, for bounce
buffering as well as allocating the backing for consistent mappings.

This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
problems with kdump, and potentially in other places where allocations
cannot cross zone boundaries. Therefore, we should avoid having two
separate DMA zones when possible.

So let's do an early scan of the IORT, and only create the ZONE_DMA
if we encounter any devices that need it. This puts the burden on
the firmware to describe such limitations in the IORT, which may be
redundant (and less precise) if _DMA methods are also being provided.
However, it should be noted that this situation is highly unusual for
arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
the _DMA method if implemented, and so we will not lose the ability to
perform streaming DMA outside the ZONE_DMA if the _DMA method permits
it.

Cc: Jeremy Linton <jeremy.linton@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
[nsaenz: Rebased, removed documentation change, warnings and add
declaration in acpi_iort.h]
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 arch/arm64/mm/init.c      |  6 +++++
 drivers/acpi/arm64/iort.c | 51 +++++++++++++++++++++++++++++++++++++++
 include/linux/acpi_iort.h |  4 +++
 3 files changed, 61 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 97b0d2768349..f321761eedb2 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -29,6 +29,7 @@
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 #include <linux/hugetlb.h>
+#include <linux/acpi_iort.h>
 
 #include <asm/boot.h>
 #include <asm/fixmap.h>
@@ -196,6 +197,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 #ifdef CONFIG_ZONE_DMA
 	zone_dma_bits = min(zone_dma_bits,
 			    (unsigned int)ilog2(of_dma_get_max_cpu_address(NULL)));
+
+	if (IS_ENABLED(CONFIG_ACPI))
+		zone_dma_bits = min(zone_dma_bits,
+				    acpi_iort_get_zone_dma_size());
+
 	arm64_dma_phys_limit = max_zone_phys(zone_dma_bits);
 	max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
 #endif
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 9929ff50c0c0..8f530bf3c03b 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1718,3 +1718,54 @@ void __init acpi_iort_init(void)
 
 	iort_init_platform_devices();
 }
+
+#ifdef CONFIG_ZONE_DMA
+/*
+ * Check the IORT whether any devices exist whose DMA mask is < 32 bits.
+ * If so, return the smallest value encountered, or 32 otherwise.
+ */
+unsigned int __init acpi_iort_get_zone_dma_size(void)
+{
+	struct acpi_table_iort *iort;
+	struct acpi_iort_node *node, *end;
+	acpi_status status;
+	u8 limit = 32;
+	int i;
+
+	if (acpi_disabled)
+		return limit;
+
+	status = acpi_get_table(ACPI_SIG_IORT, 0,
+				(struct acpi_table_header **)&iort);
+	if (ACPI_FAILURE(status))
+		return limit;
+
+	node = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->node_offset);
+	end = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->header.length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		if (node >= end)
+			break;
+
+		switch (node->type) {
+			struct acpi_iort_named_component *ncomp;
+			struct acpi_iort_root_complex *rc;
+
+		case ACPI_IORT_NODE_NAMED_COMPONENT:
+			ncomp = (struct acpi_iort_named_component *)node->node_data;
+			if (ncomp->memory_address_limit)
+				limit = min(limit, ncomp->memory_address_limit);
+			break;
+
+		case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
+			rc = (struct acpi_iort_root_complex *)node->node_data;
+			if (rc->memory_address_limit)
+				limit = min(limit, rc->memory_address_limit);
+			break;
+		}
+		node = ACPI_ADD_PTR(struct acpi_iort_node, node, node->length);
+	}
+	acpi_put_table(&iort->header);
+	return limit;
+}
+#endif
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 20a32120bb88..7d2e184f0d4d 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -38,6 +38,7 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
 const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
 						const u32 *id_in);
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
+unsigned int acpi_iort_get_zone_dma_size(void);
 #else
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_id(struct device *dev, u32 id)
@@ -55,6 +56,9 @@ static inline const struct iommu_ops *iort_iommu_configure_id(
 static inline
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 { return 0; }
+
+static inline unsigned int acpi_iort_get_zone_dma_size(void)
+{ return 32; }
 #endif
 
 #endif /* __ACPI_IORT_H__ */
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* [PATCH v3 8/8] mm: Update DMA zones description
  2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
                   ` (6 preceding siblings ...)
  2020-10-14 19:12 ` [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan Nicolas Saenz Julienne
@ 2020-10-14 19:12 ` Nicolas Saenz Julienne
  2020-10-15  5:40   ` Christoph Hellwig
  7 siblings, 1 reply; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-14 19:12 UTC (permalink / raw)
  To: robh+dt, catalin.marinas, hch, ardb, linux-kernel, Andrew Morton
  Cc: devicetree, linux-mm, jeremy.linton, iommu, linux-rpi-kernel,
	robin.murphy, linux-arm-kernel

The default behavior for arm64 changed, so reflect that.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 include/linux/mmzone.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index fb3bf696c05e..4ee2306351b9 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -363,8 +363,9 @@ enum zone_type {
 	 *  - arm only uses ZONE_DMA, the size, up to 4G, may vary depending on
 	 *    the specific device.
 	 *
-	 *  - arm64 has a fixed 1G ZONE_DMA and ZONE_DMA32 for the rest of the
-	 *    lower 4G.
+	 *  - arm64 uses a single 4GB ZONE_DMA, except on the Raspberry Pi 4,
+	 *    in which ZONE_DMA covers the first GB and ZONE_DMA32 the rest of
+	 *    the lower 4GB.
 	 *
 	 *  - powerpc only uses ZONE_DMA, the size, up to 2G, may vary
 	 *    depending on the specific device.
-- 
2.28.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-14 19:12 ` [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address() Nicolas Saenz Julienne
@ 2020-10-14 22:02   ` Rob Herring
  2020-10-15  6:56     ` Ard Biesheuvel
  2020-10-15  8:54     ` Nicolas Saenz Julienne
  2020-10-15  5:42   ` Christoph Hellwig
  1 sibling, 2 replies; 35+ messages in thread
From: Rob Herring @ 2020-10-14 22:02 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, Frank Rowand, Catalin Marinas, linux-kernel,
	Jeremy Linton, Ard Biesheuvel, Linux IOMMU,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> Introduce of_dma_get_max_cpu_address(), which provides the highest CPU
> physical address addressable by all DMA masters in the system. It's
> specially useful for setting memory zones sizes at early boot time.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
>
> ---
>
> Changes since v2:
>  - Use PHYS_ADDR_MAX
>  - return phys_dma_t
>  - Rename function
>  - Correct subject
>  - Add support to start parsing from an arbitrary device node in order
>    for the function to work with unit tests
>
>  drivers/of/address.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of.h   |  7 +++++++
>  2 files changed, 49 insertions(+)
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index eb9ab4f1e80b..b5a9695aaf82 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -1024,6 +1024,48 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
>  }
>  #endif /* CONFIG_HAS_DMA */
>
> +/**
> + * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA
> + * @np: The node to start searching from or NULL to start from the root
> + *
> + * Gets the highest CPU physical address that is addressable by all DMA masters
> + * in the system (or subtree when np is non-NULL). If no DMA constrained device
> + * is found, it returns PHYS_ADDR_MAX.
> + */
> +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> +{
> +       phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;

One issue with using phys_addr_t is it may be 32-bit even though the
DT is 64-bit addresses. LPAE capable system with LPAE disabled. Maybe
the truncation is fine here? Maybe not.

> +       struct of_range_parser parser;
> +       phys_addr_t subtree_max_addr;
> +       struct device_node *child;
> +       phys_addr_t cpu_end = 0;
> +       struct of_range range;
> +       const __be32 *ranges;
> +       int len;
> +
> +       if (!np)
> +               np = of_root;
> +
> +       ranges = of_get_property(np, "dma-ranges", &len);

I'm not really following why you changed the algorithm here. You're
skipping disabled nodes which is good. Was there some other reason?

> +       if (ranges && len) {
> +               of_dma_range_parser_init(&parser, np);
> +               for_each_of_range(&parser, &range)
> +                       if (range.cpu_addr + range.size > cpu_end)
> +                               cpu_end = range.cpu_addr + range.size;
> +
> +               if (max_cpu_addr > cpu_end)
> +                       max_cpu_addr = cpu_end;
> +       }
> +
> +       for_each_available_child_of_node(np, child) {
> +               subtree_max_addr = of_dma_get_max_cpu_address(child);
> +               if (max_cpu_addr > subtree_max_addr)
> +                       max_cpu_addr = subtree_max_addr;
> +       }
> +
> +       return max_cpu_addr;
> +}
> +
>  /**
>   * of_dma_is_coherent - Check if device is coherent
>   * @np:        device node
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 481ec0467285..db8db8f2c967 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -558,6 +558,8 @@ int of_map_id(struct device_node *np, u32 id,
>                const char *map_name, const char *map_mask_name,
>                struct device_node **target, u32 *id_out);
>
> +phys_addr_t of_dma_get_max_cpu_address(struct device_node *np);
> +
>  #else /* CONFIG_OF */
>
>  static inline void of_core_init(void)
> @@ -995,6 +997,11 @@ static inline int of_map_id(struct device_node *np, u32 id,
>         return -EINVAL;
>  }
>
> +static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np)
> +{
> +       return PHYS_ADDR_MAX;
> +}
> +
>  #define of_match_ptr(_ptr)     NULL
>  #define of_match_node(_matches, _node) NULL
>  #endif /* CONFIG_OF */
> --
> 2.28.0
>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address()
  2020-10-14 19:12 ` [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address() Nicolas Saenz Julienne
@ 2020-10-14 22:04   ` Rob Herring
  2020-10-15  9:51     ` Nicolas Saenz Julienne
  0 siblings, 1 reply; 35+ messages in thread
From: Rob Herring @ 2020-10-14 22:04 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, Frank Rowand, Catalin Marinas, linux-kernel,
	Jeremy Linton, Ard Biesheuvel, Linux IOMMU,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> Introduce a test for of_dma_get_max_cup_address(), it uses the same DT
> data as the rest of dma-ranges unit tests.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> ---
>  drivers/of/unittest.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
> index 06cc988faf78..2cbf2a585c9f 100644
> --- a/drivers/of/unittest.c
> +++ b/drivers/of/unittest.c
> @@ -869,6 +869,25 @@ static void __init of_unittest_changeset(void)
>  #endif
>  }
>
> +static void __init of_unittest_dma_get_max_cpu_address(void)
> +{
> +#ifdef CONFIG_HAS_DMA

Can't the unittest run without this? I run the unittests under UML.

> +       struct device_node *np;
> +       phys_addr_t cpu_addr;
> +
> +       np = of_find_node_by_path("/testcase-data/address-tests");
> +       if (!np) {
> +               pr_err("missing testcase data\n");
> +               return;
> +       }
> +
> +       cpu_addr = of_dma_get_max_cpu_address(np);
> +       unittest(cpu_addr == 0x50000000ULL,
> +                "of_dma_get_max_cpu_address: wrong CPU addr %pad (expecting %llx)\n",
> +                &cpu_addr, 0x50000000ULL);
> +#endif
> +}
> +
>  static void __init of_unittest_dma_ranges_one(const char *path,
>                 u64 expect_dma_addr, u64 expect_paddr)
>  {
> @@ -3266,6 +3285,7 @@ static int __init of_unittest(void)
>         of_unittest_changeset();
>         of_unittest_parse_interrupts();
>         of_unittest_parse_interrupts_extended();
> +       of_unittest_dma_get_max_cpu_address();
>         of_unittest_parse_dma_ranges();
>         of_unittest_pci_dma_ranges();
>         of_unittest_match_node();
> --
> 2.28.0
>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define
  2020-10-14 19:12 ` [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define Nicolas Saenz Julienne
@ 2020-10-15  5:38   ` Christoph Hellwig
  2020-10-15 10:05     ` Nicolas Saenz Julienne
  0 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2020-10-15  5:38 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, catalin.marinas, linux-kernel, jeremy.linton, ardb,
	iommu, robh+dt, linux-rpi-kernel, Robin Murphy, hch,
	linux-arm-kernel

On Wed, Oct 14, 2020 at 09:12:07PM +0200, Nicolas Saenz Julienne wrote:
> Set zone_dma_bits default value through a define so as for architectures
> to be able to override it with their default value.

Architectures can do that already by assigning a value to zone_dma_bits
at runtime.  I really do not want to add the extra clutter.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges
  2020-10-14 19:12 ` [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges Nicolas Saenz Julienne
@ 2020-10-15  5:39   ` Christoph Hellwig
  2020-10-15 10:05     ` Nicolas Saenz Julienne
  0 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2020-10-15  5:39 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, Will Deacon, catalin.marinas, linux-kernel,
	jeremy.linton, ardb, iommu, robh+dt, linux-rpi-kernel,
	robin.murphy, hch, linux-arm-kernel

On Wed, Oct 14, 2020 at 09:12:08PM +0200, Nicolas Saenz Julienne wrote:
> +	zone_dma_bits = min(zone_dma_bits,
> +			    (unsigned int)ilog2(of_dma_get_max_cpu_address(NULL)));

Plase avoid pointlessly long lines.  Especially if it is completely trivial
by using either min_t or not overindenting like here.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 8/8] mm: Update DMA zones description
  2020-10-14 19:12 ` [PATCH v3 8/8] mm: Update DMA zones description Nicolas Saenz Julienne
@ 2020-10-15  5:40   ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-10-15  5:40 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, catalin.marinas, linux-kernel, jeremy.linton, ardb,
	linux-mm, iommu, robh+dt, linux-rpi-kernel, Andrew Morton,
	robin.murphy, hch, linux-arm-kernel

On Wed, Oct 14, 2020 at 09:12:10PM +0200, Nicolas Saenz Julienne wrote:
> The default behavior for arm64 changed, so reflect that.
> 
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  include/linux/mmzone.h | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index fb3bf696c05e..4ee2306351b9 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -363,8 +363,9 @@ enum zone_type {
>  	 *  - arm only uses ZONE_DMA, the size, up to 4G, may vary depending on
>  	 *    the specific device.
>  	 *
> -	 *  - arm64 has a fixed 1G ZONE_DMA and ZONE_DMA32 for the rest of the
> -	 *    lower 4G.
> +	 *  - arm64 uses a single 4GB ZONE_DMA, except on the Raspberry Pi 4,
> +	 *    in which ZONE_DMA covers the first GB and ZONE_DMA32 the rest of
> +	 *    the lower 4GB.

Honestly I think this comment just needs to go away.  We can't really list
every setup in a comment in common code.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-14 19:12 ` [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address() Nicolas Saenz Julienne
  2020-10-14 22:02   ` Rob Herring
@ 2020-10-15  5:42   ` Christoph Hellwig
  2020-10-15 10:03     ` Nicolas Saenz Julienne
  2020-10-16 13:19     ` Rob Herring
  1 sibling, 2 replies; 35+ messages in thread
From: Christoph Hellwig @ 2020-10-15  5:42 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, catalin.marinas, linux-kernel, jeremy.linton, ardb,
	iommu, robh+dt, linux-rpi-kernel, Frank Rowand, hch,
	linux-arm-kernel, robin.murphy

> +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> +{
> +	phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
> +	struct of_range_parser parser;
> +	phys_addr_t subtree_max_addr;
> +	struct device_node *child;
> +	phys_addr_t cpu_end = 0;
> +	struct of_range range;
> +	const __be32 *ranges;
> +	int len;
> +
> +	if (!np)
> +		np = of_root;

Requiring of_root to be passed explicitly would seem more natural
to me than the magic NULL argument.  There doesn't seem to be any
precedent for that kind of calling convention either.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-14 22:02   ` Rob Herring
@ 2020-10-15  6:56     ` Ard Biesheuvel
  2020-10-15  9:16       ` Nicolas Saenz Julienne
  2020-10-15  8:54     ` Nicolas Saenz Julienne
  1 sibling, 1 reply; 35+ messages in thread
From: Ard Biesheuvel @ 2020-10-15  6:56 UTC (permalink / raw)
  To: Rob Herring
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Frank Rowand, Catalin Marinas, linux-kernel, Jeremy Linton,
	Linux IOMMU, linux-arm-kernel, Robin Murphy, Christoph Hellwig,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

On Thu, 15 Oct 2020 at 00:03, Rob Herring <robh+dt@kernel.org> wrote:
>
> On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
> <nsaenzjulienne@suse.de> wrote:
> >
> > Introduce of_dma_get_max_cpu_address(), which provides the highest CPU
> > physical address addressable by all DMA masters in the system. It's
> > specially useful for setting memory zones sizes at early boot time.
> >
> > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> >
> > ---
> >
> > Changes since v2:
> >  - Use PHYS_ADDR_MAX
> >  - return phys_dma_t
> >  - Rename function
> >  - Correct subject
> >  - Add support to start parsing from an arbitrary device node in order
> >    for the function to work with unit tests
> >
> >  drivers/of/address.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/of.h   |  7 +++++++
> >  2 files changed, 49 insertions(+)
> >
> > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > index eb9ab4f1e80b..b5a9695aaf82 100644
> > --- a/drivers/of/address.c
> > +++ b/drivers/of/address.c
> > @@ -1024,6 +1024,48 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
> >  }
> >  #endif /* CONFIG_HAS_DMA */
> >
> > +/**
> > + * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA
> > + * @np: The node to start searching from or NULL to start from the root
> > + *
> > + * Gets the highest CPU physical address that is addressable by all DMA masters
> > + * in the system (or subtree when np is non-NULL). If no DMA constrained device
> > + * is found, it returns PHYS_ADDR_MAX.
> > + */
> > +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> > +{
> > +       phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
>
> One issue with using phys_addr_t is it may be 32-bit even though the
> DT is 64-bit addresses. LPAE capable system with LPAE disabled. Maybe
> the truncation is fine here? Maybe not.
>

PHYS_ADDR_MAX is the max addressable CPU address on the system, and so
it makes sense to use it for the return type, and for the preliminary
return value: this is actually what /prevents/ truncation, because we
will only overwrite max_cpu_addr if the new u64 value is lower.


> > +       struct of_range_parser parser;
> > +       phys_addr_t subtree_max_addr;
> > +       struct device_node *child;
> > +       phys_addr_t cpu_end = 0;
> > +       struct of_range range;
> > +       const __be32 *ranges;
> > +       int len;
> > +
> > +       if (!np)
> > +               np = of_root;
> > +
> > +       ranges = of_get_property(np, "dma-ranges", &len);
>
> I'm not really following why you changed the algorithm here. You're
> skipping disabled nodes which is good. Was there some other reason?
>
> > +       if (ranges && len) {
> > +               of_dma_range_parser_init(&parser, np);
> > +               for_each_of_range(&parser, &range)
> > +                       if (range.cpu_addr + range.size > cpu_end)
> > +                               cpu_end = range.cpu_addr + range.size;
> > +
> > +               if (max_cpu_addr > cpu_end)
> > +                       max_cpu_addr = cpu_end;
> > +       }
> > +
> > +       for_each_available_child_of_node(np, child) {
> > +               subtree_max_addr = of_dma_get_max_cpu_address(child);
> > +               if (max_cpu_addr > subtree_max_addr)
> > +                       max_cpu_addr = subtree_max_addr;
> > +       }
> > +
> > +       return max_cpu_addr;
> > +}
> > +
> >  /**
> >   * of_dma_is_coherent - Check if device is coherent
> >   * @np:        device node
> > diff --git a/include/linux/of.h b/include/linux/of.h
> > index 481ec0467285..db8db8f2c967 100644
> > --- a/include/linux/of.h
> > +++ b/include/linux/of.h
> > @@ -558,6 +558,8 @@ int of_map_id(struct device_node *np, u32 id,
> >                const char *map_name, const char *map_mask_name,
> >                struct device_node **target, u32 *id_out);
> >
> > +phys_addr_t of_dma_get_max_cpu_address(struct device_node *np);
> > +
> >  #else /* CONFIG_OF */
> >
> >  static inline void of_core_init(void)
> > @@ -995,6 +997,11 @@ static inline int of_map_id(struct device_node *np, u32 id,
> >         return -EINVAL;
> >  }
> >
> > +static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np)
> > +{
> > +       return PHYS_ADDR_MAX;
> > +}
> > +
> >  #define of_match_ptr(_ptr)     NULL
> >  #define of_match_node(_matches, _node) NULL
> >  #endif /* CONFIG_OF */
> > --
> > 2.28.0
> >
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init()
  2020-10-14 19:12 ` [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init() Nicolas Saenz Julienne
@ 2020-10-15  8:40   ` Will Deacon
  2020-10-15  8:55     ` Nicolas Saenz Julienne
  0 siblings, 1 reply; 35+ messages in thread
From: Will Deacon @ 2020-10-15  8:40 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, catalin.marinas, linux-kernel, jeremy.linton, ardb,
	iommu, robh+dt, linux-rpi-kernel, robin.murphy, hch,
	linux-arm-kernel

On Wed, Oct 14, 2020 at 09:12:03PM +0200, Nicolas Saenz Julienne wrote:
> crashkernel might reserve memory located in ZONE_DMA. We plan to delay
> ZONE_DMA's initialization after unflattening the devicetree and ACPI's
> boot table initialization, so move it later in the boot process.
> Specifically into mem_init(), this is the last place crashkernel will be
> able to reserve the memory before the page allocator kicks in and there is
> no need to do it earlier.
> 
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> ---
>  arch/arm64/mm/init.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Please can you cc me on the whole series next time? I know different
maintainers have different preferences here, but I find it much easier to
figure out what's happening when I can see all of the changes together.

Thanks,

Will
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-14 22:02   ` Rob Herring
  2020-10-15  6:56     ` Ard Biesheuvel
@ 2020-10-15  8:54     ` Nicolas Saenz Julienne
  1 sibling, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15  8:54 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Frank Rowand, Catalin Marinas, linux-kernel,
	Jeremy Linton, Ard Biesheuvel, Linux IOMMU,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1435 bytes --]

On Wed, 2020-10-14 at 17:02 -0500, Rob Herring wrote:
> On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
> <nsaenzjulienne@suse.de> wrote:
> > Introduce of_dma_get_max_cpu_address(), which provides the highest CPU
> > physical address addressable by all DMA masters in the system. It's
> > specially useful for setting memory zones sizes at early boot time.
> > 
> > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > 
> > ---

[...]

> > +       struct of_range_parser parser;
> > +       phys_addr_t subtree_max_addr;
> > +       struct device_node *child;
> > +       phys_addr_t cpu_end = 0;
> > +       struct of_range range;
> > +       const __be32 *ranges;
> > +       int len;
> > +
> > +       if (!np)
> > +               np = of_root;
> > +
> > +       ranges = of_get_property(np, "dma-ranges", &len);
> 
> I'm not really following why you changed the algorithm here. You're
> skipping disabled nodes which is good. Was there some other reason?

Yes, it's a little more complex. But I had to change it in order to be able to
start parsing down from an arbitrary device node, which is needed for the unit
tests.

for_each_of_allnodes() and friends will traverse the whole tree, regardless of
the starting point. I couldn't find a similar function that would just iterate
over a subsection of the tree, so I went with this recursive approach.

Regards,
Nicolas


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init()
  2020-10-15  8:40   ` Will Deacon
@ 2020-10-15  8:55     ` Nicolas Saenz Julienne
  0 siblings, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15  8:55 UTC (permalink / raw)
  To: Will Deacon
  Cc: devicetree, catalin.marinas, linux-kernel, jeremy.linton, ardb,
	iommu, robh+dt, linux-rpi-kernel, robin.murphy, hch,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 979 bytes --]

On Thu, 2020-10-15 at 09:40 +0100, Will Deacon wrote:
> On Wed, Oct 14, 2020 at 09:12:03PM +0200, Nicolas Saenz Julienne wrote:
> > crashkernel might reserve memory located in ZONE_DMA. We plan to delay
> > ZONE_DMA's initialization after unflattening the devicetree and ACPI's
> > boot table initialization, so move it later in the boot process.
> > Specifically into mem_init(), this is the last place crashkernel will be
> > able to reserve the memory before the page allocator kicks in and there is
> > no need to do it earlier.
> > 
> > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > ---
> >  arch/arm64/mm/init.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> Please can you cc me on the whole series next time? I know different
> maintainers have different preferences here, but I find it much easier to
> figure out what's happening when I can see all of the changes together.

Will do.

Regards,
Nicolas



[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-15  6:56     ` Ard Biesheuvel
@ 2020-10-15  9:16       ` Nicolas Saenz Julienne
  2020-10-15  9:18         ` Ard Biesheuvel
  0 siblings, 1 reply; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15  9:16 UTC (permalink / raw)
  To: Ard Biesheuvel, Rob Herring
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Frank Rowand, Catalin Marinas, linux-kernel, Jeremy Linton,
	Linux IOMMU, moderated list:BROADCOM BCM2835 ARM ARCHITECTURE,
	Robin Murphy, Christoph Hellwig, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 3744 bytes --]

On Thu, 2020-10-15 at 08:56 +0200, Ard Biesheuvel wrote:
> On Thu, 15 Oct 2020 at 00:03, Rob Herring <robh+dt@kernel.org> wrote:
> > On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
> > <nsaenzjulienne@suse.de> wrote:
> > > Introduce of_dma_get_max_cpu_address(), which provides the highest CPU
> > > physical address addressable by all DMA masters in the system. It's
> > > specially useful for setting memory zones sizes at early boot time.
> > > 
> > > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > > 
> > > ---
> > > 
> > > Changes since v2:
> > >  - Use PHYS_ADDR_MAX
> > >  - return phys_dma_t
> > >  - Rename function
> > >  - Correct subject
> > >  - Add support to start parsing from an arbitrary device node in order
> > >    for the function to work with unit tests
> > > 
> > >  drivers/of/address.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> > >  include/linux/of.h   |  7 +++++++
> > >  2 files changed, 49 insertions(+)
> > > 
> > > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > > index eb9ab4f1e80b..b5a9695aaf82 100644
> > > --- a/drivers/of/address.c
> > > +++ b/drivers/of/address.c
> > > @@ -1024,6 +1024,48 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
> > >  }
> > >  #endif /* CONFIG_HAS_DMA */
> > > 
> > > +/**
> > > + * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA
> > > + * @np: The node to start searching from or NULL to start from the root
> > > + *
> > > + * Gets the highest CPU physical address that is addressable by all DMA masters
> > > + * in the system (or subtree when np is non-NULL). If no DMA constrained device
> > > + * is found, it returns PHYS_ADDR_MAX.
> > > + */
> > > +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> > > +{
> > > +       phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
> > 
> > One issue with using phys_addr_t is it may be 32-bit even though the
> > DT is 64-bit addresses. LPAE capable system with LPAE disabled. Maybe
> > the truncation is fine here? Maybe not.
> > 
> 
> PHYS_ADDR_MAX is the max addressable CPU address on the system, and so
> it makes sense to use it for the return type, and for the preliminary
> return value: this is actually what /prevents/ truncation, because we
> will only overwrite max_cpu_addr if the new u64 value is lower.
> 

Actually I now see how things might go south.

> > > +       if (ranges && len) {
> > > +               of_dma_range_parser_init(&parser, np);
> > > +               for_each_of_range(&parser, &range)
> > > +                       if (range.cpu_addr + range.size > cpu_end)
> > > +                               cpu_end = range.cpu_addr + range.size;

If cpu_end hits 0x1_00000000, it'll overflow to 0. This is possible on 32-bit
systems (LPAE or not). And something similar might happen on LPAE disabled
systems.

I could add some extra logic, something like:

	/* We overflowed */
	if (cpu_end < range.cpu_addr)
		cpu_end = PHYS_ADDR_MAX;

Which is not perfect but will cover most sensible cases.

Or simply deal internally in u64s, and upon returning, check if "max_cpu_addr"
falls higher than PHYS_ADDR_MAX.

> > > +
> > > +               if (max_cpu_addr > cpu_end)
> > > +                       max_cpu_addr = cpu_end;
> > > +       }
> > > +
> > > +       for_each_available_child_of_node(np, child) {
> > > +               subtree_max_addr = of_dma_get_max_cpu_address(child);
> > > +               if (max_cpu_addr > subtree_max_addr)
> > > +                       max_cpu_addr = subtree_max_addr;
> > > +       }
> > > +
> > > +       return max_cpu_addr;
> > > +}

Regards,
Nicolas


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-15  9:16       ` Nicolas Saenz Julienne
@ 2020-10-15  9:18         ` Ard Biesheuvel
  0 siblings, 0 replies; 35+ messages in thread
From: Ard Biesheuvel @ 2020-10-15  9:18 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Catalin Marinas, Robin Murphy, Jeremy Linton, linux-kernel,
	Linux IOMMU, Rob Herring,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, Frank Rowand,
	Christoph Hellwig, linux-arm-kernel

On Thu, 15 Oct 2020 at 11:16, Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> On Thu, 2020-10-15 at 08:56 +0200, Ard Biesheuvel wrote:
> > On Thu, 15 Oct 2020 at 00:03, Rob Herring <robh+dt@kernel.org> wrote:
> > > On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
> > > <nsaenzjulienne@suse.de> wrote:
> > > > Introduce of_dma_get_max_cpu_address(), which provides the highest CPU
> > > > physical address addressable by all DMA masters in the system. It's
> > > > specially useful for setting memory zones sizes at early boot time.
> > > >
> > > > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > > >
> > > > ---
> > > >
> > > > Changes since v2:
> > > >  - Use PHYS_ADDR_MAX
> > > >  - return phys_dma_t
> > > >  - Rename function
> > > >  - Correct subject
> > > >  - Add support to start parsing from an arbitrary device node in order
> > > >    for the function to work with unit tests
> > > >
> > > >  drivers/of/address.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> > > >  include/linux/of.h   |  7 +++++++
> > > >  2 files changed, 49 insertions(+)
> > > >
> > > > diff --git a/drivers/of/address.c b/drivers/of/address.c
> > > > index eb9ab4f1e80b..b5a9695aaf82 100644
> > > > --- a/drivers/of/address.c
> > > > +++ b/drivers/of/address.c
> > > > @@ -1024,6 +1024,48 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
> > > >  }
> > > >  #endif /* CONFIG_HAS_DMA */
> > > >
> > > > +/**
> > > > + * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA
> > > > + * @np: The node to start searching from or NULL to start from the root
> > > > + *
> > > > + * Gets the highest CPU physical address that is addressable by all DMA masters
> > > > + * in the system (or subtree when np is non-NULL). If no DMA constrained device
> > > > + * is found, it returns PHYS_ADDR_MAX.
> > > > + */
> > > > +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> > > > +{
> > > > +       phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
> > >
> > > One issue with using phys_addr_t is it may be 32-bit even though the
> > > DT is 64-bit addresses. LPAE capable system with LPAE disabled. Maybe
> > > the truncation is fine here? Maybe not.
> > >
> >
> > PHYS_ADDR_MAX is the max addressable CPU address on the system, and so
> > it makes sense to use it for the return type, and for the preliminary
> > return value: this is actually what /prevents/ truncation, because we
> > will only overwrite max_cpu_addr if the new u64 value is lower.
> >
>
> Actually I now see how things might go south.
>
> > > > +       if (ranges && len) {
> > > > +               of_dma_range_parser_init(&parser, np);
> > > > +               for_each_of_range(&parser, &range)
> > > > +                       if (range.cpu_addr + range.size > cpu_end)
> > > > +                               cpu_end = range.cpu_addr + range.size;
>
> If cpu_end hits 0x1_00000000, it'll overflow to 0. This is possible on 32-bit
> systems (LPAE or not). And something similar might happen on LPAE disabled
> systems.
>
> I could add some extra logic, something like:
>
>         /* We overflowed */
>         if (cpu_end < range.cpu_addr)
>                 cpu_end = PHYS_ADDR_MAX;
>
> Which is not perfect but will cover most sensible cases.
>
> Or simply deal internally in u64s, and upon returning, check if "max_cpu_addr"
> falls higher than PHYS_ADDR_MAX.
>

Just use a u64 for cpu_end

> > > > +
> > > > +               if (max_cpu_addr > cpu_end)
> > > > +                       max_cpu_addr = cpu_end;

... then this comparison and assignment will work as expected.

> > > > +       }
> > > > +
> > > > +       for_each_available_child_of_node(np, child) {
> > > > +               subtree_max_addr = of_dma_get_max_cpu_address(child);
> > > > +               if (max_cpu_addr > subtree_max_addr)
> > > > +                       max_cpu_addr = subtree_max_addr;
> > > > +       }
> > > > +
> > > > +       return max_cpu_addr;
> > > > +}
>
> Regards,
> Nicolas
>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address()
  2020-10-14 22:04   ` Rob Herring
@ 2020-10-15  9:51     ` Nicolas Saenz Julienne
  0 siblings, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15  9:51 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Frank Rowand, Catalin Marinas, linux-kernel,
	Jeremy Linton, Ard Biesheuvel, Linux IOMMU,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2342 bytes --]

On Wed, 2020-10-14 at 17:04 -0500, Rob Herring wrote:
> On Wed, Oct 14, 2020 at 2:12 PM Nicolas Saenz Julienne
> <nsaenzjulienne@suse.de> wrote:
> > Introduce a test for of_dma_get_max_cup_address(), it uses the same DT
> > data as the rest of dma-ranges unit tests.
> > 
> > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > ---
> >  drivers/of/unittest.c | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> > 
> > diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
> > index 06cc988faf78..2cbf2a585c9f 100644
> > --- a/drivers/of/unittest.c
> > +++ b/drivers/of/unittest.c
> > @@ -869,6 +869,25 @@ static void __init of_unittest_changeset(void)
> >  #endif
> >  }
> > 
> > +static void __init of_unittest_dma_get_max_cpu_address(void)
> > +{
> > +#ifdef CONFIG_HAS_DMA
> 
> Can't the unittest run without this? I run the unittests under UML.

It was cargo culted from its sibling of_unittest_dma_ranges_one(), now that you
mention it, I can't seem to find the reason why it's here in the first place,
nor for other similar usages in OF code.

I ran the test in UML with all HAS_DMA conditionals removed from OF code and
things went well. I'll prepare a fix for that.

> > +       struct device_node *np;
> > +       phys_addr_t cpu_addr;
> > +
> > +       np = of_find_node_by_path("/testcase-data/address-tests");
> > +       if (!np) {
> > +               pr_err("missing testcase data\n");
> > +               return;
> > +       }
> > +
> > +       cpu_addr = of_dma_get_max_cpu_address(np);
> > +       unittest(cpu_addr == 0x50000000ULL,
> > +                "of_dma_get_max_cpu_address: wrong CPU addr %pad (expecting %llx)\n",
> > +                &cpu_addr, 0x50000000ULL);
> > +#endif
> > +}
> > +
> >  static void __init of_unittest_dma_ranges_one(const char *path,
> >                 u64 expect_dma_addr, u64 expect_paddr)
> >  {
> > @@ -3266,6 +3285,7 @@ static int __init of_unittest(void)
> >         of_unittest_changeset();
> >         of_unittest_parse_interrupts();
> >         of_unittest_parse_interrupts_extended();
> > +       of_unittest_dma_get_max_cpu_address();
> >         of_unittest_parse_dma_ranges();
> >         of_unittest_pci_dma_ranges();
> >         of_unittest_match_node();
> > --
> > 2.28.0
> > 


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-15  5:42   ` Christoph Hellwig
@ 2020-10-15 10:03     ` Nicolas Saenz Julienne
  2020-10-16 13:19     ` Rob Herring
  1 sibling, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15 10:03 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: devicetree, catalin.marinas, robin.murphy, jeremy.linton,
	linux-kernel, iommu, robh+dt, linux-rpi-kernel, Frank Rowand,
	ardb, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 728 bytes --]

On Thu, 2020-10-15 at 07:42 +0200, Christoph Hellwig wrote:
> > +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> > +{
> > +	phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
> > +	struct of_range_parser parser;
> > +	phys_addr_t subtree_max_addr;
> > +	struct device_node *child;
> > +	phys_addr_t cpu_end = 0;
> > +	struct of_range range;
> > +	const __be32 *ranges;
> > +	int len;
> > +
> > +	if (!np)
> > +		np = of_root;
> 
> Requiring of_root to be passed explicitly would seem more natural
> to me than the magic NULL argument.  There doesn't seem to be any
> precedent for that kind of calling convention either.

I inspired that behavior from __of_find_all_nodes(). I'll change it.


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 484 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define
  2020-10-15  5:38   ` Christoph Hellwig
@ 2020-10-15 10:05     ` Nicolas Saenz Julienne
  0 siblings, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15 10:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: devicetree, catalin.marinas, linux-kernel, jeremy.linton, iommu,
	robh+dt, linux-rpi-kernel, Robin Murphy, ardb, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 439 bytes --]

On Thu, 2020-10-15 at 07:38 +0200, Christoph Hellwig wrote:
> On Wed, Oct 14, 2020 at 09:12:07PM +0200, Nicolas Saenz Julienne wrote:
> > Set zone_dma_bits default value through a define so as for architectures
> > to be able to override it with their default value.
> 
> Architectures can do that already by assigning a value to zone_dma_bits
> at runtime.  I really do not want to add the extra clutter.

I'll remove it then.


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges
  2020-10-15  5:39   ` Christoph Hellwig
@ 2020-10-15 10:05     ` Nicolas Saenz Julienne
  0 siblings, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15 10:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: devicetree, Will Deacon, catalin.marinas, linux-kernel,
	jeremy.linton, iommu, robh+dt, linux-rpi-kernel, robin.murphy,
	ardb, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 398 bytes --]

On Thu, 2020-10-15 at 07:39 +0200, Christoph Hellwig wrote:
> On Wed, Oct 14, 2020 at 09:12:08PM +0200, Nicolas Saenz Julienne wrote:
> > +	zone_dma_bits = min(zone_dma_bits,
> > +			    (unsigned int)ilog2(of_dma_get_max_cpu_address(NULL)));
> 
> Plase avoid pointlessly long lines.  Especially if it is completely trivial
> by using either min_t or not overindenting like here.

Noted


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-14 19:12 ` [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan Nicolas Saenz Julienne
@ 2020-10-15 10:31   ` Lorenzo Pieralisi
  2020-10-16  6:56     ` Ard Biesheuvel
  2020-10-15 14:26   ` Hanjun Guo
  1 sibling, 1 reply; 35+ messages in thread
From: Lorenzo Pieralisi @ 2020-10-15 10:31 UTC (permalink / raw)
  To: Nicolas Saenz Julienne
  Cc: devicetree, Will Deacon, Anshuman Khandual, catalin.marinas,
	Sudeep Holla, Rafael J. Wysocki, linux-kernel, jeremy.linton,
	ardb, linux-acpi, iommu, robh+dt, linux-rpi-kernel, Hanjun Guo,
	robin.murphy, hch, linux-arm-kernel, Len Brown

On Wed, Oct 14, 2020 at 09:12:09PM +0200, Nicolas Saenz Julienne wrote:

[...]

> +unsigned int __init acpi_iort_get_zone_dma_size(void)
> +{
> +	struct acpi_table_iort *iort;
> +	struct acpi_iort_node *node, *end;
> +	acpi_status status;
> +	u8 limit = 32;
> +	int i;
> +
> +	if (acpi_disabled)
> +		return limit;
> +
> +	status = acpi_get_table(ACPI_SIG_IORT, 0,
> +				(struct acpi_table_header **)&iort);
> +	if (ACPI_FAILURE(status))
> +		return limit;
> +
> +	node = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->node_offset);
> +	end = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->header.length);
> +
> +	for (i = 0; i < iort->node_count; i++) {
> +		if (node >= end)
> +			break;
> +
> +		switch (node->type) {
> +			struct acpi_iort_named_component *ncomp;
> +			struct acpi_iort_root_complex *rc;
> +
> +		case ACPI_IORT_NODE_NAMED_COMPONENT:
> +			ncomp = (struct acpi_iort_named_component *)node->node_data;
> +			if (ncomp->memory_address_limit)
> +				limit = min(limit, ncomp->memory_address_limit);
> +			break;
> +
> +		case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
> +			rc = (struct acpi_iort_root_complex *)node->node_data;
> +			if (rc->memory_address_limit)

You need to add a node revision check here, see rc_dma_get_range() in
drivers/acpi/arm64/iort.c, otherwise we may be reading junk data
in older IORT tables - acpica structures are always referring to the
latest specs.

Thanks,
Lorenzo

> +				limit = min(limit, rc->memory_address_limit);
> +			break;
> +		}
> +		node = ACPI_ADD_PTR(struct acpi_iort_node, node, node->length);
> +	}
> +	acpi_put_table(&iort->header);
> +	return limit;
> +}
> +#endif
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 20a32120bb88..7d2e184f0d4d 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -38,6 +38,7 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
>  const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
>  						const u32 *id_in);
>  int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
> +unsigned int acpi_iort_get_zone_dma_size(void);
>  #else
>  static inline void acpi_iort_init(void) { }
>  static inline u32 iort_msi_map_id(struct device *dev, u32 id)
> @@ -55,6 +56,9 @@ static inline const struct iommu_ops *iort_iommu_configure_id(
>  static inline
>  int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
>  { return 0; }
> +
> +static inline unsigned int acpi_iort_get_zone_dma_size(void)
> +{ return 32; }
>  #endif
>  
>  #endif /* __ACPI_IORT_H__ */
> -- 
> 2.28.0
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-14 19:12 ` [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan Nicolas Saenz Julienne
  2020-10-15 10:31   ` Lorenzo Pieralisi
@ 2020-10-15 14:26   ` Hanjun Guo
  2020-10-15 15:15     ` Nicolas Saenz Julienne
  2020-10-15 18:03     ` Catalin Marinas
  1 sibling, 2 replies; 35+ messages in thread
From: Hanjun Guo @ 2020-10-15 14:26 UTC (permalink / raw)
  To: Nicolas Saenz Julienne, robh+dt, catalin.marinas, hch, ardb,
	linux-kernel, Lorenzo Pieralisi, Sudeep Holla
  Cc: devicetree, Anshuman Khandual, Will Deacon, Rafael J. Wysocki,
	jeremy.linton, linux-acpi, iommu, linux-rpi-kernel, robin.murphy,
	linux-arm-kernel, Len Brown

On 2020/10/15 3:12, Nicolas Saenz Julienne wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
> 
> We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
> incorporating masters that can address less than 32 bits of DMA, in
> particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
> peripherals that can only address up to 1 GB (and its PCIe host
> bridge can only access the bottom 3 GB)
> 
> Instructing the DMA layer about these limitations is straight-forward,
> even though we had to fix some issues regarding memory limits set in
> the IORT for named components, and regarding the handling of ACPI _DMA
> methods. However, the DMA layer also needs to be able to allocate
> memory that is guaranteed to meet those DMA constraints, for bounce
> buffering as well as allocating the backing for consistent mappings.
> 
> This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
> it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
> problems with kdump, and potentially in other places where allocations
> cannot cross zone boundaries. Therefore, we should avoid having two
> separate DMA zones when possible.
> 
> So let's do an early scan of the IORT, and only create the ZONE_DMA
> if we encounter any devices that need it. This puts the burden on
> the firmware to describe such limitations in the IORT, which may be
> redundant (and less precise) if _DMA methods are also being provided.
> However, it should be noted that this situation is highly unusual for
> arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
> the _DMA method if implemented, and so we will not lose the ability to
> perform streaming DMA outside the ZONE_DMA if the _DMA method permits
> it.

Sorry, I'm still a little bit confused. With this patch, if we have
a device which set the right _DMA method (DMA size >= 32), but with the
wrong DMA size in IORT, we still have the ZONE_DMA created which
is actually not needed?

> 
> Cc: Jeremy Linton <jeremy.linton@arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> [nsaenz: Rebased, removed documentation change, warnings and add
> declaration in acpi_iort.h]
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> ---
>   arch/arm64/mm/init.c      |  6 +++++
>   drivers/acpi/arm64/iort.c | 51 +++++++++++++++++++++++++++++++++++++++
>   include/linux/acpi_iort.h |  4 +++
>   3 files changed, 61 insertions(+)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 97b0d2768349..f321761eedb2 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -29,6 +29,7 @@
>   #include <linux/kexec.h>
>   #include <linux/crash_dump.h>
>   #include <linux/hugetlb.h>
> +#include <linux/acpi_iort.h>
>   
>   #include <asm/boot.h>
>   #include <asm/fixmap.h>
> @@ -196,6 +197,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
>   #ifdef CONFIG_ZONE_DMA
>   	zone_dma_bits = min(zone_dma_bits,
>   			    (unsigned int)ilog2(of_dma_get_max_cpu_address(NULL)));
> +
> +	if (IS_ENABLED(CONFIG_ACPI))
> +		zone_dma_bits = min(zone_dma_bits,
> +				    acpi_iort_get_zone_dma_size());
> +
>   	arm64_dma_phys_limit = max_zone_phys(zone_dma_bits);
>   	max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
>   #endif
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 9929ff50c0c0..8f530bf3c03b 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -1718,3 +1718,54 @@ void __init acpi_iort_init(void)
>   
>   	iort_init_platform_devices();
>   }
> +
> +#ifdef CONFIG_ZONE_DMA
> +/*
> + * Check the IORT whether any devices exist whose DMA mask is < 32 bits.
> + * If so, return the smallest value encountered, or 32 otherwise.
> + */
> +unsigned int __init acpi_iort_get_zone_dma_size(void)
> +{
> +	struct acpi_table_iort *iort;
> +	struct acpi_iort_node *node, *end;
> +	acpi_status status;
> +	u8 limit = 32;
> +	int i;
> +
> +	if (acpi_disabled)
> +		return limit;
> +
> +	status = acpi_get_table(ACPI_SIG_IORT, 0,
> +				(struct acpi_table_header **)&iort);
> +	if (ACPI_FAILURE(status))
> +		return limit;
> +
> +	node = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->node_offset);
> +	end = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->header.length);
> +
> +	for (i = 0; i < iort->node_count; i++) {
> +		if (node >= end)
> +			break;
> +
> +		switch (node->type) {
> +			struct acpi_iort_named_component *ncomp;
> +			struct acpi_iort_root_complex *rc;
> +
> +		case ACPI_IORT_NODE_NAMED_COMPONENT:
> +			ncomp = (struct acpi_iort_named_component *)node->node_data;
> +			if (ncomp->memory_address_limit)
> +				limit = min(limit, ncomp->memory_address_limit);
> +			break;
> +
> +		case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
> +			rc = (struct acpi_iort_root_complex *)node->node_data;
> +			if (rc->memory_address_limit)
> +				limit = min(limit, rc->memory_address_limit);

There is no "Memory address size limit" field in revision 0 table, so as
Lorenzo reminded, please add a revision check here.

Thanks
Hanjun


> +			break;
> +		}
> +		node = ACPI_ADD_PTR(struct acpi_iort_node, node, node->length);
> +	}
> +	acpi_put_table(&iort->header);
> +	return limit;
> +}
> +#endif
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 20a32120bb88..7d2e184f0d4d 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -38,6 +38,7 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
>   const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
>   						const u32 *id_in);
>   int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
> +unsigned int acpi_iort_get_zone_dma_size(void);
>   #else
>   static inline void acpi_iort_init(void) { }
>   static inline u32 iort_msi_map_id(struct device *dev, u32 id)
> @@ -55,6 +56,9 @@ static inline const struct iommu_ops *iort_iommu_configure_id(
>   static inline
>   int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
>   { return 0; }
> +
> +static inline unsigned int acpi_iort_get_zone_dma_size(void)
> +{ return 32; }
>   #endif
>   
>   #endif /* __ACPI_IORT_H__ */
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-15 14:26   ` Hanjun Guo
@ 2020-10-15 15:15     ` Nicolas Saenz Julienne
  2020-10-15 18:03     ` Catalin Marinas
  1 sibling, 0 replies; 35+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-15 15:15 UTC (permalink / raw)
  To: Hanjun Guo, robh+dt, catalin.marinas, hch, ardb, linux-kernel,
	Lorenzo Pieralisi, Sudeep Holla
  Cc: devicetree, Anshuman Khandual, Will Deacon, Rafael J. Wysocki,
	jeremy.linton, linux-acpi, iommu, linux-rpi-kernel, robin.murphy,
	linux-arm-kernel, Len Brown


[-- Attachment #1.1: Type: text/plain, Size: 2194 bytes --]

On Thu, 2020-10-15 at 22:26 +0800, Hanjun Guo wrote:
> On 2020/10/15 3:12, Nicolas Saenz Julienne wrote:
> > From: Ard Biesheuvel <ardb@kernel.org>
> > 
> > We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
> > incorporating masters that can address less than 32 bits of DMA, in
> > particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
> > peripherals that can only address up to 1 GB (and its PCIe host
> > bridge can only access the bottom 3 GB)
> > 
> > Instructing the DMA layer about these limitations is straight-forward,
> > even though we had to fix some issues regarding memory limits set in
> > the IORT for named components, and regarding the handling of ACPI _DMA
> > methods. However, the DMA layer also needs to be able to allocate
> > memory that is guaranteed to meet those DMA constraints, for bounce
> > buffering as well as allocating the backing for consistent mappings.
> > 
> > This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
> > it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
> > problems with kdump, and potentially in other places where allocations
> > cannot cross zone boundaries. Therefore, we should avoid having two
> > separate DMA zones when possible.
> > 
> > So let's do an early scan of the IORT, and only create the ZONE_DMA
> > if we encounter any devices that need it. This puts the burden on
> > the firmware to describe such limitations in the IORT, which may be
> > redundant (and less precise) if _DMA methods are also being provided.
> > However, it should be noted that this situation is highly unusual for
> > arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
> > the _DMA method if implemented, and so we will not lose the ability to
> > perform streaming DMA outside the ZONE_DMA if the _DMA method permits
> > it.
> 
> Sorry, I'm still a little bit confused. With this patch, if we have
> a device which set the right _DMA method (DMA size >= 32), but with the
> wrong DMA size in IORT, we still have the ZONE_DMA created which
> is actually not needed?

Yes, that would be the case.

Regards,
Nicolas


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-15 14:26   ` Hanjun Guo
  2020-10-15 15:15     ` Nicolas Saenz Julienne
@ 2020-10-15 18:03     ` Catalin Marinas
  2020-10-16  6:51       ` Hanjun Guo
  1 sibling, 1 reply; 35+ messages in thread
From: Catalin Marinas @ 2020-10-15 18:03 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: devicetree, Anshuman Khandual, Will Deacon, Rafael J. Wysocki,
	linux-kernel, jeremy.linton, ardb, linux-acpi, iommu, robh+dt,
	linux-arm-kernel, Sudeep Holla, Len Brown, robin.murphy, hch,
	linux-rpi-kernel

On Thu, Oct 15, 2020 at 10:26:18PM +0800, Hanjun Guo wrote:
> On 2020/10/15 3:12, Nicolas Saenz Julienne wrote:
> > From: Ard Biesheuvel <ardb@kernel.org>
> > 
> > We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
> > incorporating masters that can address less than 32 bits of DMA, in
> > particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
> > peripherals that can only address up to 1 GB (and its PCIe host
> > bridge can only access the bottom 3 GB)
> > 
> > Instructing the DMA layer about these limitations is straight-forward,
> > even though we had to fix some issues regarding memory limits set in
> > the IORT for named components, and regarding the handling of ACPI _DMA
> > methods. However, the DMA layer also needs to be able to allocate
> > memory that is guaranteed to meet those DMA constraints, for bounce
> > buffering as well as allocating the backing for consistent mappings.
> > 
> > This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
> > it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
> > problems with kdump, and potentially in other places where allocations
> > cannot cross zone boundaries. Therefore, we should avoid having two
> > separate DMA zones when possible.
> > 
> > So let's do an early scan of the IORT, and only create the ZONE_DMA
> > if we encounter any devices that need it. This puts the burden on
> > the firmware to describe such limitations in the IORT, which may be
> > redundant (and less precise) if _DMA methods are also being provided.
> > However, it should be noted that this situation is highly unusual for
> > arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
> > the _DMA method if implemented, and so we will not lose the ability to
> > perform streaming DMA outside the ZONE_DMA if the _DMA method permits
> > it.
> 
> Sorry, I'm still a little bit confused. With this patch, if we have
> a device which set the right _DMA method (DMA size >= 32), but with the
> wrong DMA size in IORT, we still have the ZONE_DMA created which
> is actually not needed?

With the current kernel, we get a ZONE_DMA already with an arbitrary
size of 1GB that matches what RPi4 needs. We are trying to eliminate
such unnecessary ZONE_DMA based on some heuristics (well, something that
looks "better" than a OEM ID based quirk). Now, if we learn that IORT
for platforms in the field is that broken as to describe few bits-wide
DMA masks, we may have to go back to the OEM ID quirk.

-- 
Catalin
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-15 18:03     ` Catalin Marinas
@ 2020-10-16  6:51       ` Hanjun Guo
  2020-10-16  6:54         ` Ard Biesheuvel
  0 siblings, 1 reply; 35+ messages in thread
From: Hanjun Guo @ 2020-10-16  6:51 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: devicetree, Anshuman Khandual, Will Deacon, Rafael J. Wysocki,
	linux-kernel, jeremy.linton, ardb, linux-acpi, iommu, robh+dt,
	Linuxarm, linux-arm-kernel, Sudeep Holla, Len Brown,
	robin.murphy, hch, linux-rpi-kernel

On 2020/10/16 2:03, Catalin Marinas wrote:
> On Thu, Oct 15, 2020 at 10:26:18PM +0800, Hanjun Guo wrote:
>> On 2020/10/15 3:12, Nicolas Saenz Julienne wrote:
>>> From: Ard Biesheuvel <ardb@kernel.org>
>>>
>>> We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
>>> incorporating masters that can address less than 32 bits of DMA, in
>>> particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
>>> peripherals that can only address up to 1 GB (and its PCIe host
>>> bridge can only access the bottom 3 GB)
>>>
>>> Instructing the DMA layer about these limitations is straight-forward,
>>> even though we had to fix some issues regarding memory limits set in
>>> the IORT for named components, and regarding the handling of ACPI _DMA
>>> methods. However, the DMA layer also needs to be able to allocate
>>> memory that is guaranteed to meet those DMA constraints, for bounce
>>> buffering as well as allocating the backing for consistent mappings.
>>>
>>> This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
>>> it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
>>> problems with kdump, and potentially in other places where allocations
>>> cannot cross zone boundaries. Therefore, we should avoid having two
>>> separate DMA zones when possible.
>>>
>>> So let's do an early scan of the IORT, and only create the ZONE_DMA
>>> if we encounter any devices that need it. This puts the burden on
>>> the firmware to describe such limitations in the IORT, which may be
>>> redundant (and less precise) if _DMA methods are also being provided.
>>> However, it should be noted that this situation is highly unusual for
>>> arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
>>> the _DMA method if implemented, and so we will not lose the ability to
>>> perform streaming DMA outside the ZONE_DMA if the _DMA method permits
>>> it.
>>
>> Sorry, I'm still a little bit confused. With this patch, if we have
>> a device which set the right _DMA method (DMA size >= 32), but with the
>> wrong DMA size in IORT, we still have the ZONE_DMA created which
>> is actually not needed?
> 
> With the current kernel, we get a ZONE_DMA already with an arbitrary
> size of 1GB that matches what RPi4 needs. We are trying to eliminate
> such unnecessary ZONE_DMA based on some heuristics (well, something that
> looks "better" than a OEM ID based quirk). Now, if we learn that IORT
> for platforms in the field is that broken as to describe few bits-wide
> DMA masks, we may have to go back to the OEM ID quirk.

Some platforms using 0 as the memory size limit, for example D05 [0] and
D06 [1], I think we need to go back to the OEM ID quirk.

For D05/D06, there are multi interrupt controllers named as mbigen,
mbigen is using the named component to describe the mappings with
the ITS controller, and mbigen is using 0 as the memory size limit.

Also since the memory size limit for PCI RC was introduced by later
IORT revision, so firmware people may think it's fine to set that
as 0 because the system works without it.

Thanks
Hanjun

[0]:
https://github.com/tianocore/edk2-platforms/blob/master/Silicon/Hisilicon/Hi1616/D05AcpiTables/D05Iort.asl
[1]:
https://github.com/tianocore/edk2-platforms/blob/master/Silicon/Hisilicon/Hi1620/Hi1620AcpiTables/Hi1620Iort.asl
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-16  6:51       ` Hanjun Guo
@ 2020-10-16  6:54         ` Ard Biesheuvel
  2020-10-16  7:27           ` Hanjun Guo
  0 siblings, 1 reply; 35+ messages in thread
From: Ard Biesheuvel @ 2020-10-16  6:54 UTC (permalink / raw)
  To: Hanjun Guo
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Will Deacon, Anshuman Khandual, Catalin Marinas,
	Rafael J. Wysocki, Linux Kernel Mailing List, Jeremy Linton,
	Linuxarm, ACPI Devel Maling List, Linux IOMMU, Rob Herring,
	Linux ARM, Sudeep Holla, Len Brown, Robin Murphy,
	Christoph Hellwig,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

On Fri, 16 Oct 2020 at 08:51, Hanjun Guo <guohanjun@huawei.com> wrote:
>
> On 2020/10/16 2:03, Catalin Marinas wrote:
> > On Thu, Oct 15, 2020 at 10:26:18PM +0800, Hanjun Guo wrote:
> >> On 2020/10/15 3:12, Nicolas Saenz Julienne wrote:
> >>> From: Ard Biesheuvel <ardb@kernel.org>
> >>>
> >>> We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
> >>> incorporating masters that can address less than 32 bits of DMA, in
> >>> particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
> >>> peripherals that can only address up to 1 GB (and its PCIe host
> >>> bridge can only access the bottom 3 GB)
> >>>
> >>> Instructing the DMA layer about these limitations is straight-forward,
> >>> even though we had to fix some issues regarding memory limits set in
> >>> the IORT for named components, and regarding the handling of ACPI _DMA
> >>> methods. However, the DMA layer also needs to be able to allocate
> >>> memory that is guaranteed to meet those DMA constraints, for bounce
> >>> buffering as well as allocating the backing for consistent mappings.
> >>>
> >>> This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
> >>> it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
> >>> problems with kdump, and potentially in other places where allocations
> >>> cannot cross zone boundaries. Therefore, we should avoid having two
> >>> separate DMA zones when possible.
> >>>
> >>> So let's do an early scan of the IORT, and only create the ZONE_DMA
> >>> if we encounter any devices that need it. This puts the burden on
> >>> the firmware to describe such limitations in the IORT, which may be
> >>> redundant (and less precise) if _DMA methods are also being provided.
> >>> However, it should be noted that this situation is highly unusual for
> >>> arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
> >>> the _DMA method if implemented, and so we will not lose the ability to
> >>> perform streaming DMA outside the ZONE_DMA if the _DMA method permits
> >>> it.
> >>
> >> Sorry, I'm still a little bit confused. With this patch, if we have
> >> a device which set the right _DMA method (DMA size >= 32), but with the
> >> wrong DMA size in IORT, we still have the ZONE_DMA created which
> >> is actually not needed?
> >
> > With the current kernel, we get a ZONE_DMA already with an arbitrary
> > size of 1GB that matches what RPi4 needs. We are trying to eliminate
> > such unnecessary ZONE_DMA based on some heuristics (well, something that
> > looks "better" than a OEM ID based quirk). Now, if we learn that IORT
> > for platforms in the field is that broken as to describe few bits-wide
> > DMA masks, we may have to go back to the OEM ID quirk.
>
> Some platforms using 0 as the memory size limit, for example D05 [0] and
> D06 [1], I think we need to go back to the OEM ID quirk.
>
> For D05/D06, there are multi interrupt controllers named as mbigen,
> mbigen is using the named component to describe the mappings with
> the ITS controller, and mbigen is using 0 as the memory size limit.
>
> Also since the memory size limit for PCI RC was introduced by later
> IORT revision, so firmware people may think it's fine to set that
> as 0 because the system works without it.
>

Hello Hanjun,

The patch only takes the address limit field into account if its value > 0.

Also, before commit 7fb89e1d44cb6aec ("ACPI/IORT: take _DMA methods
into account for named components"), the _DMA method was not taken
into account for named components at all, and only the IORT limit was
used, so I do not anticipate any problems with that.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-15 10:31   ` Lorenzo Pieralisi
@ 2020-10-16  6:56     ` Ard Biesheuvel
  0 siblings, 0 replies; 35+ messages in thread
From: Ard Biesheuvel @ 2020-10-16  6:56 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Will Deacon, Anshuman Khandual, Catalin Marinas, Sudeep Holla,
	Rafael J. Wysocki, Linux Kernel Mailing List, Jeremy Linton,
	ACPI Devel Maling List, Linux IOMMU, Rob Herring, Linux ARM,
	Hanjun Guo, Len Brown, Robin Murphy, Christoph Hellwig,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

On Thu, 15 Oct 2020 at 12:31, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> On Wed, Oct 14, 2020 at 09:12:09PM +0200, Nicolas Saenz Julienne wrote:
>
> [...]
>
> > +unsigned int __init acpi_iort_get_zone_dma_size(void)
> > +{
> > +     struct acpi_table_iort *iort;
> > +     struct acpi_iort_node *node, *end;
> > +     acpi_status status;
> > +     u8 limit = 32;
> > +     int i;
> > +
> > +     if (acpi_disabled)
> > +             return limit;
> > +
> > +     status = acpi_get_table(ACPI_SIG_IORT, 0,
> > +                             (struct acpi_table_header **)&iort);
> > +     if (ACPI_FAILURE(status))
> > +             return limit;
> > +
> > +     node = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->node_offset);
> > +     end = ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->header.length);
> > +
> > +     for (i = 0; i < iort->node_count; i++) {
> > +             if (node >= end)
> > +                     break;
> > +
> > +             switch (node->type) {
> > +                     struct acpi_iort_named_component *ncomp;
> > +                     struct acpi_iort_root_complex *rc;
> > +
> > +             case ACPI_IORT_NODE_NAMED_COMPONENT:
> > +                     ncomp = (struct acpi_iort_named_component *)node->node_data;
> > +                     if (ncomp->memory_address_limit)
> > +                             limit = min(limit, ncomp->memory_address_limit);
> > +                     break;
> > +
> > +             case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
> > +                     rc = (struct acpi_iort_root_complex *)node->node_data;
> > +                     if (rc->memory_address_limit)
>
> You need to add a node revision check here, see rc_dma_get_range() in
> drivers/acpi/arm64/iort.c, otherwise we may be reading junk data
> in older IORT tables - acpica structures are always referring to the
> latest specs.
>

Indeed - apologies for not mentioning that when handing over the patch.

Also, we could use min_not_zero() here instead of the if ()
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-16  6:54         ` Ard Biesheuvel
@ 2020-10-16  7:27           ` Hanjun Guo
  2020-10-16  7:34             ` Hanjun Guo
  0 siblings, 1 reply; 35+ messages in thread
From: Hanjun Guo @ 2020-10-16  7:27 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Will Deacon, Anshuman Khandual, Catalin Marinas,
	Rafael J. Wysocki, Linux Kernel Mailing List, Jeremy Linton,
	Linuxarm, ACPI Devel Maling List, Linux IOMMU, Rob Herring,
	Linux ARM, Sudeep Holla, Len Brown, Robin Murphy,
	Christoph Hellwig,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

Hi Ard,

On 2020/10/16 14:54, Ard Biesheuvel wrote:
> On Fri, 16 Oct 2020 at 08:51, Hanjun Guo <guohanjun@huawei.com> wrote:
>>
>> On 2020/10/16 2:03, Catalin Marinas wrote:
>>> On Thu, Oct 15, 2020 at 10:26:18PM +0800, Hanjun Guo wrote:
>>>> On 2020/10/15 3:12, Nicolas Saenz Julienne wrote:
>>>>> From: Ard Biesheuvel <ardb@kernel.org>
>>>>>
>>>>> We recently introduced a 1 GB sized ZONE_DMA to cater for platforms
>>>>> incorporating masters that can address less than 32 bits of DMA, in
>>>>> particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has
>>>>> peripherals that can only address up to 1 GB (and its PCIe host
>>>>> bridge can only access the bottom 3 GB)
>>>>>
>>>>> Instructing the DMA layer about these limitations is straight-forward,
>>>>> even though we had to fix some issues regarding memory limits set in
>>>>> the IORT for named components, and regarding the handling of ACPI _DMA
>>>>> methods. However, the DMA layer also needs to be able to allocate
>>>>> memory that is guaranteed to meet those DMA constraints, for bounce
>>>>> buffering as well as allocating the backing for consistent mappings.
>>>>>
>>>>> This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately,
>>>>> it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes
>>>>> problems with kdump, and potentially in other places where allocations
>>>>> cannot cross zone boundaries. Therefore, we should avoid having two
>>>>> separate DMA zones when possible.
>>>>>
>>>>> So let's do an early scan of the IORT, and only create the ZONE_DMA
>>>>> if we encounter any devices that need it. This puts the burden on
>>>>> the firmware to describe such limitations in the IORT, which may be
>>>>> redundant (and less precise) if _DMA methods are also being provided.
>>>>> However, it should be noted that this situation is highly unusual for
>>>>> arm64 ACPI machines. Also, the DMA subsystem still gives precedence to
>>>>> the _DMA method if implemented, and so we will not lose the ability to
>>>>> perform streaming DMA outside the ZONE_DMA if the _DMA method permits
>>>>> it.
>>>>
>>>> Sorry, I'm still a little bit confused. With this patch, if we have
>>>> a device which set the right _DMA method (DMA size >= 32), but with the
>>>> wrong DMA size in IORT, we still have the ZONE_DMA created which
>>>> is actually not needed?
>>>
>>> With the current kernel, we get a ZONE_DMA already with an arbitrary
>>> size of 1GB that matches what RPi4 needs. We are trying to eliminate
>>> such unnecessary ZONE_DMA based on some heuristics (well, something that
>>> looks "better" than a OEM ID based quirk). Now, if we learn that IORT
>>> for platforms in the field is that broken as to describe few bits-wide
>>> DMA masks, we may have to go back to the OEM ID quirk.
>>
>> Some platforms using 0 as the memory size limit, for example D05 [0] and
>> D06 [1], I think we need to go back to the OEM ID quirk.
>>
>> For D05/D06, there are multi interrupt controllers named as mbigen,
>> mbigen is using the named component to describe the mappings with
>> the ITS controller, and mbigen is using 0 as the memory size limit.
>>
>> Also since the memory size limit for PCI RC was introduced by later
>> IORT revision, so firmware people may think it's fine to set that
>> as 0 because the system works without it.
>>
> 
> Hello Hanjun,
> 
> The patch only takes the address limit field into account if its value > 0.

Sorry I missed the if (*->memory_address_limit) check, thanks
for the reminding.

> 
> Also, before commit 7fb89e1d44cb6aec ("ACPI/IORT: take _DMA methods
> into account for named components"), the _DMA method was not taken
> into account for named components at all, and only the IORT limit was
> used, so I do not anticipate any problems with that.

Then this patch is fine to me.

Thanks
Hanjun
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan
  2020-10-16  7:27           ` Hanjun Guo
@ 2020-10-16  7:34             ` Hanjun Guo
  0 siblings, 0 replies; 35+ messages in thread
From: Hanjun Guo @ 2020-10-16  7:34 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE,
	Anshuman Khandual, Catalin Marinas, Rafael J. Wysocki,
	Linux Kernel Mailing List, Jeremy Linton, Linuxarm,
	ACPI Devel Maling List, Linux IOMMU, Rob Herring, Sudeep Holla,
	Robin Murphy, Will Deacon, Christoph Hellwig, Linux ARM,
	Len Brown

On 2020/10/16 15:27, Hanjun Guo wrote:
>> The patch only takes the address limit field into account if its value 
>> > 0.
> 
> Sorry I missed the if (*->memory_address_limit) check, thanks
> for the reminding.
> 
>>
>> Also, before commit 7fb89e1d44cb6aec ("ACPI/IORT: take _DMA methods
>> into account for named components"), the _DMA method was not taken
>> into account for named components at all, and only the IORT limit was
>> used, so I do not anticipate any problems with that.
> 
> Then this patch is fine to me.

Certainly we need to address Lorenzo's comments.

Thanks
Hanjun
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

* Re: [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address()
  2020-10-15  5:42   ` Christoph Hellwig
  2020-10-15 10:03     ` Nicolas Saenz Julienne
@ 2020-10-16 13:19     ` Rob Herring
  1 sibling, 0 replies; 35+ messages in thread
From: Rob Herring @ 2020-10-16 13:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: devicetree, Frank Rowand, Catalin Marinas, linux-kernel,
	Jeremy Linton, Linux IOMMU, linux-arm-kernel, Robin Murphy,
	Ard Biesheuvel, moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

On Thu, Oct 15, 2020 at 12:42 AM Christoph Hellwig <hch@lst.de> wrote:
>
> > +phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
> > +{
> > +     phys_addr_t max_cpu_addr = PHYS_ADDR_MAX;
> > +     struct of_range_parser parser;
> > +     phys_addr_t subtree_max_addr;
> > +     struct device_node *child;
> > +     phys_addr_t cpu_end = 0;
> > +     struct of_range range;
> > +     const __be32 *ranges;
> > +     int len;
> > +
> > +     if (!np)
> > +             np = of_root;
>
> Requiring of_root to be passed explicitly would seem more natural
> to me than the magic NULL argument.  There doesn't seem to be any
> precedent for that kind of calling convention either.

I prefer that of_root is not more widely exposed and NULL regularly
means 'the whole tree'.

Rob
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

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

end of thread, other threads:[~2020-10-16 13:20 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-14 19:12 [PATCH v3 0/8] arm64: Default to 32-bit wide ZONE_DMA Nicolas Saenz Julienne
2020-10-14 19:12 ` [PATCH v3 1/8] arm64: mm: Move reserve_crashkernel() into mem_init() Nicolas Saenz Julienne
2020-10-15  8:40   ` Will Deacon
2020-10-15  8:55     ` Nicolas Saenz Julienne
2020-10-14 19:12 ` [PATCH v3 2/8] arm64: mm: Move zone_dma_bits initialization into zone_sizes_init() Nicolas Saenz Julienne
2020-10-14 19:12 ` [PATCH v3 3/8] of/address: Introduce of_dma_get_max_cpu_address() Nicolas Saenz Julienne
2020-10-14 22:02   ` Rob Herring
2020-10-15  6:56     ` Ard Biesheuvel
2020-10-15  9:16       ` Nicolas Saenz Julienne
2020-10-15  9:18         ` Ard Biesheuvel
2020-10-15  8:54     ` Nicolas Saenz Julienne
2020-10-15  5:42   ` Christoph Hellwig
2020-10-15 10:03     ` Nicolas Saenz Julienne
2020-10-16 13:19     ` Rob Herring
2020-10-14 19:12 ` [PATCH v3 4/8] of: unittest: Add test for of_dma_get_max_cpu_address() Nicolas Saenz Julienne
2020-10-14 22:04   ` Rob Herring
2020-10-15  9:51     ` Nicolas Saenz Julienne
2020-10-14 19:12 ` [PATCH v3 5/8] dma-direct: Turn zone_dma_bits default value into a define Nicolas Saenz Julienne
2020-10-15  5:38   ` Christoph Hellwig
2020-10-15 10:05     ` Nicolas Saenz Julienne
2020-10-14 19:12 ` [PATCH v3 6/8] arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges Nicolas Saenz Julienne
2020-10-15  5:39   ` Christoph Hellwig
2020-10-15 10:05     ` Nicolas Saenz Julienne
2020-10-14 19:12 ` [PATCH v3 7/8] arm64: mm: Set ZONE_DMA size based on early IORT scan Nicolas Saenz Julienne
2020-10-15 10:31   ` Lorenzo Pieralisi
2020-10-16  6:56     ` Ard Biesheuvel
2020-10-15 14:26   ` Hanjun Guo
2020-10-15 15:15     ` Nicolas Saenz Julienne
2020-10-15 18:03     ` Catalin Marinas
2020-10-16  6:51       ` Hanjun Guo
2020-10-16  6:54         ` Ard Biesheuvel
2020-10-16  7:27           ` Hanjun Guo
2020-10-16  7:34             ` Hanjun Guo
2020-10-14 19:12 ` [PATCH v3 8/8] mm: Update DMA zones description Nicolas Saenz Julienne
2020-10-15  5:40   ` Christoph Hellwig

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).