[PATCH v3 06/10] net/gve: fix Tx stall on invalid packets
Tathagat Priyadarshi
tathagat.dpdk at gmail.com
Fri Oct 16 08:26:43 CEST 2026
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")
Cc: stable at dpdk.org
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 8349b1c92e..24ef3a4552 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -114,6 +114,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 c5ae2136ad..44d2fa870f 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -261,6 +261,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
uint16_t compl_tag;
uint16_t req_descs;
const char *reason;
+ uint16_t nb_sent = 0;
uint16_t nb_tx = 0;
uint64_t bytes = 0;
uint64_t ol_flags;
@@ -283,7 +284,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_DP_LOG(DEBUG, "Invalid mbuf: %s", reason);
- break;
+ txq->stats.invalid_mbufs++;
+ rte_pktmbuf_free(tx_pkt);
+ continue;
}
ol_flags = tx_pkt->ol_flags;
@@ -292,6 +295,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
@@ -306,12 +317,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 (!gve_free_compl_tags_pop(txq, &compl_tag))
break;
@@ -350,6 +355,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
txq->nb_free -= nb_descs;
txq->nb_used += nb_descs;
+ nb_sent++;
}
/* update the tail pointer if any packets were processed */
@@ -357,9 +363,9 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
rte_write32(tx_id, txq->qtx_tail);
txq->tx_tail = tx_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.43.0
More information about the dev
mailing list