[PATCH rdma-next 5/6] RDMA/mlx5: Add support for TLP VAR allocation

From: Leon Romanovsky

Date: Wed Feb 25 2026 - 09:24:05 EST


From: Maher Sanalla <msanalla@xxxxxxxxxx>

Extend the VAR allocation UAPI to accept an optional flags attribute,
allowing userspace to request TLP VAR allocation via the
MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP flag.

When the TLP flag "MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP" is specified,
the driver selects the TLP VAR region for allocation instead of the
regular VirtIO VAR region.

Signed-off-by: Maher Sanalla <msanalla@xxxxxxxxxx>
Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxx>
---
drivers/infiniband/hw/mlx5/main.c | 40 ++++++++++++++++++++++++++-----
include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 +
include/uapi/rdma/mlx5_user_ioctl_verbs.h | 4 ++++
3 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 424426a2cd76..77cd11c6cca9 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -4153,7 +4153,7 @@ static int mlx5_rdma_user_mmap_entry_insert(struct mlx5_ib_ucontext *c,
}

static struct mlx5_user_mmap_entry *
-alloc_var_entry(struct mlx5_ib_ucontext *c)
+alloc_var_entry(struct mlx5_ib_ucontext *c, u32 flags)
{
struct mlx5_user_mmap_entry *entry;
struct mlx5_var_region *var_region;
@@ -4162,7 +4162,11 @@ alloc_var_entry(struct mlx5_ib_ucontext *c)
int err;

var_table = &to_mdev(c->ibucontext.device)->var_table;
- var_region = &var_table->var_region;
+ if (flags & MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP)
+ var_region = &var_table->tlp_var_region;
+ else
+ var_region = &var_table->var_region;
+
entry = kzalloc_obj(*entry);
if (!entry)
return ERR_PTR(-ENOMEM);
@@ -4182,7 +4186,9 @@ alloc_var_entry(struct mlx5_ib_ucontext *c)
entry->address = var_region->hw_start_addr +
(page_idx * var_region->stride_size);
entry->page_idx = page_idx;
- entry->mmap_flag = MLX5_IB_MMAP_TYPE_VAR;
+ entry->mmap_flag = flags & MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP ?
+ MLX5_IB_MMAP_TYPE_TLP_VAR :
+ MLX5_IB_MMAP_TYPE_VAR;

err = mlx5_rdma_user_mmap_entry_insert(c, entry,
var_region->stride_size);
@@ -4205,9 +4211,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_VAR_OBJ_ALLOC)(
{
struct ib_uobject *uobj = uverbs_attr_get_uobject(
attrs, MLX5_IB_ATTR_VAR_OBJ_ALLOC_HANDLE);
- struct mlx5_ib_ucontext *c;
struct mlx5_user_mmap_entry *entry;
+ struct mlx5_ib_ucontext *c;
u64 mmap_offset;
+ u32 flags = 0;
u32 length;
int err;

@@ -4215,7 +4222,24 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_VAR_OBJ_ALLOC)(
if (IS_ERR(c))
return PTR_ERR(c);

- entry = alloc_var_entry(c);
+ err = uverbs_get_flags32(&flags, attrs,
+ MLX5_IB_ATTR_VAR_OBJ_ALLOC_FLAGS,
+ MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP);
+ if (err)
+ return err;
+
+ if (flags & MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP) {
+ if (!MLX5_CAP_GEN(to_mdev(c->ibucontext.device)->mdev,
+ tlp_device_emulation_manager))
+ return -EOPNOTSUPP;
+ } else {
+ if (!(MLX5_CAP_GEN_64(to_mdev(c->ibucontext.device)->mdev,
+ general_obj_types) &
+ MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q))
+ return -EOPNOTSUPP;
+ }
+
+ entry = alloc_var_entry(c, flags);
if (IS_ERR(entry))
return PTR_ERR(entry);

@@ -4245,6 +4269,9 @@ DECLARE_UVERBS_NAMED_METHOD(
MLX5_IB_OBJECT_VAR,
UVERBS_ACCESS_NEW,
UA_MANDATORY),
+ UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_VAR_OBJ_ALLOC_FLAGS,
+ enum mlx5_ib_uapi_var_alloc_flags,
+ UA_OPTIONAL),
UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_VAR_OBJ_ALLOC_PAGE_ID,
UVERBS_ATTR_TYPE(u32),
UA_MANDATORY),
@@ -4272,7 +4299,8 @@ static bool var_is_supported(struct ib_device *device)
struct mlx5_ib_dev *dev = to_mdev(device);

return (MLX5_CAP_GEN_64(dev->mdev, general_obj_types) &
- MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q);
+ MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q) ||
+ MLX5_CAP_GEN(dev->mdev, tlp_device_emulation_manager);
}

static struct mlx5_user_mmap_entry *
diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
index 18f9fe070213..01a2a050e468 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -139,6 +139,7 @@ enum mlx5_ib_var_alloc_attrs {
MLX5_IB_ATTR_VAR_OBJ_ALLOC_MMAP_OFFSET,
MLX5_IB_ATTR_VAR_OBJ_ALLOC_MMAP_LENGTH,
MLX5_IB_ATTR_VAR_OBJ_ALLOC_PAGE_ID,
+ MLX5_IB_ATTR_VAR_OBJ_ALLOC_FLAGS,
};

enum mlx5_ib_var_obj_destroy_attrs {
diff --git a/include/uapi/rdma/mlx5_user_ioctl_verbs.h b/include/uapi/rdma/mlx5_user_ioctl_verbs.h
index 8f86e79d78a5..ef295b38a1cf 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -100,6 +100,10 @@ enum mlx5_ib_uapi_query_port_flags {
MLX5_IB_UAPI_QUERY_PORT_ESW_OWNER_VHCA_ID = 1 << 5,
};

+enum mlx5_ib_uapi_var_alloc_flags {
+ MLX5_IB_UAPI_VAR_ALLOC_FLAG_TLP = 1 << 0,
+};
+
struct mlx5_ib_uapi_reg {
__u32 value;
__u32 mask;

--
2.53.0