Skip to contentSkip to conversation

Refactor dummy DMA ops

PATCH In review Robin Murphy 4 participants 7 messages Dec 7, 2018 – Dec 20, 2018

Subsystems (5)
ACPI PCI arm64 Driver core +1 more subsystems
lore
Share & tools
lore

Robin Murphy

author reviewer
#0 lore raw

cover Refactor dummy DMA ops

Hi all,

Tangential to Christoph's RFC for mitigating indirect call overhead in common DMA mapping scenarios[1], this is a little reshuffle to prevent the CONFIG_ACPI_CCA_REQUIRED case from getting in the way. This would best go via the dma-mapping tree, so reviews and acks welcome.

Robin.

[1] https://lore.kernel.org/lkml/[email protected]/

Robin Murphy (2):
dma-mapping: Factor out dummy DMA ops
ACPI / scan: Refactor _CCA enforcement

 arch/arm64/include/asm/dma-mapping.h |  4 +-
 arch/arm64/mm/dma-mapping.c          | 92 ----------------------------
 drivers/acpi/scan.c                  |  5 ++
 drivers/base/platform.c              |  3 +-
 drivers/pci/pci-driver.c             |  3 +-
 include/linux/dma-mapping.h          |  1 +
 kernel/dma/mapping.c                 | 54 ++++++++++++++++
 7 files changed, 63 insertions(+), 99 deletions(-)
Signature · 1 line
2.19.1.dirty
author reviewer
#1 lore raw

PATCH 1/2 dma-mapping: Factor out dummy DMA ops

The dummy DMA ops are currently used by arm64 for any device which has an invalid ACPI description and is thus barred from using DMA due to not knowing whether is is cache-coherent or not. Factor these out into general dma-mapping code so that they can be referenced from other common code paths. In the process, we can prune all the optional callbacks which just do the same thing as the default behaviour, and fill in .map_resource for completeness.

CC Catalin Marinas <[email protected]>
CC Will Deacon <[email protected]>
---
 arch/arm64/include/asm/dma-mapping.h |  4 +-
 arch/arm64/mm/dma-mapping.c          | 92 ----------------------------
 include/linux/dma-mapping.h          |  1 +
 kernel/dma/mapping.c                 | 54 ++++++++++++++++
 4 files changed, 56 insertions(+), 95 deletions(-)
arch/arm64/include/asm/dma-mapping.h +1 -3
index c41f3fb1446c..273e778f7de2 100644
@@ -24,15 +24,13 @@
 #include <xen/xen.h>
 #include <asm/xen/hypervisor.h>
 
-extern const struct dma_map_ops dummy_dma_ops;
-
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
 	/*
 	 * We expect no ISA devices, and all other DMA masters are expected to
 	 * have someone call arch_setup_dma_ops at device creation time.
 	 */
-	return &dummy_dma_ops;
+	return &dma_dummy_ops;
 }
 
 void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
arch/arm64/mm/dma-mapping.c +0 -92

98 lines not on this page · raw message

include/linux/dma-mapping.h +1 -0
index 15bd41447025..3a1928ea23c9 100644
@@ -134,6 +134,7 @@ struct dma_map_ops {
 };
 
 extern const struct dma_map_ops dma_direct_ops;
+extern const struct dma_map_ops dma_dummy_ops;
 extern const struct dma_map_ops dma_virt_ops;
 
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
kernel/dma/mapping.c +54 -0

57 lines not on this page · raw message

Signature · 1 line
2.19.1.dirty
author reviewer
#2 lore raw

PATCH 2/2 ACPI / scan: Refactor _CCA enforcement

In reply to Robin Murphy

Rather than checking the DMA attribute at each callsite, just pass it through for acpi_dma_configure() to handle directly. That can then deal with the relatively exceptional DEV_DMA_NOT_SUPPORTED case by explicitly installing dummy DMA ops instead of just skipping setup entirely. This will then free up the dev->dma_ops == NULL case for some valuable fastpath optimisations.

CC Rafael J. Wysocki <[email protected]>
CC Len Brown <[email protected]>
CC Greg Kroah-Hartman <[email protected]>
CC Bjorn Helgaas <[email protected]>
---
 drivers/acpi/scan.c      | 5 +++++
 drivers/base/platform.c  | 3 +--
 drivers/pci/pci-driver.c | 3 +--
 3 files changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/scan.c +5 -0
index bd1c59fb0e17..b75ae34ed188 100644
@@ -1456,6 +1456,11 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 	const struct iommu_ops *iommu;
 	u64 dma_addr = 0, size = 0;
 
+	if (attr == DEV_DMA_NOT_SUPPORTED) {
+		set_dma_ops(dev, &dma_dummy_ops);
+		return 0;
+	}
+
 	iort_dma_setup(dev, &dma_addr, &size);
 
 	iommu = iort_iommu_configure(dev);
drivers/base/platform.c +1 -2
index 41b91af95afb..c6daca875c17 100644
@@ -1138,8 +1138,7 @@ int platform_dma_configure(struct device *dev)
 		ret = of_dma_configure(dev, dev->of_node, true);
 	} else if (has_acpi_companion(dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
-		if (attr != DEV_DMA_NOT_SUPPORTED)
-			ret = acpi_dma_configure(dev, attr);
+		ret = acpi_dma_configure(dev, attr);
 	}
 
 	return ret;
drivers/pci/pci-driver.c +1 -2
index bef17c3fca67..f899a28b90f8 100644
@@ -1602,8 +1602,7 @@ static int pci_dma_configure(struct device *dev)
 		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
 		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
 
-		if (attr != DEV_DMA_NOT_SUPPORTED)
-			ret = acpi_dma_configure(dev, attr);
+		ret = acpi_dma_configure(dev, attr);
 	}
 
 	pci_put_host_bridge_device(bridge);
Signature · 1 line
2.19.1.dirty
#5 lore raw
In reply to Robin Murphy

So I'd really prefer if we had a separate dummy.c file, like in my take on your previous patch here:

http://git.infradead.org/users/hch/misc.git/commitdiff/e01adddc1733fa414dc16cd22e8f58be9b64a025

http://git.infradead.org/users/hch/misc.git/commitdiff/596bde76e5944a3f4beb8c2769067ca88dda127a

Otherwise this looks fine. If you don't minde I'll take your patches, apply the move to a separate file and merge it into the above tree.

author reviewer
#6 lore raw
Quoted 9 lines · Christoph Hellwig

So I'd really prefer if we had a separate dummy.c file, like in my take on your previous patch here:

http://git.infradead.org/users/hch/misc.git/commitdiff/e01adddc1733fa414dc16cd22e8f58be9b64a025

http://git.infradead.org/users/hch/misc.git/commitdiff/596bde76e5944a3f4beb8c2769067ca88dda127a

Otherwise this looks fine. If you don't minde I'll take your patches, apply the move to a separate file and merge it into the above tree.

Sure - TBH I did consider creating a separate file, but then didn't for mysterious reasons that don't stand up to scrutiny. If you're happy to do the fixup on top that's fine by me (if culling .map_resource was intentional, please scrub the last bit of the commit message to match).

I'll make the equivalent change locally anyway just in case there's any other cause to resend.

Robin.

maintainer Reviewed-by on v1 2/2
#3 lore raw

Re: [PATCH 2/2] ACPI / scan: Refactor _CCA enforcement

In reply to Robin Murphy
Quoted 8 lines · Robin Murphy

Rather than checking the DMA attribute at each callsite, just pass it through for acpi_dma_configure() to handle directly. That can then deal with the relatively exceptional DEV_DMA_NOT_SUPPORTED case by explicitly installing dummy DMA ops instead of just skipping setup entirely. This will then free up the dev->dma_ops == NULL case for some valuable fastpath optimisations.

Quoted 5 lines
CC Rafael J. Wysocki <[email protected]>
CC Len Brown <[email protected]>
CC Greg Kroah-Hartman <[email protected]>
CC Bjorn Helgaas <[email protected]>

The changes in this patch are fine by me:

Quoted 53 lines
---
 drivers/acpi/scan.c      | 5 +++++
 drivers/base/platform.c  | 3 +--
 drivers/pci/pci-driver.c | 3 +--
 3 files changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/scan.c +5 -0
index bd1c59fb0e17..b75ae34ed188 100644
@@ -1456,6 +1456,11 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
        const struct iommu_ops *iommu;
        u64 dma_addr = 0, size = 0;
 
+       if (attr == DEV_DMA_NOT_SUPPORTED) {
+               set_dma_ops(dev, &dma_dummy_ops);
+               return 0;
+       }
+
        iort_dma_setup(dev, &dma_addr, &size);
 
        iommu = iort_iommu_configure(dev);
drivers/base/platform.c +1 -2
index 41b91af95afb..c6daca875c17 100644
@@ -1138,8 +1138,7 @@ int platform_dma_configure(struct device *dev)
                ret = of_dma_configure(dev, dev->of_node, true);
        } else if (has_acpi_companion(dev)) {
                attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
-               if (attr != DEV_DMA_NOT_SUPPORTED)
-                       ret = acpi_dma_configure(dev, attr);
+               ret = acpi_dma_configure(dev, attr);
        }
 
        return ret;
drivers/pci/pci-driver.c +1 -3
index bef17c3fca67..f899a28b90f8 100644
@@ -1602,8 +1602,7 @@ static int pci_dma_configure(struct device *dev)
                struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
                enum dev_dma_attr attr = acpi_get_dma_attr(adev);
 
-               if (attr != DEV_DMA_NOT_SUPPORTED)
-                       ret = acpi_dma_configure(dev, attr);
+               ret = acpi_dma_configure(dev, attr);
        }
 
        pci_put_host_bridge_device(bridge);
--

2.19.1.dirty

Acked-by on v1 2/2
#4 lore raw

Re: [PATCH 2/2] ACPI / scan: Refactor _CCA enforcement

In reply to Robin Murphy
Quoted 7 lines · Robin Murphy

Rather than checking the DMA attribute at each callsite, just pass it through for acpi_dma_configure() to handle directly. That can then deal with the relatively exceptional DEV_DMA_NOT_SUPPORTED case by explicitly installing dummy DMA ops instead of just skipping setup entirely. This will then free up the dev->dma_ops == NULL case for some valuable fastpath optimisations.

Quoted 5 lines
CC Rafael J. Wysocki <[email protected]>
CC Len Brown <[email protected]>
CC Greg Kroah-Hartman <[email protected]>
CC Bjorn Helgaas <[email protected]>

FWIW, if this hasn't been applied already (I think you targeted a DMA tree):

Quoted 58 lines
---
 drivers/acpi/scan.c      | 5 +++++
 drivers/base/platform.c  | 3 +--
 drivers/pci/pci-driver.c | 3 +--
 3 files changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/scan.c +5 -0
index bd1c59fb0e17..b75ae34ed188 100644
@@ -1456,6 +1456,11 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 	const struct iommu_ops *iommu;
 	u64 dma_addr = 0, size = 0;
 
+	if (attr == DEV_DMA_NOT_SUPPORTED) {
+		set_dma_ops(dev, &dma_dummy_ops);
+		return 0;
+	}
+
 	iort_dma_setup(dev, &dma_addr, &size);
 
 	iommu = iort_iommu_configure(dev);
drivers/base/platform.c +1 -2
index 41b91af95afb..c6daca875c17 100644
@@ -1138,8 +1138,7 @@ int platform_dma_configure(struct device *dev)
 		ret = of_dma_configure(dev, dev->of_node, true);
 	} else if (has_acpi_companion(dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
-		if (attr != DEV_DMA_NOT_SUPPORTED)
-			ret = acpi_dma_configure(dev, attr);
+		ret = acpi_dma_configure(dev, attr);
 	}
 
 	return ret;
drivers/pci/pci-driver.c +1 -2
index bef17c3fca67..f899a28b90f8 100644
@@ -1602,8 +1602,7 @@ static int pci_dma_configure(struct device *dev)
 		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
 		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
 
-		if (attr != DEV_DMA_NOT_SUPPORTED)
-			ret = acpi_dma_configure(dev, attr);
+		ret = acpi_dma_configure(dev, attr);
 	}
 
 	pci_put_host_bridge_device(bridge);
Signature · 7 lines
2.19.1.dirty


_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel