patch 'net/gve: fix Tx stall on invalid packets' has been queued to stable release 24.11.9

luca.boccassi at gmail.com luca.boccassi at gmail.com
Thu Nov 5 17:42:55 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/170bb73df484728ce9224b6dd3677c534a6b8e6b

Thanks.

Luca Boccassi

---
>From 170bb73df484728ce9224b6dd3677c534a6b8e6b Mon Sep 17 00:00:00 2001
From: Tathagat Priyadarshi <tathagat.dpdk at gmail.com>
Date: Fri, 16 Oct 2026 17:45:41 +0000
Subject: [PATCH] net/gve: fix Tx stall on invalid packets

[ upstream commit 8eb4eb62cc0e4bb89a8726903d5a55703f099fd9 ]

When a packet fails rte_mbuf_check() or exceeds the descriptor limit,
the Tx burst stops at that packet without consuming it. The
application retries the same packet, it fails again, and the queue
never moves.

Free such packets and continue with the burst. Validate before the
ring space check, so that an oversized packet is dropped instead of
stopping the burst there. Count rte_mbuf_check() failures in a new
invalid_mbufs counter.

Fixes: f4a70b449bfa ("net/gve: add DQO Tx descriptor limit")
Fixes: f33ce4445ee6 ("net/gve: validate Tx packet before sending")

Signed-off-by: Tathagat Priyadarshi <tathagat.dpdk at gmail.com>
---
 drivers/net/gve/gve_ethdev.h |  1 +
 drivers/net/gve/gve_tx_dqo.c | 24 +++++++++++++++---------
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index dff7ceff861..1bbbfa9c9fa 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -104,6 +104,7 @@ struct gve_tx_stats {
 	uint64_t bytes;
 	uint64_t errors;
 	uint64_t too_many_descs;
+	uint64_t invalid_mbufs;
 };
 
 struct gve_rx_stats {
diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
index c09087ee4a8..350bddd4ff2 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -182,6 +182,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	uint16_t first_sw_id;
 	uint16_t req_descs;
 	const char *reason;
+	uint16_t nb_sent = 0;
 	uint16_t nb_tx = 0;
 	uint64_t ol_flags;
 	uint16_t nb_descs;
@@ -210,7 +211,9 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
 		if (rte_mbuf_check(tx_pkt, true, &reason)) {
 			PMD_DRV_LOG(DEBUG, "Invalid mbuf: %s", reason);
-			break;
+			txq->stats.invalid_mbufs++;
+			rte_pktmbuf_free(tx_pkt);
+			continue;
 		}
 
 		ol_flags = tx_pkt->ol_flags;
@@ -221,6 +224,14 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
 		nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
 		nb_descs += tso;
+
+		/* Drop packet if it doesn't adhere to hardware limits. */
+		if (!gve_tx_validate_descs(tx_pkt, nb_descs, tso)) {
+			txq->stats.too_many_descs++;
+			rte_pktmbuf_free(tx_pkt);
+			continue;
+		}
+
 		req_descs = nb_descs + GVE_TX_MIN_DESC_PREVENT_CACHE_OVERLAP;
 
 		/* Clean if there aren't enough descriptors to send the packet
@@ -235,12 +246,6 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 				break;
 		}
 
-		/* Drop packet if it doesn't adhere to hardware limits. */
-		if (!gve_tx_validate_descs(tx_pkt, nb_descs, tso)) {
-			txq->stats.too_many_descs++;
-			break;
-		}
-
 		if (tso) {
 			txd = &txr[tx_id];
 			gve_tx_fill_seg_desc_dqo(txd, tx_pkt);
@@ -301,6 +306,7 @@ finish_mbuf:
 
 		txq->nb_free -= nb_descs;
 		txq->nb_used += nb_descs;
+		nb_sent++;
 	}
 
 	/* update the tail pointer if any packets were processed */
@@ -309,9 +315,9 @@ finish_mbuf:
 		txq->tx_tail = tx_id;
 		txq->sw_tail = sw_id;
 
-		txq->stats.packets += nb_tx;
+		txq->stats.packets += nb_sent;
 		txq->stats.bytes += bytes;
-		txq->stats.errors += nb_pkts - nb_tx;
+		txq->stats.errors += nb_pkts - nb_sent;
 	}
 
 	return nb_tx;
-- 
2.47.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-11-05 16:42:48.306573549 +0000
+++ 0088-net-gve-fix-Tx-stall-on-invalid-packets.patch	2026-11-05 16:42:45.021063775 +0000
@@ -1 +1 @@
-From 8eb4eb62cc0e4bb89a8726903d5a55703f099fd9 Mon Sep 17 00:00:00 2001
+From 170bb73df484728ce9224b6dd3677c534a6b8e6b Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 8eb4eb62cc0e4bb89a8726903d5a55703f099fd9 ]
+
@@ -18 +19,0 @@
-Cc: stable at dpdk.org
@@ -27 +28 @@
-index 4d17ba727d..66cb31dadb 100644
+index dff7ceff861..1bbbfa9c9fa 100644
@@ -30 +31 @@
-@@ -114,6 +114,7 @@ struct gve_tx_stats {
+@@ -104,6 +104,7 @@ struct gve_tx_stats {
@@ -39 +40 @@
-index 637632ce4d..281700b463 100644
+index c09087ee4a8..350bddd4ff2 100644
@@ -42,2 +43,2 @@
-@@ -258,6 +258,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
- 	uint16_t compl_tag;
+@@ -182,6 +182,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+ 	uint16_t first_sw_id;
@@ -48 +48,0 @@
- 	uint64_t bytes = 0;
@@ -50 +50,2 @@
-@@ -280,7 +281,9 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+ 	uint16_t nb_descs;
+@@ -210,7 +211,9 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -53 +54 @@
- 			PMD_DRV_DP_LOG(DEBUG, "Invalid mbuf: %s", reason);
+ 			PMD_DRV_LOG(DEBUG, "Invalid mbuf: %s", reason);
@@ -61 +62 @@
-@@ -289,6 +292,14 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+@@ -221,6 +224,14 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -76 +77 @@
-@@ -303,12 +314,6 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+@@ -235,12 +246,6 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -86,4 +87,4 @@
- 		if (!gve_free_compl_tags_pop(txq, &compl_tag))
- 			break;
- 
-@@ -347,6 +352,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+ 		if (tso) {
+ 			txd = &txr[tx_id];
+ 			gve_tx_fill_seg_desc_dqo(txd, tx_pkt);
+@@ -301,6 +306,7 @@ finish_mbuf:
@@ -97,2 +98 @@
-@@ -354,9 +360,9 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
- 		rte_write32(tx_id, txq->qtx_tail);
+@@ -309,9 +315,9 @@ finish_mbuf:
@@ -99,0 +100 @@
+ 		txq->sw_tail = sw_id;


More information about the stable mailing list