From: Maher Sanalla Allow passing a rate limit attribute in modify QP flows even when the QP is in a state that does not support packet pacing programming in the lower layers. When the user sets a rate limit during a QP transition that is not to RTS, store the value in the mlx5 QP struct and program it to FW when the QP later transitions to RTS, which is the state that allows configuring the rate limit index in the QP context. Signed-off-by: Maher Sanalla Reviewed-by: Michael Guralnik Signed-off-by: Edward Srouji --- drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 + drivers/infiniband/hw/mlx5/qp.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index e156dc4d752996cc4ae465bb567b0c1305d07fed..c74a53da99393cf4d4c0823cd12f9eccaa28f212 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -536,6 +536,7 @@ struct mlx5_ib_qp { struct list_head cq_recv_list; struct list_head cq_send_list; struct mlx5_rate_limit rl; + struct mlx5_rate_limit rl_desired; u32 underlay_qpn; u32 flags_en; /* diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index e96d26253e3b1fabee23947b1a61ab26e7c7067f..66ab16b017c8311d44b521c023cfaf23ac42190a 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -3946,7 +3946,11 @@ static void qp_rl_commit(struct mlx5_core_dev *dev, if (qp->rl.rate) mlx5_rl_remove_rate(dev, &qp->rl); memset(&qp->rl, 0, sizeof(qp->rl)); + memset(&qp->rl_desired, 0, sizeof(qp->rl_desired)); + return; } + + qp->rl_desired = ctx->rl_desired; } static int modify_raw_packet_qp_sq( @@ -3990,6 +3994,7 @@ static int modify_raw_packet_qp_sq( if (new_state != MLX5_SQC_STATE_RDY) { mlx5_rl_remove_rate(dev, &ibqp->rl); memset(&ibqp->rl, 0, sizeof(ibqp->rl)); + memset(&ibqp->rl_desired, 0, sizeof(ibqp->rl_desired)); } sq->state = new_state; @@ -4449,7 +4454,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, if (err) goto out; } else { - rl_ctx.rl_desired = qp->rl; + rl_ctx.rl_desired = qp->rl_desired; } op = optab[mlx5_cur][mlx5_new]; @@ -4833,6 +4838,13 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, attr_mask); goto out; } + } else if (attr_mask == IB_QP_RATE_LIMIT && cur_state != IB_QPS_RTS) { + struct mlx5_rate_limit rl_desired = {}; + + err = qp_rl_parse(dev, qp, attr, &ucmd, &rl_desired); + if (!err) + qp->rl_desired = rl_desired; + goto out; } else if (qp_type != MLX5_IB_QPT_REG_UMR && qp_type != MLX5_IB_QPT_DCI && !ib_modify_qp_is_ok(cur_state, new_state, qp_type, -- 2.49.0