Skip to content

Commit c5ae195

Browse files
yishaihjgunthorpe
authored andcommitted
IB/mlx5: Use mlx5 core to create/destroy a DEVX DCT
To prevent a hardware memory leak when a DEVX DCT object is destroyed without calling DRAIN DCT before, (e.g. under cleanup flow), need to manage its creation and destruction via mlx5 core. In that case the DRAIN DCT command will be called and only once that it will be completed the DESTROY DCT command will be called. Otherwise, the DESTROY DCT may fail and a hardware leak may occur. As of that change the DRAIN DCT command should not be exposed any more from DEVX, it's managed internally by the driver to work as expected by the device specification. Fixes: 7efce36 ("IB/mlx5: Add obj create and destroy functionality") Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Reviewed-by: Artemy Kovalyov <artemyko@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
1 parent f84b66b commit c5ae195

File tree

4 files changed

+34
-13
lines changed
  • drivers
  • include/linux/mlx5

4 files changed

+34
-13
lines changed

drivers/infiniband/hw/mlx5/devx.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
enum devx_obj_flags {
2222
DEVX_OBJ_FLAGS_INDIRECT_MKEY = 1 << 0,
23+
DEVX_OBJ_FLAGS_DCT = 1 << 1,
2324
};
2425

2526
struct devx_async_data {
@@ -39,7 +40,10 @@ struct devx_obj {
3940
u32 dinlen; /* destroy inbox length */
4041
u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
4142
u32 flags;
42-
struct mlx5_ib_devx_mr devx_mr;
43+
union {
44+
struct mlx5_ib_devx_mr devx_mr;
45+
struct mlx5_core_dct core_dct;
46+
};
4347
};
4448

4549
struct devx_umem {
@@ -347,7 +351,6 @@ static u64 devx_get_obj_id(const void *in)
347351
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
348352
MLX5_GET(arm_rq_in, in, srq_number));
349353
break;
350-
case MLX5_CMD_OP_DRAIN_DCT:
351354
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
352355
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
353356
MLX5_GET(drain_dct_in, in, dctn));
@@ -618,7 +621,6 @@ static bool devx_is_obj_modify_cmd(const void *in)
618621
case MLX5_CMD_OP_2RST_QP:
619622
case MLX5_CMD_OP_ARM_XRC_SRQ:
620623
case MLX5_CMD_OP_ARM_RQ:
621-
case MLX5_CMD_OP_DRAIN_DCT:
622624
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
623625
case MLX5_CMD_OP_ARM_XRQ:
624626
case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
@@ -1124,7 +1126,11 @@ static int devx_obj_cleanup(struct ib_uobject *uobject,
11241126
if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
11251127
devx_cleanup_mkey(obj);
11261128

1127-
ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
1129+
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
1130+
ret = mlx5_core_destroy_dct(obj->mdev, &obj->core_dct);
1131+
else
1132+
ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out,
1133+
sizeof(out));
11281134
if (ib_is_destroy_retryable(ret, why, uobject))
11291135
return ret;
11301136

@@ -1185,9 +1191,17 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
11851191
devx_set_umem_valid(cmd_in);
11861192
}
11871193

1188-
err = mlx5_cmd_exec(dev->mdev, cmd_in,
1189-
cmd_in_len,
1190-
cmd_out, cmd_out_len);
1194+
if (opcode == MLX5_CMD_OP_CREATE_DCT) {
1195+
obj->flags |= DEVX_OBJ_FLAGS_DCT;
1196+
err = mlx5_core_create_dct(dev->mdev, &obj->core_dct,
1197+
cmd_in, cmd_in_len,
1198+
cmd_out, cmd_out_len);
1199+
} else {
1200+
err = mlx5_cmd_exec(dev->mdev, cmd_in,
1201+
cmd_in_len,
1202+
cmd_out, cmd_out_len);
1203+
}
1204+
11911205
if (err)
11921206
goto obj_free;
11931207

@@ -1214,7 +1228,11 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
12141228
if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
12151229
devx_cleanup_mkey(obj);
12161230
obj_destroy:
1217-
mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
1231+
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
1232+
mlx5_core_destroy_dct(obj->mdev, &obj->core_dct);
1233+
else
1234+
mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out,
1235+
sizeof(out));
12181236
obj_free:
12191237
kfree(obj);
12201238
return err;

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3729,6 +3729,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
37293729

37303730
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
37313731
struct mlx5_ib_modify_qp_resp resp = {};
3732+
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
37323733
u32 min_resp_len = offsetof(typeof(resp), dctn) +
37333734
sizeof(resp.dctn);
37343735

@@ -3747,7 +3748,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
37473748
MLX5_SET(dctc, dctc, hop_limit, attr->ah_attr.grh.hop_limit);
37483749

37493750
err = mlx5_core_create_dct(dev->mdev, &qp->dct.mdct, qp->dct.in,
3750-
MLX5_ST_SZ_BYTES(create_dct_in));
3751+
MLX5_ST_SZ_BYTES(create_dct_in), out,
3752+
sizeof(out));
37513753
if (err)
37523754
return err;
37533755
resp.dctn = qp->dct.mdct.mqp.qpn;

drivers/net/ethernet/mellanox/mlx5/core/qp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,16 @@ static int _mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
263263

264264
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
265265
struct mlx5_core_dct *dct,
266-
u32 *in, int inlen)
266+
u32 *in, int inlen,
267+
u32 *out, int outlen)
267268
{
268-
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
269269
struct mlx5_core_qp *qp = &dct->mqp;
270270
int err;
271271

272272
init_completion(&dct->drained);
273273
MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
274274

275-
err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
275+
err = mlx5_cmd_exec(dev, in, inlen, out, outlen);
276276
if (err) {
277277
mlx5_core_warn(dev, "create DCT failed, ret %d\n", err);
278278
return err;

include/linux/mlx5/qp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,8 @@ static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev,
557557

558558
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
559559
struct mlx5_core_dct *qp,
560-
u32 *in, int inlen);
560+
u32 *in, int inlen,
561+
u32 *out, int outlen);
561562
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
562563
struct mlx5_core_qp *qp,
563564
u32 *in,

0 commit comments

Comments
 (0)