* [PATCH 23.11 1/3] net/gve: send whole packet when mbuf is large
@ 2025-12-23 22:30 Joshua Washington
2025-12-23 22:30 ` [PATCH 23.11 2/3] net/gve: clean when insufficient Tx descriptors Joshua Washington
2025-12-23 22:30 ` [PATCH 23.11 3/3] net/gve: add DQO Tx descriptor limit Joshua Washington
0 siblings, 2 replies; 3+ messages in thread
From: Joshua Washington @ 2025-12-23 22:30 UTC (permalink / raw)
To: stable, Thomas Monjalon, Junfeng Guo, Jeroen de Borst,
Rushil Gupta, Joshua Washington
Cc: Ankit Garg
Before this patch, only one descriptor would be written per mbuf in a
packet. In cases like TSO, it is possible for a single mbuf to have more
bytes than GVE_MAX_TX_BUF_SIZE_DQO. As such, instead of simply
truncating the data down to this size, the driver should actually write
descriptors for the rest of the buffers in the mbuf segment.
To that effect, the number of descriptors needed to send a packet must
be corrected to account for the potential additional descriptors.
Fixes: 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Ankit Garg <nktgrg@google.com>
---
.mailmap | 1 +
drivers/net/gve/gve_tx_dqo.c | 53 ++++++++++++++++++++++++++----------
2 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/.mailmap b/.mailmap
index 96b7809f89..eb6a3afa44 100644
--- a/.mailmap
+++ b/.mailmap
@@ -119,6 +119,7 @@ Andy Green <andy@warmcat.com>
Andy Moreton <andy.moreton@amd.com> <amoreton@xilinx.com> <amoreton@solarflare.com>
Andy Pei <andy.pei@intel.com>
Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+Ankit Garg <nktgrg@google.com>
Ankur Dwivedi <adwivedi@marvell.com> <ankur.dwivedi@caviumnetworks.com> <ankur.dwivedi@cavium.com>
Anna Lukin <annal@silicom.co.il>
Anoob Joseph <anoobj@marvell.com> <anoob.joseph@caviumnetworks.com>
diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
index 95a02bab17..a4ba8c3536 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -74,6 +74,19 @@ gve_tx_clean_dqo(struct gve_tx_queue *txq)
txq->complq_tail = next;
}
+static uint16_t
+gve_tx_pkt_nb_data_descs(struct rte_mbuf *tx_pkt)
+{
+ int nb_descs = 0;
+
+ while (tx_pkt) {
+ nb_descs += (GVE_TX_MAX_BUF_SIZE_DQO - 1 + tx_pkt->data_len) /
+ GVE_TX_MAX_BUF_SIZE_DQO;
+ tx_pkt = tx_pkt->next;
+ }
+ return nb_descs;
+}
+
uint16_t
gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -88,7 +101,7 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
const char *reason;
uint16_t nb_tx = 0;
uint64_t ol_flags;
- uint16_t nb_used;
+ uint16_t nb_descs;
uint16_t tx_id;
uint16_t sw_id;
uint64_t bytes;
@@ -122,11 +135,14 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
}
ol_flags = tx_pkt->ol_flags;
- nb_used = tx_pkt->nb_segs;
first_sw_id = sw_id;
csum = !!(ol_flags & GVE_TX_CKSUM_OFFLOAD_MASK_DQO);
+ nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
+ if (txq->nb_free < nb_descs)
+ break;
+
do {
if (sw_ring[sw_id] != NULL)
PMD_DRV_LOG(DEBUG, "Overwriting an entry in sw_ring");
@@ -135,22 +151,29 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
if (!tx_pkt->data_len)
goto finish_mbuf;
- txd = &txr[tx_id];
sw_ring[sw_id] = tx_pkt;
- /* fill Tx descriptor */
- txd->pkt.buf_addr = rte_cpu_to_le_64(rte_mbuf_data_iova(tx_pkt));
- txd->pkt.dtype = GVE_TX_PKT_DESC_DTYPE_DQO;
- txd->pkt.compl_tag = rte_cpu_to_le_16(first_sw_id);
- txd->pkt.buf_size = RTE_MIN(tx_pkt->data_len, GVE_TX_MAX_BUF_SIZE_DQO);
- txd->pkt.end_of_packet = 0;
- txd->pkt.checksum_offload_enable = csum;
+ /* fill Tx descriptors */
+ int mbuf_offset = 0;
+ while (mbuf_offset < tx_pkt->data_len) {
+ uint64_t buf_addr = rte_mbuf_data_iova(tx_pkt) +
+ mbuf_offset;
+
+ txd = &txr[tx_id];
+ txd->pkt.buf_addr = rte_cpu_to_le_64(buf_addr);
+ txd->pkt.compl_tag = rte_cpu_to_le_16(first_sw_id);
+ txd->pkt.dtype = GVE_TX_PKT_DESC_DTYPE_DQO;
+ txd->pkt.buf_size = RTE_MIN(tx_pkt->data_len - mbuf_offset,
+ GVE_TX_MAX_BUF_SIZE_DQO);
+ txd->pkt.end_of_packet = 0;
+ txd->pkt.checksum_offload_enable = csum;
+
+ mbuf_offset += txd->pkt.buf_size;
+ tx_id = (tx_id + 1) & mask;
+ }
- /* size of desc_ring and sw_ring could be different */
- tx_id = (tx_id + 1) & mask;
finish_mbuf:
sw_id = (sw_id + 1) & sw_mask;
-
bytes += tx_pkt->data_len;
tx_pkt = tx_pkt->next;
} while (tx_pkt);
@@ -159,8 +182,8 @@ 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;
- txq->nb_free -= nb_used;
- txq->nb_used += nb_used;
+ txq->nb_free -= nb_descs;
+ txq->nb_used += nb_descs;
}
/* update the tail pointer if any packets were processed */
--
2.52.0.351.gbe84eed79e-goog
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 23.11 2/3] net/gve: clean when insufficient Tx descriptors
2025-12-23 22:30 [PATCH 23.11 1/3] net/gve: send whole packet when mbuf is large Joshua Washington
@ 2025-12-23 22:30 ` Joshua Washington
2025-12-23 22:30 ` [PATCH 23.11 3/3] net/gve: add DQO Tx descriptor limit Joshua Washington
1 sibling, 0 replies; 3+ messages in thread
From: Joshua Washington @ 2025-12-23 22:30 UTC (permalink / raw)
To: stable, Junfeng Guo, Jeroen de Borst, Rushil Gupta, Joshua Washington
Cc: Ankit Garg
A single packet can technically require more than 32 (free_thresh)
descriptors to send. Count the number of descriptors needed to send out
a packet in DQO Tx, and ensure that there are enough descriptors in the
ring before writing. If there are not enough free descriptors, drop the
packet and increment drop counters.
Fixes: 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Ankit Garg <nktgrg@google.com>
---
drivers/net/gve/gve_tx_dqo.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
index a4ba8c3536..8e75e4d570 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -74,6 +74,12 @@ gve_tx_clean_dqo(struct gve_tx_queue *txq)
txq->complq_tail = next;
}
+static inline void
+gve_tx_clean_descs_dqo(struct gve_tx_queue *txq, uint16_t nb_descs) {
+ while (--nb_descs)
+ gve_tx_clean_dqo(txq);
+}
+
static uint16_t
gve_tx_pkt_nb_data_descs(struct rte_mbuf *tx_pkt)
{
@@ -96,7 +102,6 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
struct rte_mbuf **sw_ring;
struct rte_mbuf *tx_pkt;
uint16_t mask, sw_mask;
- uint16_t nb_to_clean;
uint16_t first_sw_id;
const char *reason;
uint16_t nb_tx = 0;
@@ -119,11 +124,9 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
tx_pkt = tx_pkts[nb_tx];
- if (txq->nb_free <= txq->free_thresh) {
- nb_to_clean = DQO_TX_MULTIPLIER * txq->rs_thresh;
- while (nb_to_clean--)
- gve_tx_clean_dqo(txq);
- }
+ if (txq->nb_free <= txq->free_thresh)
+ gve_tx_clean_descs_dqo(txq, DQO_TX_MULTIPLIER *
+ txq->rs_thresh);
if (txq->nb_free < tx_pkt->nb_segs)
break;
@@ -140,8 +143,16 @@ gve_tx_burst_dqo(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
csum = !!(ol_flags & GVE_TX_CKSUM_OFFLOAD_MASK_DQO);
nb_descs = gve_tx_pkt_nb_data_descs(tx_pkt);
- if (txq->nb_free < nb_descs)
- break;
+
+ /* Clean if there aren't enough descriptors to send the packet. */
+ if (unlikely(txq->nb_free < nb_descs)) {
+ int nb_to_clean = RTE_MAX(DQO_TX_MULTIPLIER * txq->rs_thresh,
+ nb_descs);
+
+ gve_tx_clean_descs_dqo(txq, nb_to_clean);
+ if (txq->nb_free < nb_descs)
+ break;
+ }
do {
if (sw_ring[sw_id] != NULL)
--
2.52.0.351.gbe84eed79e-goog
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 23.11 3/3] net/gve: add DQO Tx descriptor limit
2025-12-23 22:30 [PATCH 23.11 1/3] net/gve: send whole packet when mbuf is large Joshua Washington
2025-12-23 22:30 ` [PATCH 23.11 2/3] net/gve: clean when insufficient Tx descriptors Joshua Washington
@ 2025-12-23 22:30 ` Joshua Washington
1 sibling, 0 replies; 3+ messages in thread
From: Joshua Washington @ 2025-12-23 22:30 UTC (permalink / raw)
To: stable, Junfeng Guo, Jeroen de Borst, Rushil Gupta, Joshua Washington
Cc: Ankit Garg
The hardware supports at most 10 data descriptors per MTU-sized segment.
GVE_TX_MAX_DATA_DESCS was defined in the initial implmenentation, but
the descriptor limit was never actually enforced.
Fixes: 4022f9999f56 ("net/gve: support basic Tx data path for DQO")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Ankit Garg <nktgrg@google.com>
---
drivers/net/gve/gve_ethdev.c | 1 +
drivers/net/gve/gve_ethdev.h | 1 +
drivers/net/gve/gve_tx_dqo.c | 6 ++++++
3 files changed, 8 insertions(+)
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index 2dc47c1226..c0df116b1b 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -450,6 +450,7 @@ gve_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
.nb_max = gve_is_gqi(priv) ? priv->tx_desc_cnt : GVE_MAX_QUEUE_SIZE_DQO,
.nb_min = priv->tx_desc_cnt,
.nb_align = 1,
+ .nb_mtu_seg_max = GVE_TX_MAX_DATA_DESCS,
};
return 0;
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index e145d6b639..2d916a40a2 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -82,6 +82,7 @@ struct gve_tx_stats {
uint64_t packets;
uint64_t bytes;
uint64_t errors;
+ uint64_t too_many_descs;
};
struct gve_rx_stats {
diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
index 8e75e4d570..96b4ef01bb 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -154,6 +154,12 @@ 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 (nb_descs > GVE_TX_MAX_DATA_DESCS) {
+ txq->stats.too_many_descs++;
+ break;
+ }
+
do {
if (sw_ring[sw_id] != NULL)
PMD_DRV_LOG(DEBUG, "Overwriting an entry in sw_ring");
--
2.52.0.351.gbe84eed79e-goog
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-12-23 22:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-23 22:30 [PATCH 23.11 1/3] net/gve: send whole packet when mbuf is large Joshua Washington
2025-12-23 22:30 ` [PATCH 23.11 2/3] net/gve: clean when insufficient Tx descriptors Joshua Washington
2025-12-23 22:30 ` [PATCH 23.11 3/3] net/gve: add DQO Tx descriptor limit Joshua Washington
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).