dma-mapping: add flags to dma_map_ops to indicate PCI P2PDMA support
authorLogan Gunthorpe <logang@deltatee.com>
Fri, 8 Jul 2022 16:50:57 +0000 (10:50 -0600)
committerChristoph Hellwig <hch@lst.de>
Tue, 26 Jul 2022 11:27:48 +0000 (07:27 -0400)
Add a flags member to the dma_map_ops structure with one flag to
indicate support for PCI P2PDMA.

Also, add a helper to check if a device supports PCI P2PDMA.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
include/linux/dma-map-ops.h
include/linux/dma-mapping.h
kernel/dma/mapping.c

index 99cec59dbfcbdca139de5671f53f27b9e2246c89..010df04358aa103f287f5ca5a93640e0141f78a3 100644 (file)
 
 struct cma;
 
+/*
+ * Values for struct dma_map_ops.flags:
+ *
+ * DMA_F_PCI_P2PDMA_SUPPORTED: Indicates the dma_map_ops implementation can
+ * handle PCI P2PDMA pages in the map_sg/unmap_sg operation.
+ */
+#define DMA_F_PCI_P2PDMA_SUPPORTED     (1 << 0)
+
 struct dma_map_ops {
+       unsigned int flags;
+
        void *(*alloc)(struct device *dev, size_t size,
                        dma_addr_t *dma_handle, gfp_t gfp,
                        unsigned long attrs);
index fe3849434b2a21ea2d5419813595c357b4f4f850..25a30906289d987e9fc0936132bb526e3bf7a4d0 100644 (file)
@@ -140,6 +140,7 @@ int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
                unsigned long attrs);
 bool dma_can_mmap(struct device *dev);
 int dma_supported(struct device *dev, u64 mask);
+bool dma_pci_p2pdma_supported(struct device *dev);
 int dma_set_mask(struct device *dev, u64 mask);
 int dma_set_coherent_mask(struct device *dev, u64 mask);
 u64 dma_get_required_mask(struct device *dev);
@@ -251,6 +252,10 @@ static inline int dma_supported(struct device *dev, u64 mask)
 {
        return 0;
 }
+static inline bool dma_pci_p2pdma_supported(struct device *dev)
+{
+       return false;
+}
 static inline int dma_set_mask(struct device *dev, u64 mask)
 {
        return -EIO;
index 746d46825d08fe4a043d2ed05e13d95f96db5ec4..a9ce5d728231ba8701c59abce8e140b00754423c 100644 (file)
@@ -723,6 +723,24 @@ int dma_supported(struct device *dev, u64 mask)
 }
 EXPORT_SYMBOL(dma_supported);
 
+bool dma_pci_p2pdma_supported(struct device *dev)
+{
+       const struct dma_map_ops *ops = get_dma_ops(dev);
+
+       /* if ops is not set, dma direct will be used which supports P2PDMA */
+       if (!ops)
+               return true;
+
+       /*
+        * Note: dma_ops_bypass is not checked here because P2PDMA should
+        * not be used with dma mapping ops that do not have support even
+        * if the specific device is bypassing them.
+        */
+
+       return ops->flags & DMA_F_PCI_P2PDMA_SUPPORTED;
+}
+EXPORT_SYMBOL_GPL(dma_pci_p2pdma_supported);
+
 #ifdef CONFIG_ARCH_HAS_DMA_SET_MASK
 void arch_dma_set_mask(struct device *dev, u64 mask);
 #else