Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/mlx5: Use mlx5_cmd_do() in core create_{cq,dct}

mlx5_core_create_{cq/dct} functions are non-trivial mlx5 commands
functions. They check command execution status themselves and hide
valuable FW failure information.

For mlx5_core/eth kernel user this is what we actually want, but for a
devx/rdma user the hidden information is essential and should be propagated
up to the caller, thus we convert these commands to use mlx5_cmd_do
to return the FW/driver and command outbox status as is, and let the caller
decide what to do with it.

For kernel callers of mlx5_core_create_{cq/dct} or those who only care about
the binary status (FAIL/SUCCESS) they must check status themselves via
mlx5_cmd_check() to restore the current behavior.

err = mlx5_create_cq(in, out)
err = mlx5_cmd_check(err, in, out)
if (err)
// handle err

For DEVX users and those who care about full visibility, They will just
propagate the error to user space, and app can check if err == -EREMOTEIO,
then outbox.{status,syndrome} are valid.

API Note:
mlx5_cmd_check() must be used by kernel users since it allows the driver
to intercept the command execution status and return a driver simulated
status in case of driver induced error handling or reset/recovery flows.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>

authored by

Saeed Mahameed and committed by
Saeed Mahameed
31803e59 f23519e5

+21 -7
+3 -3
drivers/infiniband/hw/mlx5/devx.c
··· 1497 1497 !is_apu_cq(dev, cmd_in)) { 1498 1498 obj->flags |= DEVX_OBJ_FLAGS_CQ; 1499 1499 obj->core_cq.comp = devx_cq_comp; 1500 - err = mlx5_core_create_cq(dev->mdev, &obj->core_cq, 1501 - cmd_in, cmd_in_len, cmd_out, 1502 - cmd_out_len); 1500 + err = mlx5_create_cq(dev->mdev, &obj->core_cq, 1501 + cmd_in, cmd_in_len, cmd_out, 1502 + cmd_out_len); 1503 1503 } else { 1504 1504 err = mlx5_cmd_exec(dev->mdev, cmd_in, 1505 1505 cmd_in_len,
+1
drivers/infiniband/hw/mlx5/qp.c
··· 4465 4465 err = mlx5_core_create_dct(dev, &qp->dct.mdct, qp->dct.in, 4466 4466 MLX5_ST_SZ_BYTES(create_dct_in), out, 4467 4467 sizeof(out)); 4468 + err = mlx5_cmd_check(dev->mdev, err, qp->dct.in, out); 4468 4469 if (err) 4469 4470 return err; 4470 4471 resp.dctn = qp->dct.mdct.mqp.qpn;
+1 -1
drivers/infiniband/hw/mlx5/qpc.c
··· 220 220 init_completion(&dct->drained); 221 221 MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT); 222 222 223 - err = mlx5_cmd_exec(dev->mdev, in, inlen, out, outlen); 223 + err = mlx5_cmd_do(dev->mdev, in, inlen, out, outlen); 224 224 if (err) 225 225 return err; 226 226
+14 -3
drivers/net/ethernet/mellanox/mlx5/core/cq.c
··· 86 86 spin_unlock_irqrestore(&tasklet_ctx->lock, flags); 87 87 } 88 88 89 - int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 90 - u32 *in, int inlen, u32 *out, int outlen) 89 + /* Callers must verify outbox status in case of err */ 90 + int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 91 + u32 *in, int inlen, u32 *out, int outlen) 91 92 { 92 93 int eqn = MLX5_GET(cqc, MLX5_ADDR_OF(create_cq_in, in, cq_context), 93 94 c_eqn_or_apu_element); ··· 102 101 103 102 memset(out, 0, outlen); 104 103 MLX5_SET(create_cq_in, in, opcode, MLX5_CMD_OP_CREATE_CQ); 105 - err = mlx5_cmd_exec(dev, in, inlen, out, outlen); 104 + err = mlx5_cmd_do(dev, in, inlen, out, outlen); 106 105 if (err) 107 106 return err; 108 107 ··· 148 147 MLX5_SET(destroy_cq_in, din, uid, cq->uid); 149 148 mlx5_cmd_exec_in(dev, destroy_cq, din); 150 149 return err; 150 + } 151 + EXPORT_SYMBOL(mlx5_create_cq); 152 + 153 + /* oubox is checked and err val is normalized */ 154 + int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 155 + u32 *in, int inlen, u32 *out, int outlen) 156 + { 157 + int err = mlx5_create_cq(dev, cq, in, inlen, out, outlen); 158 + 159 + return mlx5_cmd_check(dev, err, in, out); 151 160 } 152 161 EXPORT_SYMBOL(mlx5_core_create_cq); 153 162
+2
include/linux/mlx5/cq.h
··· 183 183 complete(&cq->free); 184 184 } 185 185 186 + int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 187 + u32 *in, int inlen, u32 *out, int outlen); 186 188 int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 187 189 u32 *in, int inlen, u32 *out, int outlen); 188 190 int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);