]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDMA/mlx5: Support deferred rate limit configuration
authorMaher Sanalla <msanalla@nvidia.com>
Sun, 24 May 2026 15:38:05 +0000 (18:38 +0300)
committerLeon Romanovsky <leon@kernel.org>
Thu, 11 Jun 2026 11:02:05 +0000 (07:02 -0400)
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 <msanalla@nvidia.com>
Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260524-packet-pacing-v1-4-3d79439f8d08@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/qp.c

index 0550cdfacad4ece8335660bbac96086d6d3e3d42..522984d958bbfc1755cfefa485dbff53a42eae6e 100644 (file)
@@ -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;
        /*
index 1f8d6dd6057c6ffa12a251d57cad3e44de33913b..0725d1161c40d605b658eb383b1f8c4b2d0e2fb7 100644 (file)
@@ -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,