Skip to contentSkip to conversation

net/gve: fix DQO Tx queue stalls

PATCH In review Tathagat Priyadarshi 3 participants 19 messages Oct 16 – Oct 20 Network drivers

lore
Share & tools
lore
Acked-by on v4 7/10
#8 lore raw

Re: [PATCH v4 07/10] net/gve: export Tx drop counters in xstats

In reply to Tathagat Priyadarshi
Quoted 8 lines · Tathagat Priyadarshi

too_many_descs is counted but missing from the Tx xstats table, so it cannot be read. Export it together with invalid_mbufs.

Fixes f4a70b449bfa ("net/gve: add DQO Tx descriptor limit")
Quoted 18 lines
---
 drivers/net/gve/gve_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/gve/gve_ethdev.c +2 -1
index 3c8d1a76e4..1dfbe8f396 100644
@@ -1042,6 +1042,8 @@ static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
        { "packets", TX_QUEUE_STATS_OFFSET(packets) },
        { "bytes",   TX_QUEUE_STATS_OFFSET(bytes) },
        { "errors",  TX_QUEUE_STATS_OFFSET(errors) },
+       { "too_many_descs", TX_QUEUE_STATS_OFFSET(too_many_descs) },
+       { "invalid_mbufs", TX_QUEUE_STATS_OFFSET(invalid_mbufs) },
 };
 
 static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
--
Quoted 2 lines

2.43.0

Thanks!

Acked-by on v4 8/10
#10 lore raw

Re: [PATCH v4 08/10] net/gve: reject Tx packets that cannot fit in the ring

In reply to Tathagat Priyadarshi
Quoted 7 lines · Tathagat Priyadarshi

A TSO packet needing more descriptors than the ring can ever have free fails the ring space check on every burst and blocks the queue. One slot is always reserved, the cacheline overlap margin must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 posted descriptors are not reclaimed until more are posted.

Quoted 6 lines

Drop such packets and count them as too_many_descs.

Fixes 403c671a46b6 ("net/gve: support TSO in DQO RDA")
Quoted 52 lines
---
 drivers/net/gve/gve_tx_dqo.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/net/gve/gve_tx_dqo.c +18 -3
index 281700b463..46a03d482d 100644
@@ -123,14 +123,30 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
                gve_tx_clean_dqo(txq);
 }
 
+/* Max descriptors a single packet may use. A larger packet can never pass
+ * gve_can_tx(): one slot is always reserved, the cacheline overlap margin
+ * must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 descriptors posted
+ * after the last report_event are not reclaimed until more are posted.
+ */
+static inline int
+gve_tx_max_pkt_descs(const struct gve_tx_queue *txq)
+{
+       return (int)txq->nb_tx_desc - 1 - GVE_TX_MIN_DESC_PREVENT_CACHE_OVERLAP -
+               (GVE_TX_MIN_RE_INTERVAL - 1);
+}
+
 /* GVE expects at most 10 data descriptors per mtu-sized segment. Beyond this,
  * the hardware will assume the driver is malicious and stop transmitting
  * packets altogether. Validate that a packet can be sent to avoid sending
  * posting descriptors for an invalid packet.
  */
 static inline bool
-gve_tx_validate_descs(struct rte_mbuf *tx_pkt, uint16_t nb_descs, bool is_tso)
+gve_tx_validate_descs(const struct gve_tx_queue *txq, struct rte_mbuf *tx_pkt,
+                     uint16_t nb_descs, bool is_tso)
 {
+       if (nb_descs > gve_tx_max_pkt_descs(txq))
+               return false;
+
        if (!is_tso)
                return nb_descs <= GVE_TX_MAX_DATA_DESCS;
 
@@ -294,7 +310,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                nb_descs += tso;
 
                /* Drop packet if it doesn't adhere to hardware limits. */
-               if (!gve_tx_validate_descs(tx_pkt, nb_descs, tso)) {
+               if (!gve_tx_validate_descs(txq, tx_pkt, nb_descs, tso)) {
                        txq->stats.too_many_descs++;
                        rte_pktmbuf_free(tx_pkt);
                        continue;
--

2.43.0

Acked-by on v4 9/10
#12 lore raw

Re: [PATCH v4 09/10] net/gve: enforce DQO Tx packet length limits

In reply to Tathagat Priyadarshi
Quoted 7 lines · Tathagat Priyadarshi

The device requires non-TSO packets to be 17 to 9728 bytes long, as noted in the Linux driver, but packets of any length are posted. The device treats an out-of-range packet as coming from a malicious
driver: it drops the packet and disables the datapath, stalling all queues.

Quoted 7 lines

Drop such packets in the driver and count them in a new invalid_pkts counter.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Quoted 49 lines
---
 drivers/net/gve/base/gve_desc_dqo.h |  2 ++
 drivers/net/gve/gve_ethdev.c        |  1 +
 drivers/net/gve/gve_ethdev.h        |  1 +
 drivers/net/gve/gve_tx_dqo.c        | 17 +++++++++++++++++
 4 files changed, 21 insertions(+)
drivers/net/gve/base/gve_desc_dqo.h +2 -0
index c1534959c2..d50d88765e 100644
@@ -12,6 +12,8 @@
 
 #define GVE_TX_MAX_HDR_SIZE_DQO 255
 #define GVE_TX_MIN_TSO_MSS_DQO 88
+#define GVE_TX_MIN_PKT_SIZE_DQO 17
+#define GVE_TX_MAX_PKT_SIZE_DQO 9728
 
 /* Basic TX descriptor (DTYPE 0x0C) */
 struct gve_tx_pkt_desc_dqo {
drivers/net/gve/gve_ethdev.c +1 -0
index 1dfbe8f396..53b0a0ec63 100644
@@ -1044,6 +1044,7 @@ static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
        { "errors",  TX_QUEUE_STATS_OFFSET(errors) },
        { "too_many_descs", TX_QUEUE_STATS_OFFSET(too_many_descs) },
        { "invalid_mbufs", TX_QUEUE_STATS_OFFSET(invalid_mbufs) },
+       { "invalid_pkts", TX_QUEUE_STATS_OFFSET(invalid_pkts) },
 };
 
 static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
drivers/net/gve/gve_ethdev.h +1 -0
index 66cb31dadb..be744d955b 100644
@@ -115,6 +115,7 @@ struct gve_tx_stats {
        uint64_t errors;
        uint64_t too_many_descs;
        uint64_t invalid_mbufs;
+       uint64_t invalid_pkts;
 };
 
 struct gve_rx_stats {
drivers/net/gve/gve_tx_dqo.c +0 -0
index 46a03d482d..f686a8c110 100644

drivers/net/gve/gve_tx_dqo.c gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) { · line 128

Quoted 6 lines
drivers/net/gve/gve_tx_dqo.c +3 -0
@@ -123,6 +123,17 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
                gve_tx_clean_dqo(txq);
 }
 
+/* Validate packet lengths against the device limits. */
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)

Minor nit (not worth blocking over, but maybe can be done as the patches are being merged): can this be renamed to gve_tx_validate_pkt_len? This is one step of many in the packet validation pipeline.

Quoted 27 lines
drivers/net/gve/gve_tx_dqo.c +14 -1
+{
+       if (!is_tso)
+               return tx_pkt->pkt_len >= GVE_TX_MIN_PKT_SIZE_DQO &&
+                      tx_pkt->pkt_len <= GVE_TX_MAX_PKT_SIZE_DQO;
+
+       return true;
+}
+
 /* Max descriptors a single packet may use. A larger packet can never pass
  * gve_can_tx(): one slot is always reserved, the cacheline overlap margin
  * must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 descriptors posted
@@ -306,6 +317,12 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                tso = !!(ol_flags & RTE_MBUF_F_TX_TCP_SEG);
                csum = !!(ol_flags & GVE_TX_CKSUM_OFFLOAD_MASK_DQO);
 
+               if (!gve_tx_validate_pkt(tx_pkt, tso)) {
+                       txq->stats.invalid_pkts++;
+                       rte_pktmbuf_free(tx_pkt);
+                       continue;
+               }
+
                nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
                nb_descs += tso;
 
--

2.43.0

Acked-by on v4 10/10
#18 lore raw

Re: [PATCH v4 10/10] net/gve: enforce DQO TSO header and length limits

In reply to Tathagat Priyadarshi
Quoted 13 lines · Tathagat Priyadarshi

TSO packets are not checked against the device limits before use. The device requires an MSS of 88 to 9728 bytes and a payload of at most 262143 bytes, as noted in the Linux driver. A packet outside these limits triggers malicious driver detection, which drops it and disables the datapath, stalling all queues.

The missing checks also break the driver itself: a tso_segsz of 0 divides by zero in gve_tx_validate_descs(), headers longer than 255 bytes are truncated by the 8-bit header_len field, and headers not contained in the first segment give gve_tx_validate_descs() a negative first segment length.

Quoted 8 lines

Drop TSO packets that violate these limits and count them as invalid_pkts.

Fixes 403c671a46b6 ("net/gve: support TSO in DQO RDA")
Fixes be8f0eb81f98 ("net/gve: fix DQO TSO descriptor limit")
Quoted 49 lines
---
 drivers/net/gve/base/gve_desc_dqo.h |  1 +
 drivers/net/gve/gve_tx_dqo.c        | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)
drivers/net/gve/base/gve_desc_dqo.h +1 -0
index d50d88765e..53e394f01c 100644
@@ -14,6 +14,7 @@
 #define GVE_TX_MIN_TSO_MSS_DQO 88
 #define GVE_TX_MIN_PKT_SIZE_DQO 17
 #define GVE_TX_MAX_PKT_SIZE_DQO 9728
+#define GVE_TX_MAX_TSO_LEN_DQO ((256 * 1024) - 1)
 
 /* Basic TX descriptor (DTYPE 0x0C) */
 struct gve_tx_pkt_desc_dqo {
drivers/net/gve/gve_tx_dqo.c +13 -2
index f686a8c110..52fcdb285a 100644
@@ -127,11 +127,23 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
 static inline bool
 gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)
 {
+       uint32_t headlen;
+
        if (!is_tso)
                return tx_pkt->pkt_len >= GVE_TX_MIN_PKT_SIZE_DQO &&
                       tx_pkt->pkt_len <= GVE_TX_MAX_PKT_SIZE_DQO;
 
-       return true;
+       /* Headers must be present, fit the context descriptor, and be
+        * contained in the first segment; the payload must not be empty.
+        */
+       headlen = tx_pkt->l2_len + tx_pkt->l3_len + tx_pkt->l4_len;
+       if (tx_pkt->l4_len == 0 || headlen > GVE_TX_MAX_HDR_SIZE_DQO ||
+           tx_pkt->data_len < headlen || tx_pkt->pkt_len <= headlen)
+               return false;
+
+       return tx_pkt->pkt_len - headlen <= GVE_TX_MAX_TSO_LEN_DQO &&
+              tx_pkt->tso_segsz >= GVE_TX_MIN_TSO_MSS_DQO &&
+              tx_pkt->tso_segsz <= GVE_TX_MAX_PKT_SIZE_DQO;
 }
 
 /* Max descriptors a single packet may use. A larger packet can never pass
--

2.43.0

#0 lore raw

v4 cover net/gve: fix DQO Tx queue stalls

This series fixes several ways the gve DQO RDA Tx path can stall or post invalid descriptors: completion handling bugs (1-2), a report event interval that can starve the ring (3), a stray TSO context descriptor when completion tags run out (4), a missing cacheline margin (5), invalid packets blocking the burst (6-8), and missing device length checks (9-10).

v4:
- Rebased on main; v3 no longer applied after 4a543ae8c8 ("net/gve: clean Tx queue directly in DQO") removed txqs next to the field changed in 3/10. No functional changes.

v3:
- Split the series into one fix per patch, per review feedback. The code is the same as v2 except where noted below.
- 1/10, 2/10: v2 1/4, split in two. Kept Joshua's Ack.
- 3/10: v2 2/4 without the declaration reordering
(per Joshua Washington) and without ringing the doorbell on each report event, which is a performance change to be sent separately with numbers (per Stephen Hemminger).
- 4/10: the completion tag reorder from v2 2/4, as its own patch. Fixes tag now points at the commit that made the tag pop fallible.
- 5/10: v2 3/4, unchanged. Kept Joshua's Ack.
- 6/10-10/10: v2 4/4, split:
* Keep too_many_descs and add per-reason invalid_mbufs and invalid_pkts counters instead of a generic dropped_pkts (per Joshua Washington), and export them as xstats (per Stephen Hemminger).
* Count sent packets after writing descriptors instead of subtracting drops (per Joshua Washington).
* Move the length and TSO header checks into gve_tx_validate_pkt(), leaving gve_tx_validate_descs() to descriptor counts, without the declaration moves.
* Reword the TSO length limit (per Stephen Hemminger) and shorten the commit messages.
- Stephen's Reviewed-by on v2 is not carried over because of the rework.

Tathagat Priyadarshi (10):
net/gve: fix DQO descriptor cleaning loop bound net/gve: fix DQO completion queue stall on unknown type net/gve: fix DQO Tx report event interval net/gve: fix stray TSO context descriptor on tag exhaustion net/gve: add cacheline overlap margin to DQO Tx ring net/gve: fix Tx stall on invalid packets
net/gve: export Tx drop counters in xstats net/gve: reject Tx packets that cannot fit in the ring net/gve: enforce DQO Tx packet length limits net/gve: enforce DQO TSO header and length limits

 drivers/net/gve/base/gve_desc_dqo.h |   3 +
 drivers/net/gve/gve_ethdev.c        |   3 +
 drivers/net/gve/gve_ethdev.h        |   4 +-
 drivers/net/gve/gve_tx_dqo.c        | 113 +++++++++++++++++++++-------
 4 files changed, 96 insertions(+), 27 deletions(-)
Signature · 1 line
2.43.0
#1 lore raw

PATCH v4 1/10 net/gve: fix DQO descriptor cleaning loop bound

gve_tx_clean_descs_dqo() loops on "while (--nb_descs)", which processes one completion fewer than requested, and none when asked for one.

Use a post-decrement so exactly nb_descs completions are processed.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
---
 drivers/net/gve/gve_tx_dqo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/gve/gve_tx_dqo.c +1 -1
index 901c6ca749..7e12da68e6 100644
@@ -119,7 +119,7 @@ gve_tx_clean_dqo(struct gve_tx_queue *txq)
 
 static inline void
 gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
-	while (--nb_descs)
+	while (nb_descs--)
 		gve_tx_clean_dqo(txq);
 }
 
Signature · 1 line
2.43.0
#2 lore raw

PATCH v4 2/10 net/gve: fix DQO completion queue stall on unknown type

In reply to Tathagat Priyadarshi

When gve_tx_clean_dqo() sees an unknown completion type, it returns without advancing complq_tail. Every later call stops at the same entry, so Tx completions are never processed again.

Log the type and skip the entry.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
---
 drivers/net/gve/gve_tx_dqo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/gve/gve_tx_dqo.c +2 -2
index 7e12da68e6..4b84135d02 100644
@@ -105,8 +105,8 @@ gve_tx_clean_dqo(struct gve_tx_queue *txq)
 		PMD_DRV_DP_LOG(DEBUG, "GVE_COMPL_TYPE_DQO_MISS ignored !!!");
 		break;
 	default:
-		PMD_DRV_DP_LOG(ERR, "unknown completion type.");
-		return;
+		PMD_DRV_DP_LOG(ERR, "unknown completion type %u", compl_desc->type);
+		break;
 	}
 
 	next++;
Signature · 1 line
2.43.0
#3 lore raw

PATCH v4 3/10 net/gve: fix DQO Tx report event interval

In reply to Tathagat Priyadarshi

A descriptor completion is requested once every 32 packets, and Tx descriptors are only reclaimed on these completions. With multi-segment or TSO packets the ring can fill before 32 packets are posted, so no completion is ever requested and the Tx queue stalls for good.

Request a completion once GVE_TX_MIN_RE_INTERVAL descriptors have been posted since the last one, as the Linux driver does.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Fixes 403c671a46b6 ("net/gve: support TSO in DQO RDA")
---
 drivers/net/gve/gve_ethdev.h |  2 +-
 drivers/net/gve/gve_tx_dqo.c | 22 ++++++++++++++--------
 2 files changed, 15 insertions(+), 9 deletions(-)
drivers/net/gve/gve_ethdev.h +1 -1
index 19eac9ec0b..4d17ba727d 100644
@@ -193,7 +193,7 @@ struct gve_tx_queue {
 	uint16_t sw_size;
 	uint8_t cur_gen_bit;
 	uint32_t last_desc_cleaned;
-	uint16_t re_cnt;
+	uint16_t last_re_idx;
 
 	/* Only valid for DQO_RDA queue format */
 	struct gve_tx_queue *complq;
drivers/net/gve/gve_tx_dqo.c +14 -8
index 4b84135d02..6cca968122 100644
@@ -251,6 +251,8 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	volatile union gve_tx_desc_dqo *txr;
 	volatile union gve_tx_desc_dqo *txd;
 	uint16_t mask = txq->nb_tx_desc - 1;
+	uint16_t last_re_interval;
+	uint16_t last_desc_idx;
 	struct gve_tx_pkt *pkts;
 	struct rte_mbuf *tx_pkt;
 	uint16_t compl_tag;
@@ -328,20 +330,23 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		txd = &txr[(tx_id - 1) & mask];
 		txd->pkt.end_of_packet = 1;
 
+		/* Request a descriptor completion once at least
+		 * GVE_TX_MIN_RE_INTERVAL descriptors have been posted
+		 * since the last request.
+		 */
+		last_desc_idx = (tx_id - 1) & mask;
+		last_re_interval = (last_desc_idx - txq->last_re_idx) & mask;
+		if (unlikely(last_re_interval >= GVE_TX_MIN_RE_INTERVAL)) {
+			txd->pkt.report_event = true;
+			txq->last_re_idx = last_desc_idx;
+		}
+
 		txq->nb_free -= nb_descs;
 		txq->nb_used += nb_descs;
 	}
 
 	/* update the tail pointer if any packets were processed */
 	if (nb_tx > 0) {
-		/* Request a descriptor completion on the last descriptor */
-		txq->re_cnt += nb_tx;
-		if (txq->re_cnt >= GVE_TX_MIN_RE_INTERVAL) {
-			txd = &txr[(tx_id - 1) & mask];
-			txd->pkt.report_event = true;
-			txq->re_cnt = 0;
-		}
-
 		rte_write32(tx_id, txq->qtx_tail);
 		txq->tx_tail = tx_id;
 
@@ -442,6 +447,7 @@ gve_reset_tx_ring_state_dqo(struct gve_tx_queue *txq)
 	txq->nb_used = 0;
 
 	txq->last_desc_cleaned = 0;
+	txq->last_re_idx = 0;
 	txq->nb_free = txq->nb_tx_desc - 1;
 
 	txq->complq_tail = 0;
Signature · 1 line
2.43.0
#4 lore raw

PATCH v4 4/10 net/gve: fix stray TSO context descriptor on tag exhaustion

In reply to Tathagat Priyadarshi

For TSO packets, the context descriptor is written and tx_id advanced before a completion tag is allocated. If no tag is available, the burst stops, but when earlier packets in the burst were sent, the tail written at the end of the burst still covers the context descriptor. The device then receives it with no data descriptors behind it, and the slot is never deducted from nb_free.

Allocate the completion tag before writing any descriptor.

Fixes 5fd289ff3a00 ("net/gve: support out-of-order completions on DQ Tx")
---
 drivers/net/gve/gve_tx_dqo.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/gve/gve_tx_dqo.c +3 -3
index 6cca968122..55187fec71 100644
@@ -305,15 +305,15 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			break;
 		}
 
+		if (!gve_free_compl_tags_pop(txq, &compl_tag))
+			break;
+
 		if (tso) {
 			txd = &txr[tx_id];
 			gve_tx_fill_seg_desc_dqo(txd, tx_pkt);
 			tx_id = (tx_id + 1) & mask;
 		}
 
-		if (!gve_free_compl_tags_pop(txq, &compl_tag))
-			break;
-
 		pkts[compl_tag].mbuf = tx_pkt;
 		while (tx_pkt) {
 			/* Skip writing descriptors if mbuf has no data. */
Signature · 1 line
2.43.0
#5 lore raw

PATCH v4 5/10 net/gve: add cacheline overlap margin to DQO Tx ring

In reply to Tathagat Priyadarshi

The GVNIC DQO hardware DMA engine prefetches descriptors in cacheline units (64 bytes = 4 descriptors of 16 bytes each). When producer tail and consumer head indices share a cacheline, CPU and device DMA memory collisions can occur.

Align with the Linux driver (gve_has_tx_slots_available()) by requiring GVE_TX_MIN_DESC_PREVENT_CACHE_OVERLAP (4 descriptors) headroom when checking descriptor availability before enqueueing packets.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
---
 drivers/net/gve/gve_tx_dqo.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/net/gve/gve_tx_dqo.c +8 -4
index 55187fec71..637632ce4d 100644
@@ -256,6 +256,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	struct gve_tx_pkt *pkts;
 	struct rte_mbuf *tx_pkt;
 	uint16_t compl_tag;
+	uint16_t req_descs;
 	const char *reason;
 	uint16_t nb_tx = 0;
 	uint64_t bytes = 0;
@@ -288,14 +289,17 @@ 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;
+		req_descs = nb_descs + GVE_TX_MIN_DESC_PREVENT_CACHE_OVERLAP;
 
-		/* Clean if there aren't enough descriptors to send the packet. */
-		if (unlikely(!gve_can_tx(txq, nb_descs, 1))) {
+		/* Clean if there aren't enough descriptors to send the packet
+		 * while maintaining the cacheline overlap margin.
+		 */
+		if (unlikely(!gve_can_tx(txq, req_descs, 1))) {
 			int nb_to_clean = RTE_MAX(DQO_TX_MULTIPLIER * txq->rs_thresh,
-						  nb_descs);
+						  (int)req_descs);
 
 			gve_tx_clean_descs_dqo(txq, nb_to_clean);
-			if (!gve_can_tx(txq, nb_descs, 1))
+			if (!gve_can_tx(txq, req_descs, 1))
 				break;
 		}
 
Signature · 1 line
2.43.0
#6 lore raw

PATCH v4 6/10 net/gve: fix Tx stall on invalid packets

In reply to Tathagat Priyadarshi

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")
---
 drivers/net/gve/gve_ethdev.h |  1 +
 drivers/net/gve/gve_tx_dqo.c | 24 +++++++++++++++---------
 2 files changed, 16 insertions(+), 9 deletions(-)
drivers/net/gve/gve_ethdev.h +1 -0
index 4d17ba727d..66cb31dadb 100644
@@ -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 {
drivers/net/gve/gve_tx_dqo.c +15 -9
index 637632ce4d..281700b463 100644
@@ -258,6 +258,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;
@@ -280,7 +281,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;
@@ -289,6 +292,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
@@ -303,12 +314,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;
 
@@ -347,6 +352,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 */
@@ -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);
 		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;
Signature · 1 line
2.43.0
#7 lore raw

PATCH v4 7/10 net/gve: export Tx drop counters in xstats

In reply to Tathagat Priyadarshi

too_many_descs is counted but missing from the Tx xstats table, so it cannot be read. Export it together with invalid_mbufs.

Fixes f4a70b449bfa ("net/gve: add DQO Tx descriptor limit")
---
 drivers/net/gve/gve_ethdev.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/gve/gve_ethdev.c +2 -0
index 3c8d1a76e4..1dfbe8f396 100644
@@ -1042,6 +1042,8 @@ static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
 	{ "packets", TX_QUEUE_STATS_OFFSET(packets) },
 	{ "bytes",   TX_QUEUE_STATS_OFFSET(bytes) },
 	{ "errors",  TX_QUEUE_STATS_OFFSET(errors) },
+	{ "too_many_descs", TX_QUEUE_STATS_OFFSET(too_many_descs) },
+	{ "invalid_mbufs", TX_QUEUE_STATS_OFFSET(invalid_mbufs) },
 };
 
 static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
Signature · 1 line
2.43.0
#9 lore raw

PATCH v4 8/10 net/gve: reject Tx packets that cannot fit in the ring

In reply to Tathagat Priyadarshi

A TSO packet needing more descriptors than the ring can ever have free fails the ring space check on every burst and blocks the queue. One slot is always reserved, the cacheline overlap margin must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 posted descriptors are not reclaimed until more are posted.

Drop such packets and count them as too_many_descs.

Fixes 403c671a46b6 ("net/gve: support TSO in DQO RDA")
---
 drivers/net/gve/gve_tx_dqo.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/net/gve/gve_tx_dqo.c +18 -2
index 281700b463..46a03d482d 100644
@@ -123,14 +123,30 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
 		gve_tx_clean_dqo(txq);
 }
 
+/* Max descriptors a single packet may use. A larger packet can never pass
+ * gve_can_tx(): one slot is always reserved, the cacheline overlap margin
+ * must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 descriptors posted
+ * after the last report_event are not reclaimed until more are posted.
+ */
+static inline int
+gve_tx_max_pkt_descs(const struct gve_tx_queue *txq)
+{
+	return (int)txq->nb_tx_desc - 1 - GVE_TX_MIN_DESC_PREVENT_CACHE_OVERLAP -
+		(GVE_TX_MIN_RE_INTERVAL - 1);
+}
+
 /* GVE expects at most 10 data descriptors per mtu-sized segment. Beyond this,
  * the hardware will assume the driver is malicious and stop transmitting
  * packets altogether. Validate that a packet can be sent to avoid sending
  * posting descriptors for an invalid packet.
  */
 static inline bool
-gve_tx_validate_descs(struct rte_mbuf *tx_pkt, uint16_t nb_descs, bool is_tso)
+gve_tx_validate_descs(const struct gve_tx_queue *txq, struct rte_mbuf *tx_pkt,
+		      uint16_t nb_descs, bool is_tso)
 {
+	if (nb_descs > gve_tx_max_pkt_descs(txq))
+		return false;
+
 	if (!is_tso)
 		return nb_descs <= GVE_TX_MAX_DATA_DESCS;
 
@@ -294,7 +310,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		nb_descs += tso;
 
 		/* Drop packet if it doesn't adhere to hardware limits. */
-		if (!gve_tx_validate_descs(tx_pkt, nb_descs, tso)) {
+		if (!gve_tx_validate_descs(txq, tx_pkt, nb_descs, tso)) {
 			txq->stats.too_many_descs++;
 			rte_pktmbuf_free(tx_pkt);
 			continue;
Signature · 1 line
2.43.0
#11 lore raw

PATCH v4 9/10 net/gve: enforce DQO Tx packet length limits

In reply to Tathagat Priyadarshi

The device requires non-TSO packets to be 17 to 9728 bytes long, as noted in the Linux driver, but packets of any length are posted. The device treats an out-of-range packet as coming from a malicious
driver: it drops the packet and disables the datapath, stalling all queues.

Drop such packets in the driver and count them in a new invalid_pkts counter.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
---
 drivers/net/gve/base/gve_desc_dqo.h |  2 ++
 drivers/net/gve/gve_ethdev.c        |  1 +
 drivers/net/gve/gve_ethdev.h        |  1 +
 drivers/net/gve/gve_tx_dqo.c        | 17 +++++++++++++++++
 4 files changed, 21 insertions(+)
drivers/net/gve/base/gve_desc_dqo.h +2 -0
index c1534959c2..d50d88765e 100644
@@ -12,6 +12,8 @@
 
 #define GVE_TX_MAX_HDR_SIZE_DQO 255
 #define GVE_TX_MIN_TSO_MSS_DQO 88
+#define GVE_TX_MIN_PKT_SIZE_DQO 17
+#define GVE_TX_MAX_PKT_SIZE_DQO 9728
 
 /* Basic TX descriptor (DTYPE 0x0C) */
 struct gve_tx_pkt_desc_dqo {
drivers/net/gve/gve_ethdev.c +1 -0
index 1dfbe8f396..53b0a0ec63 100644
@@ -1044,6 +1044,7 @@ static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
 	{ "errors",  TX_QUEUE_STATS_OFFSET(errors) },
 	{ "too_many_descs", TX_QUEUE_STATS_OFFSET(too_many_descs) },
 	{ "invalid_mbufs", TX_QUEUE_STATS_OFFSET(invalid_mbufs) },
+	{ "invalid_pkts", TX_QUEUE_STATS_OFFSET(invalid_pkts) },
 };
 
 static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
drivers/net/gve/gve_ethdev.h +1 -0
index 66cb31dadb..be744d955b 100644
@@ -115,6 +115,7 @@ struct gve_tx_stats {
 	uint64_t errors;
 	uint64_t too_many_descs;
 	uint64_t invalid_mbufs;
+	uint64_t invalid_pkts;
 };
 
 struct gve_rx_stats {
drivers/net/gve/gve_tx_dqo.c +17 -0
index 46a03d482d..f686a8c110 100644
@@ -123,6 +123,17 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
 		gve_tx_clean_dqo(txq);
 }
 
+/* Validate packet lengths against the device limits. */
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)
+{
+	if (!is_tso)
+		return tx_pkt->pkt_len >= GVE_TX_MIN_PKT_SIZE_DQO &&
+		       tx_pkt->pkt_len <= GVE_TX_MAX_PKT_SIZE_DQO;
+
+	return true;
+}
+
 /* Max descriptors a single packet may use. A larger packet can never pass
  * gve_can_tx(): one slot is always reserved, the cacheline overlap margin
  * must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 descriptors posted
@@ -306,6 +317,12 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		tso = !!(ol_flags & RTE_MBUF_F_TX_TCP_SEG);
 		csum = !!(ol_flags & GVE_TX_CKSUM_OFFLOAD_MASK_DQO);
 
+		if (!gve_tx_validate_pkt(tx_pkt, tso)) {
+			txq->stats.invalid_pkts++;
+			rte_pktmbuf_free(tx_pkt);
+			continue;
+		}
+
 		nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
 		nb_descs += tso;
 
Signature · 1 line
2.43.0
#17 lore raw

PATCH v4 10/10 net/gve: enforce DQO TSO header and length limits

In reply to Tathagat Priyadarshi

TSO packets are not checked against the device limits before use. The device requires an MSS of 88 to 9728 bytes and a payload of at most 262143 bytes, as noted in the Linux driver. A packet outside these limits triggers malicious driver detection, which drops it and disables the datapath, stalling all queues.

The missing checks also break the driver itself: a tso_segsz of 0 divides by zero in gve_tx_validate_descs(), headers longer than 255 bytes are truncated by the 8-bit header_len field, and headers not contained in the first segment give gve_tx_validate_descs() a negative first segment length.

Drop TSO packets that violate these limits and count them as invalid_pkts.

Fixes 403c671a46b6 ("net/gve: support TSO in DQO RDA")
Fixes be8f0eb81f98 ("net/gve: fix DQO TSO descriptor limit")
---
 drivers/net/gve/base/gve_desc_dqo.h |  1 +
 drivers/net/gve/gve_tx_dqo.c        | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)
drivers/net/gve/base/gve_desc_dqo.h +1 -0
index d50d88765e..53e394f01c 100644
@@ -14,6 +14,7 @@
 #define GVE_TX_MIN_TSO_MSS_DQO 88
 #define GVE_TX_MIN_PKT_SIZE_DQO 17
 #define GVE_TX_MAX_PKT_SIZE_DQO 9728
+#define GVE_TX_MAX_TSO_LEN_DQO ((256 * 1024) - 1)
 
 /* Basic TX descriptor (DTYPE 0x0C) */
 struct gve_tx_pkt_desc_dqo {
drivers/net/gve/gve_tx_dqo.c +13 -1
index f686a8c110..52fcdb285a 100644
@@ -127,11 +127,23 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
 static inline bool
 gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)
 {
+	uint32_t headlen;
+
 	if (!is_tso)
 		return tx_pkt->pkt_len >= GVE_TX_MIN_PKT_SIZE_DQO &&
 		       tx_pkt->pkt_len <= GVE_TX_MAX_PKT_SIZE_DQO;
 
-	return true;
+	/* Headers must be present, fit the context descriptor, and be
+	 * contained in the first segment; the payload must not be empty.
+	 */
+	headlen = tx_pkt->l2_len + tx_pkt->l3_len + tx_pkt->l4_len;
+	if (tx_pkt->l4_len == 0 || headlen > GVE_TX_MAX_HDR_SIZE_DQO ||
+	    tx_pkt->data_len < headlen || tx_pkt->pkt_len <= headlen)
+		return false;
+
+	return tx_pkt->pkt_len - headlen <= GVE_TX_MAX_TSO_LEN_DQO &&
+	       tx_pkt->tso_segsz >= GVE_TX_MIN_TSO_MSS_DQO &&
+	       tx_pkt->tso_segsz <= GVE_TX_MAX_PKT_SIZE_DQO;
 }
 
 /* Max descriptors a single packet may use. A larger packet can never pass
Signature · 1 line
2.43.0
#13 lore raw

Re: [PATCH v4 09/10] net/gve: enforce DQO Tx packet length limits

In reply to Joshua Washington
Quoted 70 lines · Joshua Washington
Quoted 7 lines · Tathagat Priyadarshi

The device requires non-TSO packets to be 17 to 9728 bytes long, as noted in the Linux driver, but packets of any length are posted. The device treats an out-of-range packet as coming from a malicious
driver: it drops the packet and disables the datapath, stalling all queues.

Quoted 7 lines

Drop such packets in the driver and count them in a new invalid_pkts counter.

Fixes 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Quoted 52 lines
---
 drivers/net/gve/base/gve_desc_dqo.h |  2 ++
 drivers/net/gve/gve_ethdev.c        |  1 +
 drivers/net/gve/gve_ethdev.h        |  1 +
 drivers/net/gve/gve_tx_dqo.c        | 17 +++++++++++++++++
 4 files changed, 21 insertions(+)
drivers/net/gve/base/gve_desc_dqo.h +2 -0
index c1534959c2..d50d88765e 100644
@@ -12,6 +12,8 @@
 
 #define GVE_TX_MAX_HDR_SIZE_DQO 255
 #define GVE_TX_MIN_TSO_MSS_DQO 88
+#define GVE_TX_MIN_PKT_SIZE_DQO 17
+#define GVE_TX_MAX_PKT_SIZE_DQO 9728
 
 /* Basic TX descriptor (DTYPE 0x0C) */
 struct gve_tx_pkt_desc_dqo {
drivers/net/gve/gve_ethdev.c +1 -0
index 1dfbe8f396..53b0a0ec63 100644
@@ -1044,6 +1044,7 @@ static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
        { "errors",  TX_QUEUE_STATS_OFFSET(errors) },
        { "too_many_descs", TX_QUEUE_STATS_OFFSET(too_many_descs) },
        { "invalid_mbufs", TX_QUEUE_STATS_OFFSET(invalid_mbufs) },
+       { "invalid_pkts", TX_QUEUE_STATS_OFFSET(invalid_pkts) },
 };
 
 static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
drivers/net/gve/gve_ethdev.h +1 -0
index 66cb31dadb..be744d955b 100644
@@ -115,6 +115,7 @@ struct gve_tx_stats {
        uint64_t errors;
        uint64_t too_many_descs;
        uint64_t invalid_mbufs;
+       uint64_t invalid_pkts;
 };
 
 struct gve_rx_stats {
drivers/net/gve/gve_tx_dqo.c +0 -0
index 46a03d482d..f686a8c110 100644
@@ -123,6 +123,17 @@ gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
                gve_tx_clean_dqo(txq);
 }
 
Quoted 8 lines

drivers/net/gve/gve_tx_dqo.c gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) { · line 128

Quoted 3 lines
drivers/net/gve/gve_tx_dqo.c +3 -0
+/* Validate packet lengths against the device limits. */
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)

Minor nit (not worth blocking over, but maybe can be done as the patches are being merged): can this be renamed to gve_tx_validate_pkt_len? This is one step of many in the packet validation pipeline.

Thanks for the review, Joshua. Agreed on renaming to gve_tx_validate_pkt_len. This change impacts patches 9/10 and 10/10. I am happy to submit a v5 series if preferred,
or the maintainer can rename it upon applying.

Quoted 28 lines
Quoted 28 lines
drivers/net/gve/gve_tx_dqo.c +14 -1
+{
+       if (!is_tso)
+               return tx_pkt->pkt_len >= GVE_TX_MIN_PKT_SIZE_DQO &&
+                      tx_pkt->pkt_len <= GVE_TX_MAX_PKT_SIZE_DQO;
+
+       return true;
+}
+
 /* Max descriptors a single packet may use. A larger packet can never pass
  * gve_can_tx(): one slot is always reserved, the cacheline overlap margin
  * must stay free, and up to GVE_TX_MIN_RE_INTERVAL - 1 descriptors posted
@@ -306,6 +317,12 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                tso = !!(ol_flags & RTE_MBUF_F_TX_TCP_SEG);
                csum = !!(ol_flags & GVE_TX_CKSUM_OFFLOAD_MASK_DQO);
 
+               if (!gve_tx_validate_pkt(tx_pkt, tso)) {
+                       txq->stats.invalid_pkts++;
+                       rte_pktmbuf_free(tx_pkt);
+                       continue;
+               }
+
                nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
                nb_descs += tso;
 
--

2.43.0

#14 lore raw

Re: [PATCH v4 09/10] net/gve: enforce DQO Tx packet length limits

Quoted 8 lines · On Sun, 18 Oct 2026 13:24:03 +0530 Tathagat Priyadarshi…
Quoted 7 lines

drivers/net/gve/gve_tx_dqo.c gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) { · line 128

Quoted 2 lines
drivers/net/gve/gve_tx_dqo.c +2 -0
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)  

Minor nit (not worth blocking over, but maybe can be done as the patches are being merged): can this be renamed to gve_tx_validate_pkt_len? This is one step of many in the packet validation pipeline.

Quoted 4 lines

Thanks for the review, Joshua. Agreed on renaming to gve_tx_validate_pkt_len. This change impacts patches 9/10 and 10/10. I am happy to submit a v5 series if preferred,
or the maintainer can rename it upon applying.

Renames should go through patchwork. I can cleanup commit messages and release notes, that is where I stop.

#15 lore raw

Re: [PATCH v4 09/10] net/gve: enforce DQO Tx packet length limits

Quoted 12 lines · Stephen Hemminger
Quoted 8 lines · On Sun, 18 Oct 2026 13:24:03 +0530 Tathagat Priyadarshi…
Quoted 7 lines

drivers/net/gve/gve_tx_dqo.c gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) { · line 128

Quoted 2 lines
drivers/net/gve/gve_tx_dqo.c +2 -0
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)

Minor nit (not worth blocking over, but maybe can be done as the patches are being merged): can this be renamed to gve_tx_validate_pkt_len? This is one step of many in the packet validation pipeline.

Quoted 7 lines
Quoted 4 lines

Thanks for the review, Joshua. Agreed on renaming to gve_tx_validate_pkt_len. This change impacts patches 9/10 and 10/10. I am happy to submit a v5 series if preferred,
or the maintainer can rename it upon applying.

Renames should go through patchwork. I can cleanup commit messages and release notes, that is where I stop.

In that case, would it be okay to merge as-is? I will be following up this series directly with some TX datapath fixes of my own which are kind of related to Tathagat's fixes, so I can probably update the function name in my patch series, rather than going to v5.

#16 lore raw

Re: [PATCH v4 09/10] net/gve: enforce DQO Tx packet length limits

Thanks, Joshua.

Stephen, could you please merge these, or let me know if we still need a v5?

Quoted 27 lines · Joshua Washington
Quoted 12 lines · Stephen Hemminger
Quoted 8 lines · On Sun, 18 Oct 2026 13:24:03 +0530 Tathagat Priyadarshi…
Quoted 7 lines

drivers/net/gve/gve_tx_dqo.c gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) { · line 128

Quoted 2 lines
drivers/net/gve/gve_tx_dqo.c +2 -0
+static inline bool
+gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)

Minor nit (not worth blocking over, but maybe can be done as the patches are being merged): can this be renamed to gve_tx_validate_pkt_len? This is one step of many in the packet validation pipeline.

Quoted 7 lines
Quoted 4 lines

Thanks for the review, Joshua. Agreed on renaming to gve_tx_validate_pkt_len. This change impacts patches 9/10 and 10/10. I am happy to submit a v5 series if preferred,
or the maintainer can rename it upon applying.

Renames should go through patchwork. I can cleanup commit messages and release notes, that is where I stop.

In that case, would it be okay to merge as-is? I will be following up this series directly with some TX datapath fixes of my own which are kind of related to Tathagat's fixes, so I can probably update the function name in my patch series, rather than going to v5.