Skip to content

Commit 7c891a4

Browse files
PatrisiousHaddadrleon
authored andcommitted
RDMA/mlx5: Add implementation for ufile_hw_cleanup device operation
Implement the device API for ufile_hw_cleanup operation, which iterates over the ufile uobjects lists, and attempts to destroy DevX QPs, by issuing up to 8 commands in parallel. This function is responsible only for cleaning the FW resources of the QP, and doesn't necessarily cleanup all of its resources. Hence the normal serialized cleanup flow is still executed after it in __uverbs_cleanup_ufile() to cleanup the remaining resources and handle the cleanup of SW objects. In order to avoid double cleanup for the FW resources, new DevX flag was added DEVX_OBJ_FLAGS_HW_FREED, which marks the object's FW resources as already freed. Since QP destruction is the most time-consuming operation in FW, parallelizing it reduces the cleanup time of applications that use DevX QPs. Signed-off-by: Patrisious Haddad <[email protected]> Link: https://patch.msgid.link/2f82675d0412542cba1c47a6b86f589521ae41e1.1730373303.git.leon@kernel.org Signed-off-by: Leon Romanovsky <[email protected]>
1 parent 27ed2f0 commit 7c891a4

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

drivers/infiniband/hw/mlx5/devx.c

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ enum devx_obj_flags {
2727
DEVX_OBJ_FLAGS_INDIRECT_MKEY = 1 << 0,
2828
DEVX_OBJ_FLAGS_DCT = 1 << 1,
2929
DEVX_OBJ_FLAGS_CQ = 1 << 2,
30+
DEVX_OBJ_FLAGS_HW_FREED = 1 << 3,
31+
};
32+
33+
#define MAX_ASYNC_CMDS 8
34+
35+
struct mlx5_async_cmd {
36+
struct ib_uobject *uobject;
37+
void *in;
38+
int in_size;
39+
u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
40+
int err;
41+
struct mlx5_async_work cb_work;
42+
struct completion comp;
3043
};
3144

3245
struct devx_async_data {
@@ -1405,7 +1418,9 @@ static int devx_obj_cleanup(struct ib_uobject *uobject,
14051418
*/
14061419
mlx5r_deref_wait_odp_mkey(&obj->mkey);
14071420

1408-
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
1421+
if (obj->flags & DEVX_OBJ_FLAGS_HW_FREED)
1422+
ret = 0;
1423+
else if (obj->flags & DEVX_OBJ_FLAGS_DCT)
14091424
ret = mlx5_core_destroy_dct(obj->ib_dev, &obj->core_dct);
14101425
else if (obj->flags & DEVX_OBJ_FLAGS_CQ)
14111426
ret = mlx5_core_destroy_cq(obj->ib_dev->mdev, &obj->core_cq);
@@ -2595,6 +2610,82 @@ void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev)
25952610
}
25962611
}
25972612

2613+
static void devx_async_destroy_cb(int status, struct mlx5_async_work *context)
2614+
{
2615+
struct mlx5_async_cmd *devx_out = container_of(context,
2616+
struct mlx5_async_cmd, cb_work);
2617+
struct devx_obj *obj = devx_out->uobject->object;
2618+
2619+
if (!status)
2620+
obj->flags |= DEVX_OBJ_FLAGS_HW_FREED;
2621+
2622+
complete(&devx_out->comp);
2623+
}
2624+
2625+
static void devx_async_destroy(struct mlx5_ib_dev *dev,
2626+
struct mlx5_async_cmd *cmd)
2627+
{
2628+
init_completion(&cmd->comp);
2629+
cmd->err = mlx5_cmd_exec_cb(&dev->async_ctx, cmd->in, cmd->in_size,
2630+
&cmd->out, sizeof(cmd->out),
2631+
devx_async_destroy_cb, &cmd->cb_work);
2632+
}
2633+
2634+
static void devx_wait_async_destroy(struct mlx5_async_cmd *cmd)
2635+
{
2636+
if (!cmd->err)
2637+
wait_for_completion(&cmd->comp);
2638+
atomic_set(&cmd->uobject->usecnt, 0);
2639+
}
2640+
2641+
void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
2642+
{
2643+
struct mlx5_async_cmd async_cmd[MAX_ASYNC_CMDS];
2644+
struct ib_ucontext *ucontext = ufile->ucontext;
2645+
struct ib_device *device = ucontext->device;
2646+
struct mlx5_ib_dev *dev = to_mdev(device);
2647+
struct ib_uobject *uobject;
2648+
struct devx_obj *obj;
2649+
int head = 0;
2650+
int tail = 0;
2651+
2652+
list_for_each_entry(uobject, &ufile->uobjects, list) {
2653+
WARN_ON(uverbs_try_lock_object(uobject, UVERBS_LOOKUP_WRITE));
2654+
2655+
/*
2656+
* Currently we only support QP destruction, if other objects
2657+
* are to be destroyed need to add type synchronization to the
2658+
* cleanup algorithm and handle pre/post FW cleanup for the
2659+
* new types if needed.
2660+
*/
2661+
if (uobj_get_object_id(uobject) != MLX5_IB_OBJECT_DEVX_OBJ ||
2662+
(get_dec_obj_type(uobject->object, MLX5_EVENT_TYPE_MAX) !=
2663+
MLX5_OBJ_TYPE_QP)) {
2664+
atomic_set(&uobject->usecnt, 0);
2665+
continue;
2666+
}
2667+
2668+
obj = uobject->object;
2669+
2670+
async_cmd[tail % MAX_ASYNC_CMDS].in = obj->dinbox;
2671+
async_cmd[tail % MAX_ASYNC_CMDS].in_size = obj->dinlen;
2672+
async_cmd[tail % MAX_ASYNC_CMDS].uobject = uobject;
2673+
2674+
devx_async_destroy(dev, &async_cmd[tail % MAX_ASYNC_CMDS]);
2675+
tail++;
2676+
2677+
if (tail - head == MAX_ASYNC_CMDS) {
2678+
devx_wait_async_destroy(&async_cmd[head % MAX_ASYNC_CMDS]);
2679+
head++;
2680+
}
2681+
}
2682+
2683+
while (head != tail) {
2684+
devx_wait_async_destroy(&async_cmd[head % MAX_ASYNC_CMDS]);
2685+
head++;
2686+
}
2687+
}
2688+
25982689
static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,
25992690
size_t count, loff_t *pos)
26002691
{

drivers/infiniband/hw/mlx5/devx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user);
2828
void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid);
2929
int mlx5_ib_devx_init(struct mlx5_ib_dev *dev);
3030
void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev);
31+
void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile);
3132
#else
3233
static inline int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
3334
{
@@ -41,5 +42,8 @@ static inline int mlx5_ib_devx_init(struct mlx5_ib_dev *dev)
4142
static inline void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev)
4243
{
4344
}
45+
static inline void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
46+
{
47+
}
4448
#endif
4549
#endif /* _MLX5_IB_DEVX_H */

drivers/infiniband/hw/mlx5/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4149,6 +4149,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
41494149
.req_notify_cq = mlx5_ib_arm_cq,
41504150
.rereg_user_mr = mlx5_ib_rereg_user_mr,
41514151
.resize_cq = mlx5_ib_resize_cq,
4152+
.ufile_hw_cleanup = mlx5_ib_ufile_hw_cleanup,
41524153

41534154
INIT_RDMA_OBJ_SIZE(ib_ah, mlx5_ib_ah, ibah),
41544155
INIT_RDMA_OBJ_SIZE(ib_counters, mlx5_ib_mcounters, ibcntrs),

0 commit comments

Comments
 (0)