From: Joshua Washington <joshwash@google.com>
To: Joshua Washington <joshwash@google.com>,
Ankit Garg <nktgrg@google.com>,
Tathagat Priyadarshi <tathagat.dpdk@gmail.com>
Cc: dev@dpdk.org, stable@dpdk.org,
Praveen Kaligineedi <pkaligineedi@google.com>
Subject: [PATCH 2/3] net/gve: account for multi-mbuf headers when validating TSO
Date: Mon, 26 Oct 2026 13:23:26 -0700 [thread overview]
Message-ID: <20261026202327.3897802-3-joshwash@google.com> (raw)
In-Reply-To: <20261026202327.3897802-1-joshwash@google.com>
The DQ queue format allows TSO headers to span up to 3 descriptors.
Before this patch, the TSO descriptor limit check logic assumed that
headers would only be in a single descriptor. This can cause under
counting when processing descriptors, which can lead to hardware
failures.
As an example: suppose a header spans 3 mbufs. In that case, 3
descriptors will need to be reserved per TSO segment. Now imagine that
there is a TSO segment whose payload spans 8 buffers. The previous logic
would add one for the headers, making a total of 9, which would be
considered valid. In actuality, since the header spans 3 descriptors
themselves, there are actually 11 descriptors for the one wire segment,
which is invalid.
Compute the number of descriptors needed for the TSO header, reject
mbufs in which the headers span more than 3 buffers, and count the
number of descriptors needed against the descriptor budget per wire
packet/TSO segment.
Also, relax the strong restriction that all headers be in the same
buffer, as this is not a requirement by the hardware.
Fixes: be8f0eb81f98 ("net/gve: fix DQO TSO descriptor limit")
Fixes: 6b0452f76bf0 ("net/gve: enforce DQO Tx packet length limits")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Praveen Kaligineedi <pkaligineedi@google.com>
Reviewed-by: Ankit Garg <nktgrg@google.com>
---
Depends-on: series-39707 ("net/gve: fix DQO Tx queue stalls")
---
drivers/net/gve/base/gve_desc_dqo.h | 1 +
drivers/net/gve/gve_tx_dqo.c | 38 ++++++++++++++++++++++-------
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/net/gve/base/gve_desc_dqo.h b/drivers/net/gve/base/gve_desc_dqo.h
index 53e394f01c..b7d8b27d68 100644
--- a/drivers/net/gve/base/gve_desc_dqo.h
+++ b/drivers/net/gve/base/gve_desc_dqo.h
@@ -45,6 +45,7 @@ GVE_CHECK_STRUCT_LEN(16, gve_tx_pkt_desc_dqo);
/* Maximum number of data descriptors allowed per packet, or per-TSO segment. */
#define GVE_TX_MAX_DATA_DESCS 10
+#define GVE_TX_MAX_HEADER_DESCS_TSO 3
/* Min gap between tail and head to avoid cacheline overlap */
#define GVE_TX_MIN_DESC_PREVENT_CACHE_OVERLAP 4
diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
index 3a20109a5d..00a4ea9d27 100644
--- a/drivers/net/gve/gve_tx_dqo.c
+++ b/drivers/net/gve/gve_tx_dqo.c
@@ -138,7 +138,7 @@ gve_tx_validate_pkt(const struct rte_mbuf *tx_pkt, bool is_tso)
*/
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)
+ tx_pkt->pkt_len <= headlen)
return false;
return tx_pkt->pkt_len - headlen <= GVE_TX_MAX_TSO_LEN_DQO &&
@@ -167,20 +167,41 @@ static inline bool
gve_tx_validate_descs(const struct gve_tx_queue *txq, struct rte_mbuf *tx_pkt,
uint16_t nb_descs, bool is_tso)
{
+ int headlen = tx_pkt->l2_len + tx_pkt->l3_len + tx_pkt->l4_len;
+ int num_descs, seg_offset, mbuf_len;
+ int tso_segsz = tx_pkt->tso_segsz;
+ int header_remain = headlen;
+ uint16_t num_header_descs;
+
if (nb_descs > gve_tx_max_pkt_descs(txq))
return false;
if (!is_tso)
return nb_descs <= GVE_TX_MAX_DATA_DESCS;
- int tso_segsz = tx_pkt->tso_segsz;
- int num_descs, seg_offset, mbuf_len;
- int headlen = tx_pkt->l2_len + tx_pkt->l3_len + tx_pkt->l4_len;
+ /* Process headers. Headers can span up to 3 descriptors. */
+ if (headlen == 0)
+ return false;
+
+ num_header_descs = 1;
+ while (tx_pkt != NULL) {
+ if (header_remain <= tx_pkt->data_len)
+ break;
+
+ if (likely(tx_pkt->data_len > 0)) {
+ header_remain -= tx_pkt->data_len;
+ num_header_descs++;
+ }
- /* Headers will be split into their own buffer. */
- num_descs = 1;
+ tx_pkt = tx_pkt->next;
+ }
+
+ if (tx_pkt == NULL || num_header_descs > GVE_TX_MAX_HEADER_DESCS_TSO)
+ return false;
+
+ num_descs = num_header_descs;
seg_offset = 0;
- mbuf_len = tx_pkt->data_len - headlen;
+ mbuf_len = tx_pkt->data_len - header_remain;
while (tx_pkt) {
if (!mbuf_len)
@@ -207,7 +228,7 @@ gve_tx_validate_descs(const struct gve_tx_queue *txq, struct rte_mbuf *tx_pkt,
* segment in this mbuf is divided between two
* descriptors, both must be counted.
*/
- num_descs = 1 + !!(seg_offset) +
+ num_descs = num_header_descs + !!(seg_offset) +
(mbuf_remain < seg_offset && mbuf_remain);
} else {
seg_offset += mbuf_len;
@@ -220,7 +241,6 @@ gve_tx_validate_descs(const struct gve_tx_queue *txq, struct rte_mbuf *tx_pkt,
mbuf_len = tx_pkt->data_len;
}
-
return true;
}
--
2.56.0.307.g5fe7bd680c-goog
next prev parent reply other threads:[~2026-10-26 20:23 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 20:23 [PATCH 0/3] net/gve: TSO descriptor count fixes for GVE DQO Joshua Washington
2026-10-26 20:23 ` [PATCH 1/3] net/gve: fix segment TSO segment offset calculation Joshua Washington
2026-10-26 20:23 ` Joshua Washington [this message]
2026-10-26 20:23 ` [PATCH 3/3] net/gve: introduce Tx packet preparation for DQO format Joshua Washington
2026-10-27 4:14 ` [PATCH 0/3] net/gve: TSO descriptor count fixes for GVE DQO Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261026202327.3897802-3-joshwash@google.com \
--to=joshwash@google.com \
--cc=dev@dpdk.org \
--cc=nktgrg@google.com \
--cc=pkaligineedi@google.com \
--cc=stable@dpdk.org \
--cc=tathagat.dpdk@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox