[RFC v2 2/2] RDMA/mlx5: get tph for p2p access when registering dmabuf mr

Zhiping Zhang
2026-03-24T23:51:54Z

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 <zhipingz@meta.com>
---
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