This patch adds support to retrieve tph info from dmabuf during mr
registration for P2P memory access. A new helper get_tph_mr_dmabuf()
queries the dmabuf exporter for tph (steering tag and processing hint)
and converts the raw steering tag to an st_index via
mlx5_st_alloc_index_by_tag(). The DMAH workflow for CPU still takes
precedence in the process.

The new mlx5_st_alloc_index_by_tag() API is extracted from
mlx5_st_alloc_index() to allow callers that already have a raw steering
tag value (e.g., from a dmabuf) to allocate an st_index directly,
without requiring a CPU ID and memory type lookup.

Signed-off-by: Zhiping Zhang <[email protected]>
---
 drivers/infiniband/hw/mlx5/mr.c               | 34 +++++++++++++++++++
 .../net/ethernet/mellanox/mlx5/core/lib/st.c  | 23 +++++++++----
 include/linux/mlx5/driver.h                   |  7 ++++
 3 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 665323b90b64..041922ba3bff 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -46,6 +46,8 @@
 #include "data_direct.h"
 #include "dmah.h"

+MODULE_IMPORT_NS("DMA_BUF");
+
 enum {
        MAX_PENDING_REG_MR = 8,
 };
@@ -1622,6 +1624,36 @@ static struct dma_buf_attach_ops 
mlx5_ib_dmabuf_attach_ops = {
        .move_notify = mlx5_ib_dmabuf_invalidate_cb,
 };

+static void get_tph_mr_dmabuf(struct mlx5_ib_dev *dev, int fd, u16 *st_index,
+                             u8 *ph)
+{
+       struct dma_buf *dmabuf;
+       u16 steering_tag;
+       int ret;
+
+       dmabuf = dma_buf_get(fd);
+       if (IS_ERR(dmabuf))
+               return;
+
+       if (!dmabuf->ops->get_tph)
+               goto end_dbuf_put;
+
+       ret = dmabuf->ops->get_tph(dmabuf, &steering_tag, ph);
+       if (ret) {
+               mlx5_ib_dbg(dev, "get_tph failed (%d)\n", ret);
+               goto end_dbuf_put;
+       }
+
+       ret = mlx5_st_alloc_index_by_tag(dev->mdev, steering_tag, st_index);
+       if (ret) {
+               *ph = MLX5_IB_NO_PH;
+               mlx5_ib_dbg(dev, "st_alloc_index_by_tag failed (%d)\n", ret);
+       }
+
+end_dbuf_put:
+       dma_buf_put(dmabuf);
+}
+
 static struct ib_mr *
 reg_user_mr_dmabuf(struct ib_pd *pd, struct device *dma_device,
                   u64 offset, u64 length, u64 virt_addr,
@@ -1664,6 +1696,8 @@ reg_user_mr_dmabuf(struct ib_pd *pd, struct device 
*dma_device,
                ph = dmah->ph;
                if (dmah->valid_fields & BIT(IB_DMAH_CPU_ID_EXISTS))
                        st_index = mdmah->st_index;
+       } else {
+               get_tph_mr_dmabuf(dev, fd, &st_index, &ph);
        }

        mr = alloc_cacheable_mr(pd, &umem_dmabuf->umem, virt_addr,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c 
b/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c
index 997be91f0a13..112c55ede731 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c
@@ -92,23 +92,18 @@ void mlx5_st_destroy(struct mlx5_core_dev *dev)
        kfree(st);
 }

-int mlx5_st_alloc_index(struct mlx5_core_dev *dev, enum tph_mem_type mem_type,
-                       unsigned int cpu_uid, u16 *st_index)
+int mlx5_st_alloc_index_by_tag(struct mlx5_core_dev *dev, u16 tag,
+                              u16 *st_index)
 {
        struct mlx5_st_idx_data *idx_data;
        struct mlx5_st *st = dev->st;
        unsigned long index;
        u32 xa_id;
-       u16 tag;
        int ret;

        if (!st)
                return -EOPNOTSUPP;

-       ret = pcie_tph_get_cpu_st(dev->pdev, mem_type, cpu_uid, &tag);
-       if (ret)
-               return ret;
-
        if (st->direct_mode) {
                *st_index = tag;
                return 0;
@@ -152,6 +147,20 @@ int mlx5_st_alloc_index(struct mlx5_core_dev *dev, enum 
tph_mem_type mem_type,
        mutex_unlock(&st->lock);
        return ret;
 }
+EXPORT_SYMBOL_GPL(mlx5_st_alloc_index_by_tag);
+
+int mlx5_st_alloc_index(struct mlx5_core_dev *dev, enum tph_mem_type mem_type,
+                       unsigned int cpu_uid, u16 *st_index)
+{
+       u16 tag;
+       int ret;
+
+       ret = pcie_tph_get_cpu_st(dev->pdev, mem_type, cpu_uid, &tag);
+       if (ret)
+               return ret;
+
+       return mlx5_st_alloc_index_by_tag(dev, tag, st_index);
+}
 EXPORT_SYMBOL_GPL(mlx5_st_alloc_index);

 int mlx5_st_dealloc_index(struct mlx5_core_dev *dev, u16 st_index)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 04dcd09f7517..c1d2d603bd96 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -1177,10 +1177,17 @@ int mlx5_dm_sw_icm_dealloc(struct mlx5_core_dev *dev, 
enum mlx5_sw_icm_type type
                           u64 length, u16 uid, phys_addr_t addr, u32 obj_id);

 #ifdef CONFIG_PCIE_TPH
+int mlx5_st_alloc_index_by_tag(struct mlx5_core_dev *dev, u16 tag,
+                              u16 *st_index);
 int mlx5_st_alloc_index(struct mlx5_core_dev *dev, enum tph_mem_type mem_type,
                        unsigned int cpu_uid, u16 *st_index);
 int mlx5_st_dealloc_index(struct mlx5_core_dev *dev, u16 st_index);
 #else
+static inline int mlx5_st_alloc_index_by_tag(struct mlx5_core_dev *dev,
+                                            u16 tag, u16 *st_index)
+{
+       return -EOPNOTSUPP;
+}
 static inline int mlx5_st_alloc_index(struct mlx5_core_dev *dev,
                                      enum tph_mem_type mem_type,
                                      unsigned int cpu_uid, u16 *st_index)
--
2.52.0

Reply via email to