Drop the use of pci_p2pdma_map_sg() in favour of dma_map_sg_p2pdma().

The new interface allows mapping scatterlists that mix both regular
and P2PDMA pages and will verify that the dma device can communicate
with the device the pages are on.

Signed-off-by: Logan Gunthorpe <log...@deltatee.com>
---
 drivers/infiniband/core/rw.c | 50 ++++++++++--------------------------
 include/rdma/ib_verbs.h      | 32 +++++++++++++++++++++++
 2 files changed, 46 insertions(+), 36 deletions(-)

diff --git a/drivers/infiniband/core/rw.c b/drivers/infiniband/core/rw.c
index 31156e22d3e7..0c6213d9b044 100644
--- a/drivers/infiniband/core/rw.c
+++ b/drivers/infiniband/core/rw.c
@@ -273,26 +273,6 @@ static int rdma_rw_init_single_wr(struct rdma_rw_ctx *ctx, 
struct ib_qp *qp,
        return 1;
 }
 
-static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg,
-                            u32 sg_cnt, enum dma_data_direction dir)
-{
-       if (is_pci_p2pdma_page(sg_page(sg)))
-               pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir);
-       else
-               ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
-}
-
-static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg,
-                         u32 sg_cnt, enum dma_data_direction dir)
-{
-       if (is_pci_p2pdma_page(sg_page(sg))) {
-               if (WARN_ON_ONCE(ib_uses_virt_dma(dev)))
-                       return 0;
-               return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir);
-       }
-       return ib_dma_map_sg(dev, sg, sg_cnt, dir);
-}
-
 /**
  * rdma_rw_ctx_init - initialize a RDMA READ/WRITE context
  * @ctx:       context to initialize
@@ -315,9 +295,9 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp 
*qp, u8 port_num,
        struct ib_device *dev = qp->pd->device;
        int ret;
 
-       ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir);
-       if (!ret)
-               return -ENOMEM;
+       ret = ib_dma_map_sg_p2pdma(dev, sg, sg_cnt, dir);
+       if (ret < 0)
+               return ret;
        sg_cnt = ret;
 
        /*
@@ -354,7 +334,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp 
*qp, u8 port_num,
        return ret;
 
 out_unmap_sg:
-       rdma_rw_unmap_sg(dev, sg, sg_cnt, dir);
+       ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
        return ret;
 }
 EXPORT_SYMBOL(rdma_rw_ctx_init);
@@ -394,17 +374,15 @@ int rdma_rw_ctx_signature_init(struct rdma_rw_ctx *ctx, 
struct ib_qp *qp,
                return -EINVAL;
        }
 
-       ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir);
-       if (!ret)
-               return -ENOMEM;
+       ret = ib_dma_map_sg_p2pdma(dev, sg, sg_cnt, dir);
+       if (ret < 0)
+               return ret;
        sg_cnt = ret;
 
        if (prot_sg_cnt) {
-               ret = rdma_rw_map_sg(dev, prot_sg, prot_sg_cnt, dir);
-               if (!ret) {
-                       ret = -ENOMEM;
+               ret = ib_dma_map_sg_p2pdma(dev, prot_sg, prot_sg_cnt, dir);
+               if (ret < 0)
                        goto out_unmap_sg;
-               }
                prot_sg_cnt = ret;
        }
 
@@ -469,9 +447,9 @@ int rdma_rw_ctx_signature_init(struct rdma_rw_ctx *ctx, 
struct ib_qp *qp,
        kfree(ctx->reg);
 out_unmap_prot_sg:
        if (prot_sg_cnt)
-               rdma_rw_unmap_sg(dev, prot_sg, prot_sg_cnt, dir);
+               ib_dma_unmap_sg(dev, prot_sg, prot_sg_cnt, dir);
 out_unmap_sg:
-       rdma_rw_unmap_sg(dev, sg, sg_cnt, dir);
+       ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
        return ret;
 }
 EXPORT_SYMBOL(rdma_rw_ctx_signature_init);
@@ -603,7 +581,7 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct 
ib_qp *qp, u8 port_num,
                break;
        }
 
-       rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
+       ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
 }
 EXPORT_SYMBOL(rdma_rw_ctx_destroy);
 
@@ -631,8 +609,8 @@ void rdma_rw_ctx_destroy_signature(struct rdma_rw_ctx *ctx, 
struct ib_qp *qp,
        kfree(ctx->reg);
 
        if (prot_sg_cnt)
-               rdma_rw_unmap_sg(qp->pd->device, prot_sg, prot_sg_cnt, dir);
-       rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
+               ib_dma_unmap_sg(qp->pd->device, prot_sg, prot_sg_cnt, dir);
+       ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
 }
 EXPORT_SYMBOL(rdma_rw_ctx_destroy_signature);
 
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index ca28fca5736b..a541ed1702f5 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -4028,6 +4028,17 @@ static inline int ib_dma_map_sg_attrs(struct ib_device 
*dev,
                                dma_attrs);
 }
 
+static inline int ib_dma_map_sg_p2pdma_attrs(struct ib_device *dev,
+                                            struct scatterlist *sg, int nents,
+                                            enum dma_data_direction direction,
+                                            unsigned long dma_attrs)
+{
+       if (ib_uses_virt_dma(dev))
+               return ib_dma_virt_map_sg(dev, sg, nents);
+       return dma_map_sg_p2pdma_attrs(dev->dma_device, sg, nents, direction,
+                                      dma_attrs);
+}
+
 static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev,
                                         struct scatterlist *sg, int nents,
                                         enum dma_data_direction direction,
@@ -4052,6 +4063,27 @@ static inline int ib_dma_map_sg(struct ib_device *dev,
        return ib_dma_map_sg_attrs(dev, sg, nents, direction, 0);
 }
 
+/**
+ * ib_dma_map_sg_p2pdma - Map a scatter/gather list to DMA addresses
+ * @dev: The device for which the DMA addresses are to be created
+ * @sg: The array of scatter/gather entries
+ * @nents: The number of scatter/gather entries
+ * @direction: The direction of the DMA
+ *
+ * Map an scatter/gather list that might contain P2PDMA pages.
+ * Unlike ib_dma_map_sg() it will return either a negative errno or
+ * a positive value indicating the number of dma segments. See
+ * dma_map_sg_p2pdma_attrs() for details.
+ *
+ * The resulting list should be unmapped with ib_dma_unmap_sg().
+ */
+static inline int ib_dma_map_sg_p2pdma(struct ib_device *dev,
+                                      struct scatterlist *sg, int nents,
+                                      enum dma_data_direction direction)
+{
+       return ib_dma_map_sg_p2pdma_attrs(dev, sg, nents, direction, 0);
+}
+
 /**
  * ib_dma_unmap_sg - Unmap a scatter/gather list of DMA addresses
  * @dev: The device for which the DMA addresses were created
-- 
2.20.1

Reply via email to