From: Edward Srouji <edwards@nvidia.com>
To: Leon Romanovsky <leon@kernel.org>,
Saeed Mahameed <saeedm@nvidia.com>,
Tariq Toukan <tariqt@nvidia.com>, Mark Bloch <mbloch@nvidia.com>,
"Jason Gunthorpe" <jgg@ziepe.ca>,
Selvin Xavier <selvin.xavier@broadcom.com>,
"Kalesh AP" <kalesh-anakkur.purayil@broadcom.com>,
Abhijit Gangurde <abhijit.gangurde@amd.com>,
Allen Hubbe <allen.hubbe@amd.com>
Cc: <linux-rdma@vger.kernel.org>, <netdev@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
Edward Srouji <edwards@nvidia.com>,
"Maher Sanalla" <msanalla@nvidia.com>,
Michael Guralnik <michaelgur@nvidia.com>
Subject: [PATCH rdma-next 3/8] RDMA/mlx5: Add support for rate limit in UD and UC QPs
Date: Sun, 24 May 2026 18:38:04 +0300 [thread overview]
Message-ID: <20260524-packet-pacing-v1-3-3d79439f8d08@nvidia.com> (raw)
In-Reply-To: <20260524-packet-pacing-v1-0-3d79439f8d08@nvidia.com>
From: Maher Sanalla <msanalla@nvidia.com>
Rate limiting is currently supported only for raw packet QPs, where
the packet pacing index is programmed into the SQC during SQ modify.
Extend rate limit support to UD and UC QPs by setting the pacing
index in the QPC during RTR2RTS and RTS2RTS transitions.
Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
---
drivers/infiniband/hw/mlx5/qp.c | 107 ++++++++++++++++++++++++++++------------
include/linux/mlx5/qp.h | 1 +
2 files changed, 76 insertions(+), 32 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index fde319a021908317d96f3cdd212ea5ebf691f13a..e96d26253e3b1fabee23947b1a61ab26e7c7067f 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -2725,6 +2725,10 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
if (err)
mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n",
base->mqp.qpn);
+ if (qp->rl.rate) {
+ mlx5_rl_remove_rate(dev->mdev, &qp->rl);
+ memset(&qp->rl, 0, sizeof(qp->rl));
+ }
}
destroy_qp(dev, qp, base, udata);
@@ -3673,8 +3677,10 @@ static enum mlx5_qp_optpar opt_mask[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE][MLX5_Q
MLX5_QP_OPTPAR_RNR_TIMEOUT,
[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH |
MLX5_QP_OPTPAR_RWE |
- MLX5_QP_OPTPAR_PM_STATE,
- [MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY,
+ MLX5_QP_OPTPAR_PM_STATE |
+ MLX5_QP_OPTPAR_PP_INDEX,
+ [MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY |
+ MLX5_QP_OPTPAR_PP_INDEX,
[MLX5_QP_ST_XRC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH |
MLX5_QP_OPTPAR_RRE |
MLX5_QP_OPTPAR_RAE |
@@ -3693,10 +3699,12 @@ static enum mlx5_qp_optpar opt_mask[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE][MLX5_Q
MLX5_QP_OPTPAR_ALT_ADDR_PATH,
[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_RWE |
MLX5_QP_OPTPAR_PM_STATE |
- MLX5_QP_OPTPAR_ALT_ADDR_PATH,
+ MLX5_QP_OPTPAR_ALT_ADDR_PATH |
+ MLX5_QP_OPTPAR_PP_INDEX,
[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY |
MLX5_QP_OPTPAR_SRQN |
- MLX5_QP_OPTPAR_CQN_RCV,
+ MLX5_QP_OPTPAR_CQN_RCV |
+ MLX5_QP_OPTPAR_PP_INDEX,
[MLX5_QP_ST_XRC] = MLX5_QP_OPTPAR_RRE |
MLX5_QP_OPTPAR_RAE |
MLX5_QP_OPTPAR_RWE |
@@ -3840,11 +3848,31 @@ static int modify_raw_packet_qp_rq(
return err;
}
+static bool qp_rate_limit_supported(struct mlx5_ib_dev *dev,
+ struct mlx5_ib_qp *qp)
+{
+ if (qp->type == IB_QPT_RAW_PACKET ||
+ qp->flags & IB_QP_CREATE_SOURCE_QPN)
+ return true;
+
+ if (qp->type == IB_QPT_UD)
+ return MLX5_CAP_QOS(dev->mdev, packet_pacing_req_ud);
+
+ if (qp->type == IB_QPT_UC)
+ return MLX5_CAP_QOS(dev->mdev, packet_pacing_req_uc);
+
+ return false;
+}
+
static int qp_rl_parse(struct mlx5_ib_dev *dev,
+ struct mlx5_ib_qp *qp,
const struct ib_qp_attr *attr,
const struct mlx5_ib_modify_qp *ucmd,
struct mlx5_rate_limit *rl_desired)
{
+ if (!qp_rate_limit_supported(dev, qp))
+ return -EOPNOTSUPP;
+
rl_desired->rate = attr->rate_limit;
if (ucmd->burst_info.max_burst_sz) {
@@ -3905,15 +3933,20 @@ static void qp_rl_rollback(struct mlx5_core_dev *dev,
static void qp_rl_commit(struct mlx5_core_dev *dev,
struct mlx5_ib_qp *qp,
- struct mlx5_rate_limit_ctx *ctx)
+ struct mlx5_rate_limit_ctx *ctx,
+ enum ib_qp_state new_state)
{
- if (!ctx->rl_changed)
- return;
-
- if (ctx->rl_old.rate)
- mlx5_rl_remove_rate(dev, &ctx->rl_old);
+ if (ctx->rl_changed) {
+ if (ctx->rl_old.rate)
+ mlx5_rl_remove_rate(dev, &ctx->rl_old);
+ qp->rl = ctx->rl_desired;
+ }
- qp->rl = ctx->rl_desired;
+ if (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR) {
+ if (qp->rl.rate)
+ mlx5_rl_remove_rate(dev, &qp->rl);
+ memset(&qp->rl, 0, sizeof(qp->rl));
+ }
}
static int modify_raw_packet_qp_sq(
@@ -4220,6 +4253,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
struct mlx5_ib_qp *qp = to_mqp(ibqp);
struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
struct mlx5_ib_cq *send_cq, *recv_cq;
+ struct mlx5_rate_limit_ctx rl_ctx = {};
struct mlx5_ib_pd *pd;
enum mlx5_qp_state mlx5_cur, mlx5_new;
void *qpc, *pri_path, *alt_path;
@@ -4410,20 +4444,31 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
goto out;
}
+ if (attr_mask & IB_QP_RATE_LIMIT) {
+ err = qp_rl_parse(dev, qp, attr, ucmd, &rl_ctx.rl_desired);
+ if (err)
+ goto out;
+ } else {
+ rl_ctx.rl_desired = qp->rl;
+ }
+
op = optab[mlx5_cur][mlx5_new];
+ if (!mlx5_rl_are_equal(&rl_ctx.rl_desired, &qp->rl)) {
+ err = qp_rl_prepare(dev, qp, op, &rl_ctx);
+ if (err)
+ goto out;
+ }
optpar |= ib_mask_to_mlx5_opt(attr_mask);
+ if (rl_ctx.rl_changed)
+ optpar |= MLX5_QP_OPTPAR_PP_INDEX;
optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st];
- if (attr_mask & IB_QP_RATE_LIMIT && qp->type != IB_QPT_RAW_PACKET) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
if (qp->type == IB_QPT_RAW_PACKET ||
qp->flags & IB_QP_CREATE_SOURCE_QPN) {
struct mlx5_modify_raw_qp_param raw_qp_param = {};
raw_qp_param.operation = op;
+ raw_qp_param.rl_ctx = rl_ctx;
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
raw_qp_param.rq_q_ctr_id = set_id;
raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;
@@ -4432,22 +4477,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
if (attr_mask & IB_QP_PORT)
raw_qp_param.port = attr->port_num;
- if (attr_mask & IB_QP_RATE_LIMIT) {
- err = qp_rl_parse(dev, qp, attr, ucmd,
- &raw_qp_param.rl_ctx.rl_desired);
- if (err)
- goto out;
-
- if (!mlx5_rl_are_equal(&raw_qp_param.rl_ctx.rl_desired,
- &qp->rl)) {
- err = qp_rl_prepare(dev, qp, op,
- &raw_qp_param.rl_ctx);
- if (err)
- goto out;
- }
-
+ if (rl_ctx.rl_changed)
raw_qp_param.set_mask |= MLX5_RAW_QP_RATE_LIMIT;
- }
err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
if (err) {
@@ -4455,8 +4486,13 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
goto out;
}
- qp_rl_commit(dev->mdev, qp, &raw_qp_param.rl_ctx);
+ qp_rl_commit(dev->mdev, qp, &raw_qp_param.rl_ctx, new_state);
} else {
+ if (rl_ctx.rl_changed) {
+ MLX5_SET(qpc, qpc, packet_pacing_rate_limit_index,
+ rl_ctx.rl_desired_index);
+ }
+
if (udata) {
/* For the kernel flows, the resp will stay zero */
resp->ece_options =
@@ -4466,6 +4502,13 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
}
err = mlx5_core_qp_modify(dev, op, optpar, qpc, &base->mqp,
&resp->ece_options);
+
+ if (err) {
+ qp_rl_rollback(dev->mdev, &rl_ctx);
+ goto out;
+ }
+
+ qp_rl_commit(dev->mdev, qp, &rl_ctx, new_state);
}
if (err)
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index d67aedc6ea68ae9f514a1de11626792bfe847c04..40f889403b075ebc6b860705206843aafa5d9a32 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -72,6 +72,7 @@ enum mlx5_qp_optpar {
MLX5_QP_OPTPAR_CQN_RCV = 1 << 19,
MLX5_QP_OPTPAR_DC_HS = 1 << 20,
MLX5_QP_OPTPAR_DC_KEY = 1 << 21,
+ MLX5_QP_OPTPAR_PP_INDEX = 1 << 22,
MLX5_QP_OPTPAR_COUNTER_SET_ID = 1 << 25,
};
--
2.49.0
next prev parent reply other threads:[~2026-05-24 15:39 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-24 15:38 [PATCH rdma-next 0/8] RDMA: Extend packet pacing support to " Edward Srouji
2026-05-24 15:38 ` [PATCH rdma-next 1/8] net/mlx5: Add UD and UC packet pacing caps Edward Srouji
2026-05-24 15:38 ` [PATCH rdma-next 2/8] RDMA/mlx5: Refactor raw packet QP rate limit handling Edward Srouji
2026-05-24 15:38 ` Edward Srouji [this message]
2026-05-24 15:38 ` [PATCH rdma-next 4/8] RDMA/mlx5: Support deferred rate limit configuration Edward Srouji
2026-05-24 15:38 ` [PATCH rdma-next 5/8] RDMA/mlx5: Report packet pacing capabilities when querying device Edward Srouji
2026-05-24 15:38 ` [PATCH rdma-next 6/8] RDMA/bnxt_re: Validate rate limit attribute in modify QP Edward Srouji
2026-05-24 15:38 ` [PATCH rdma-next 7/8] RDMA/ionic: " Edward Srouji
2026-05-24 15:38 ` [PATCH rdma-next 8/8] IB/core: Delegate IB_QP_RATE_LIMIT validation to drivers Edward Srouji
2026-06-11 11:06 ` [PATCH rdma-next 0/8] RDMA: Extend packet pacing support to UD and UC QPs Leon Romanovsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260524-packet-pacing-v1-3-3d79439f8d08@nvidia.com \
--to=edwards@nvidia.com \
--cc=abhijit.gangurde@amd.com \
--cc=allen.hubbe@amd.com \
--cc=jgg@ziepe.ca \
--cc=kalesh-anakkur.purayil@broadcom.com \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mbloch@nvidia.com \
--cc=michaelgur@nvidia.com \
--cc=msanalla@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=saeedm@nvidia.com \
--cc=selvin.xavier@broadcom.com \
--cc=tariqt@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®