patch 'net/bnxt: fix Rx packet stall' has been queued to stable release 24.11.9

luca.boccassi at gmail.com luca.boccassi at gmail.com
Thu Nov 5 17:41:59 CET 2026


Hi,

FYI, your patch has been queued to stable release 24.11.9

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 11/07/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable

This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/7af4cd7f106c98cc43551c22af21e215e7de8294

Thanks.

Luca Boccassi

---
>From 7af4cd7f106c98cc43551c22af21e215e7de8294 Mon Sep 17 00:00:00 2001
From: Shuanglin Wang <shuanglin.wang at broadcom.com>
Date: Mon, 26 Oct 2026 13:12:47 -0600
Subject: [PATCH] net/bnxt: fix Rx packet stall

[ upstream commit 3c0d14981397a5854328267b7b082c284951c7eb ]

Rx on Thor could stop delivering packets. Independent issues in the
doorbell and vectorized Rx paths combined to cause this:

- bnxt_db_epoch_write(), bnxt_db_mpc_write() and bnxt_db_mpc_cq()
  always OR'd the epoch bit into the doorbell key, even on rings
  whose db_epoch_mask is unset (every chip but P7). On those rings
  the epoch bit lands in doorbell key space the firmware interprets
  differently, corrupting the doorbell write. Only apply the epoch bit
  when db_epoch_mask is set, and shift the epoch value as a 64 bit
  quantity.

- The AVX2, SSE and NEON Rx wrappers split a request into chunks of
  rx_free_thresh packets. A small rx_free_thresh could force chunks
  narrower than one vector loop, so clamp the chunk size to at least
  one vector loop width.

- bnxt_rxq_rearm() computes nb from rxrearm_nb & ~0x3, which is zero
  whenever fewer than four mbufs need rearming. It then fell through
  and rang the doorbell a second time with no new descriptors posted.
  Return early when nb is zero.

Fixes: 30656a1cace8 ("net/bnxt: refactor epoch setting")

Signed-off-by: Shuanglin Wang <shuanglin.wang at broadcom.com>
Signed-off-by: Mohammad Shuab Siddique <mohammad-shuab.siddique at broadcom.com>
---
 drivers/net/bnxt/bnxt_ring.h            | 15 ++++++++++-----
 drivers/net/bnxt/bnxt_rxtx_vec_common.h |  2 ++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 3e2bd634a8a..969e9fa993c 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -116,7 +116,8 @@ static inline void bnxt_db_epoch_write(struct bnxt_db_info *db, uint32_t idx, ui
 	if (db->db_64) {
 		uint64_t key_idx = db->db_key64 | db_idx;
 
-		key_idx |= epoch << DBR_EPOCH_SFT;
+		if (db->db_epoch_mask)
+			key_idx |= ((uint64_t)epoch << DBR_EPOCH_SFT);
 
 		rte_compiler_barrier();
 		rte_write64_relaxed(key_idx, doorbell);
@@ -133,8 +134,10 @@ static inline void bnxt_db_mpc_write(struct bnxt_db_info *db, uint32_t idx, uint
 	void *doorbell = db->doorbell;
 
 	if (likely(db->db_64)) {
-		uint64_t key_idx = db->db_key64 | db_idx |
-			(epoch << 24);
+		uint64_t key_idx = db->db_key64 | db_idx;
+
+		if (db->db_epoch_mask)
+			key_idx |= ((uint64_t)epoch << 24);
 		rte_write64_relaxed(key_idx, doorbell);
 	} else {
 		uint32_t key_idx = db->db_key32 | db_idx;
@@ -195,8 +198,10 @@ static inline void bnxt_db_mpc_cq(struct bnxt_cp_ring_info *cpr)
 	uint32_t idx = DB_RING_IDX(&cpr->cp_db, cpr->cp_raw_cons);
 
 	if (likely(db->db_64)) {
-		uint64_t key_idx = db->db_key64 | idx |
-			(cpr->epoch << 24);
+		uint64_t key_idx = db->db_key64 | idx;
+
+		if (db->db_epoch_mask)
+			key_idx |= ((uint64_t)cpr->epoch << 24);
 		void *doorbell = db->doorbell;
 
 		rte_compiler_barrier();
diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_common.h b/drivers/net/bnxt/bnxt_rxtx_vec_common.h
index e1850052930..1823fa69894 100644
--- a/drivers/net/bnxt/bnxt_rxtx_vec_common.h
+++ b/drivers/net/bnxt/bnxt_rxtx_vec_common.h
@@ -67,6 +67,8 @@ bnxt_rxq_rearm(struct bnxt_rx_queue *rxq, struct bnxt_rx_ring_info *rxr)
 	 */
 	nb = RTE_MIN(rxq->rxrearm_nb & ~0x3,
 		     rxq->nb_rx_desc - rxq->rxrearm_start);
+	if (unlikely(nb == 0))
+		return;
 
 	/* Allocate new mbufs into the software ring. */
 	if (rte_mempool_get_bulk(rxq->mb_pool, (void *)rx_bufs, nb) < 0) {
-- 
2.47.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-11-05 16:42:46.254423374 +0000
+++ 0032-net-bnxt-fix-Rx-packet-stall.patch	2026-11-05 16:42:44.933061145 +0000
@@ -1 +1 @@
-From 3c0d14981397a5854328267b7b082c284951c7eb Mon Sep 17 00:00:00 2001
+From 7af4cd7f106c98cc43551c22af21e215e7de8294 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 3c0d14981397a5854328267b7b082c284951c7eb ]
+
@@ -28 +29,0 @@
-Cc: stable at dpdk.org
@@ -34 +34,0 @@
- drivers/net/bnxt/bnxt_rxtx_vec_avx2.c   |  9 ++++++---
@@ -36,3 +36 @@
- drivers/net/bnxt/bnxt_rxtx_vec_neon.c   |  3 ++-
- drivers/net/bnxt/bnxt_rxtx_vec_sse.c    |  6 ++++--
- 5 files changed, 24 insertions(+), 11 deletions(-)
+ 2 files changed, 12 insertions(+), 5 deletions(-)
@@ -41 +39 @@
-index d710d85371..d63ae8d8f8 100644
+index 3e2bd634a8a..969e9fa993c 100644
@@ -80,34 +77,0 @@
-diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
-index 1236d3c2fe..96ca3f4f07 100644
---- a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
-+++ b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
-@@ -685,7 +685,8 @@ bnxt_recv_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
- 			 uint16_t nb_pkts)
- {
- 	struct bnxt_rx_queue *rxq = rx_queue;
--	uint32_t brst = rxq->rx_free_thresh;
-+	uint16_t brst = (uint16_t)RTE_MAX((uint32_t)rxq->rx_free_thresh,
-+					   BNXT_RX_DESCS_PER_LOOP_VEC256);
- 	uint16_t cnt = 0;
- 
- 	while (nb_pkts > brst) {
-@@ -707,7 +708,8 @@ bnxt_crx_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
- 		       uint16_t nb_pkts)
- {
- 	struct bnxt_rx_queue *rxq = rx_queue;
--	uint32_t brst = rxq->rx_free_thresh;
-+	uint16_t brst = (uint16_t)RTE_MAX((uint32_t)rxq->rx_free_thresh,
-+					   BNXT_RX_DESCS_PER_LOOP_VEC256);
- 	uint16_t cnt = 0;
- 
- 	while (nb_pkts > brst) {
-@@ -1334,7 +1336,8 @@ bnxt_recv_pkts_vec_avx2_v3(void *rx_queue, struct rte_mbuf **rx_pkts,
- 			   uint16_t nb_pkts)
- {
- 	struct bnxt_rx_queue *rxq = rx_queue;
--	uint32_t expected_burst = rxq->rx_free_thresh;
-+	uint32_t expected_burst = (uint16_t)RTE_MAX((uint32_t)rxq->rx_free_thresh,
-+						     BNXT_RX_DESCS_PER_LOOP_VEC256);
- 	uint16_t cnt = 0;
- 
- 	while (nb_pkts > expected_burst) {
@@ -115 +79 @@
-index c75a8bd09f..bca18f936f 100644
+index e1850052930..1823fa69894 100644
@@ -127,38 +90,0 @@
-diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_neon.c b/drivers/net/bnxt/bnxt_rxtx_vec_neon.c
-index 7aa153bc4e..c1998fccde 100644
---- a/drivers/net/bnxt/bnxt_rxtx_vec_neon.c
-+++ b/drivers/net/bnxt/bnxt_rxtx_vec_neon.c
-@@ -318,7 +318,8 @@ uint16_t
- bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
- {
- 	struct bnxt_rx_queue *rxq = rx_queue;
--	uint32_t brst = rxq->rx_free_thresh;
-+	uint16_t brst = (uint16_t)RTE_MAX((uint32_t)rxq->rx_free_thresh,
-+					   BNXT_RX_DESCS_PER_LOOP_VEC128);
- 	uint16_t cnt = 0;
- 
- 	while (nb_pkts > brst) {
-diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_sse.c b/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
-index 8dfb16a26d..28f0bb568c 100644
---- a/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
-+++ b/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
-@@ -518,7 +518,8 @@ uint16_t
- bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
- {
- 	struct bnxt_rx_queue *rxq = rx_queue;
--	uint32_t brst = rxq->rx_free_thresh;
-+	uint16_t brst = (uint16_t)RTE_MAX((uint32_t)rxq->rx_free_thresh,
-+					   BNXT_RX_DESCS_PER_LOOP_VEC128);
- 	uint16_t cnt = 0;
- 
- 	while (nb_pkts > brst) {
-@@ -540,7 +541,8 @@ uint16_t
- bnxt_crx_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
- {
- 	struct bnxt_rx_queue *rxq = rx_queue;
--	uint32_t brst = rxq->rx_free_thresh;
-+	uint16_t brst = (uint16_t)RTE_MAX((uint32_t)rxq->rx_free_thresh,
-+					   BNXT_RX_DESCS_PER_LOOP_VEC128);
- 	uint16_t cnt = 0;
- 
- 	while (nb_pkts > brst) {


More information about the stable mailing list