All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anurag Mandal <anurag.mandal@intel.com>
To: dev@dpdk.org
Cc: bruce.richardson@intel.com, anatoly.burakov@intel.com,
	Anurag Mandal <anurag.mandal@intel.com>
Subject: [PATCH] net/ice: add per-queue Tx rate limit support
Date: Thu, 10 Sep 2026 10:04:32 +0000	[thread overview]
Message-ID: <20260910100432.207328-1-anurag.mandal@intel.com> (raw)

The Tx rate can be limited per queue with
ethdev operation ``rte_eth_set_queue_rate_limit()``
and can be read through ``rte_eth_get_queue_rate_limit()``.

This feature uses the hardware packet pacing
mechanism to enforce a data rate on individual
Tx queues without tearing down the queue.

The rate is specified in Mbps.

ice_set_queue_rate_limit() applies the requested rate
as the EIR (maximum bandwidth) limit of the queue
scheduler node using ice_cfg_q_bw_lmt(),
converting the Mbps value taken by the API to the Kbps
expected by the scheduler.
A rate of 0 removes the limit and restores the default
bandwidth via ice_cfg_q_bw_dflt_lmt().

ice_get_queue_rate_limit() reads back the value cached
in the queue context by the scheduler on a successful
set, and reports 0 when the queue runs unlimited.

Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
---
 doc/guides/nics/features/ice.ini       |  1 +
 doc/guides/rel_notes/release_26_11.rst |  3 +
 drivers/net/intel/ice/ice_ethdev.c     | 77 ++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index 893d09e9ec..6b21d56144 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -30,6 +30,7 @@ RSS hash             = Y
 RSS key update       = Y
 RSS reta update      = Y
 VLAN filter          = Y
+Rate limitation      = Y
 Traffic manager      = Y
 CRC offload          = Y
 VLAN offload         = Y
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 907f9013ff..1567f93563 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -64,6 +64,9 @@ New Features
   * Renamed the ``enable_ptype_lldp`` devarg to ``enable_lldp``.
     The old name is no longer accepted.
 
+* **Updated Intel ice driver.**
+
+  * Added support for Tx rate limiting per queue.
 
 Removed Items
 -------------
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 76b8ff0a72..8ae2842098 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -212,6 +212,10 @@ static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_
 						size_t *no_of_elements);
 static int ice_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info);
 static int ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf);
+static int ice_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t queue_idx,
+				    uint32_t tx_rate);
+static int ice_get_queue_rate_limit(struct rte_eth_dev *dev, uint16_t queue_idx,
+				    uint32_t *tx_rate);
 
 static const struct rte_pci_id pci_id_ice_map[] = {
 	{ RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -353,6 +357,8 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
 	.buffer_split_supported_hdr_ptypes_get = ice_buffer_split_supported_hdr_ptypes_get,
 	.get_dcb_info                 =	ice_get_dcb_info,
 	.priority_flow_ctrl_set       = ice_priority_flow_ctrl_set,
+	.set_queue_rate_limit         = ice_set_queue_rate_limit,
+	.get_queue_rate_limit         = ice_get_queue_rate_limit,
 };
 
 /* store statistics names and its offset in stats structure */
@@ -4205,6 +4211,77 @@ ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc
 	return 0;
 }
 
+static int
+ice_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t queue_idx,
+			 uint32_t tx_rate)
+{
+	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+	struct ice_vsi *vsi = pf->main_vsi;
+	int ret;
+
+	if (queue_idx >= dev->data->nb_tx_queues) {
+		PMD_DRV_LOG(ERR, "Tx queue %u is out of range (%u configured)",
+			    queue_idx, dev->data->nb_tx_queues);
+		return -EINVAL;
+	}
+
+	/* The scheduler node of a Tx queue only exists once the queue has been
+	 * added to the Tx scheduler tree, which happens on queue start.
+	 */
+	if (dev->data->tx_queue_state[queue_idx] != RTE_ETH_QUEUE_STATE_STARTED) {
+		PMD_DRV_LOG(ERR, "Tx queue %u must be started before setting its rate limit",
+			    queue_idx);
+		return -EINVAL;
+	}
+
+	/* Rate is expressed in Mbps by the API, the scheduler uses Kbps. */
+	if (tx_rate > ICE_SCHED_MAX_BW / 1000) {
+		PMD_DRV_LOG(ERR, "Invalid Tx rate %u Mbps for queue %u, maximum is %u Mbps",
+			    tx_rate, queue_idx, (uint32_t)(ICE_SCHED_MAX_BW / 1000));
+		return -EINVAL;
+	}
+
+	/* A rate of 0 removes the limit and restores the default bandwidth. */
+	if (tx_rate == 0)
+		ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, 0,
+					    queue_idx, ICE_MAX_BW);
+	else
+		ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, 0, queue_idx,
+				       ICE_MAX_BW, tx_rate * 1000);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to set Tx rate limit on queue %u, error %d",
+			    queue_idx, ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int
+ice_get_queue_rate_limit(struct rte_eth_dev *dev, uint16_t queue_idx,
+			 uint32_t *tx_rate)
+{
+	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+	struct ice_vsi *vsi = pf->main_vsi;
+	struct ice_q_ctx *q_ctx;
+
+	q_ctx = ice_get_lan_q_ctx(hw, vsi->idx, 0, queue_idx);
+	if (q_ctx == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to get the context of Tx queue %u",
+			    queue_idx);
+		return -EINVAL;
+	}
+
+	/* The scheduler caches the EIR limit in Kbps, and stores 0 when the
+	 * queue runs at the default (unlimited) bandwidth.
+	 */
+	*tx_rate = q_ctx->bw_t_info.eir_bw.bw / 1000;
+
+	return 0;
+}
+
 static void
 __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
 		       int base_queue, int nb_queue)
-- 
2.34.1


             reply	other threads:[~2026-09-10 10:02 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-10 10:04 Anurag Mandal [this message]
2026-09-10 10:29 ` [PATCH] net/ice: add per-queue Tx rate limit support Bruce Richardson
2026-09-15 10:19   ` Mandal, Anurag
2026-09-15 17:13     ` Bruce Richardson
2026-09-17  6:37       ` Mandal, Anurag
2026-09-17  6:38 ` [PATCH v2] " Anurag Mandal
2026-09-18 10:14   ` Bruce Richardson

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=20260910100432.207328-1-anurag.mandal@intel.com \
    --to=anurag.mandal@intel.com \
    --cc=anatoly.burakov@intel.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.