net/mlx5: Use mlx5_cmd_do() in core create_{cq,dct}
authorSaeed Mahameed <saeedm@mellanox.com>
Tue, 31 Mar 2020 04:12:58 +0000 (21:12 -0700)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 23 Feb 2022 23:21:59 +0000 (15:21 -0800)
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>
drivers/infiniband/hw/mlx5/devx.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/mlx5/qpc.c
drivers/net/ethernet/mellanox/mlx5/core/cq.c
include/linux/mlx5/cq.h

index 08b7f6bc56c37a628aae752f889bfae24ae6fe56..1f62c0ede0480b55b1211d49d0c8c51da3691841 100644 (file)
@@ -1497,9 +1497,9 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
                   !is_apu_cq(dev, cmd_in)) {
                obj->flags |= DEVX_OBJ_FLAGS_CQ;
                obj->core_cq.comp = devx_cq_comp;
-               err = mlx5_core_create_cq(dev->mdev, &obj->core_cq,
-                                         cmd_in, cmd_in_len, cmd_out,
-                                         cmd_out_len);
+               err = mlx5_create_cq(dev->mdev, &obj->core_cq,
+                                    cmd_in, cmd_in_len, cmd_out,
+                                    cmd_out_len);
        } else {
                err = mlx5_cmd_exec(dev->mdev, cmd_in,
                                    cmd_in_len,
index 29475cf8c7c3571ce7b2515a9d6a9312dc1f79ac..b7fe47107d7667f66372e23b44e3b461e34c16eb 100644 (file)
@@ -4465,6 +4465,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                err = mlx5_core_create_dct(dev, &qp->dct.mdct, qp->dct.in,
                                           MLX5_ST_SZ_BYTES(create_dct_in), out,
                                           sizeof(out));
+               err = mlx5_cmd_check(dev->mdev, err, qp->dct.in, out);
                if (err)
                        return err;
                resp.dctn = qp->dct.mdct.mqp.qpn;
index 8844eacf2380e34699fd6707b326baa47e9ad506..542e4c63a8de61a7e9702314ce3bff3962b09ab1 100644 (file)
@@ -220,7 +220,7 @@ int mlx5_core_create_dct(struct mlx5_ib_dev *dev, struct mlx5_core_dct *dct,
        init_completion(&dct->drained);
        MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
 
-       err = mlx5_cmd_exec(dev->mdev, in, inlen, out, outlen);
+       err = mlx5_cmd_do(dev->mdev, in, inlen, out, outlen);
        if (err)
                return err;
 
index 5371ad0a12eb5651e3227edb1ad785b49c25a0d3..15a74966be7d567b1ede35e7806e1e9c01a44042 100644 (file)
@@ -86,8 +86,9 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq,
        spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
 }
 
-int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
-                       u32 *in, int inlen, u32 *out, int outlen)
+/* Callers must verify outbox status in case of err */
+int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+                  u32 *in, int inlen, u32 *out, int outlen)
 {
        int eqn = MLX5_GET(cqc, MLX5_ADDR_OF(create_cq_in, in, cq_context),
                           c_eqn_or_apu_element);
@@ -101,7 +102,7 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
 
        memset(out, 0, outlen);
        MLX5_SET(create_cq_in, in, opcode, MLX5_CMD_OP_CREATE_CQ);
-       err = mlx5_cmd_exec(dev, in, inlen, out, outlen);
+       err = mlx5_cmd_do(dev, in, inlen, out, outlen);
        if (err)
                return err;
 
@@ -148,6 +149,16 @@ err_cmd:
        mlx5_cmd_exec_in(dev, destroy_cq, din);
        return err;
 }
+EXPORT_SYMBOL(mlx5_create_cq);
+
+/* oubox is checked and err val is normalized */
+int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+                       u32 *in, int inlen, u32 *out, int outlen)
+{
+       int err = mlx5_create_cq(dev, cq, in, inlen, out, outlen);
+
+       return mlx5_cmd_check(dev, err, in, out);
+}
 EXPORT_SYMBOL(mlx5_core_create_cq);
 
 int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
index 7bfb67363434224aded467c2587ed78fce7b1d1f..cb15308b5cb0bc96dccb89ceb82f3a6186200dad 100644 (file)
@@ -183,6 +183,8 @@ static inline void mlx5_cq_put(struct mlx5_core_cq *cq)
                complete(&cq->free);
 }
 
+int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+                  u32 *in, int inlen, u32 *out, int outlen);
 int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
                        u32 *in, int inlen, u32 *out, int outlen);
 int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);