The GQ TX datapath was set up to write the mbuf head into the sw_ring
before writing the descriptors. This poses a problem because it's
possible for the packet to be dropped due to lacking the FIFO space to
do a proper TX. In such a case, the packet won't be sent, and will lead
to leaked mbufs in the subsequent segments.
There is also no real reason that the head mbuf must be set in the
sw_ring separately from the others; the mbuf chain is not actually
walked as part of GQ TX.
Fixes: a46583cf43c8 ("net/gve: support Rx/Tx")
Cc: [email protected]
Signed-off-by: Joshua Washington <[email protected]>
Reviewed-by: Jasper Tran O'Leary <[email protected]>
---
drivers/net/gve/gve_tx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/gve/gve_tx.c b/drivers/net/gve/gve_tx.c
index 5c73c21b8d..59c82b04ed 100644
--- a/drivers/net/gve/gve_tx.c
+++ b/drivers/net/gve/gve_tx.c
@@ -301,7 +301,6 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
(uint32_t)(tx_offload.l2_len + tx_offload.l3_len +
tx_offload.l4_len) :
tx_pkt->pkt_len;
- sw_ring[sw_id] = tx_pkt;
if (!is_fifo_avail(txq, hlen)) {
gve_tx_clean(txq);
if (!is_fifo_avail(txq, hlen))
@@ -344,13 +343,14 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf
**tx_pkts, uint16_t nb_pkts)
}
/* record mbuf in sw_ring for free */
- for (i = 1; i < first->nb_segs; i++) {
+ for (i = 0; i < first->nb_segs; i++) {
+ if (!tx_pkt)
+ break;
+ sw_ring[sw_id] = tx_pkt;
sw_id = (sw_id + 1) & mask;
tx_pkt = tx_pkt->next;
- sw_ring[sw_id] = tx_pkt;
}
- sw_id = (sw_id + 1) & mask;
tx_id = (tx_id + 1) & mask;
txq->nb_free -= nb_used;
--
2.55.0.rc0.799.gd6f94ed593-goog