From: Maher Sanalla Date: Sun, 24 May 2026 15:38:05 +0000 (+0300) Subject: RDMA/mlx5: Support deferred rate limit configuration X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=915bbc8578e3f784b35bd9e5fa06a3b0720eb292;p=thirdparty%2Flinux.git RDMA/mlx5: Support deferred rate limit configuration 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 Link: https://patch.msgid.link/20260524-packet-pacing-v1-4-3d79439f8d08@nvidia.com Signed-off-by: Leon Romanovsky --- diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 0550cdfacad4e..522984d958bbf 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -540,6 +540,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 1f8d6dd6057c6..0725d1161c40d 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -3976,7 +3976,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( @@ -4020,6 +4024,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; @@ -4479,7 +4484,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]; @@ -4863,6 +4868,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,