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

Joshua Washington joshwash at google.com
Fri Oct 16 20:18:49 CEST 2026


On Fri, Oct 16, 2026 at 10:46 AM Tathagat Priyadarshi
<tathagat.dpdk at gmail.com> wrote:
>
> 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")
> Cc: stable at dpdk.org
>
> Signed-off-by: Tathagat Priyadarshi <tathagat.dpdk at gmail.com>
Acked-by: Joshua Washington <joshwash at google.com>
> ---
>  drivers/net/gve/gve_tx_dqo.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c
> index 281700b463..46a03d482d 100644
> --- a/drivers/net/gve/gve_tx_dqo.c
> +++ b/drivers/net/gve/gve_tx_dqo.c
> @@ -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
>


More information about the dev mailing list