> [PATCH v8 4/4] net/zxdh: optimize Tx xmit pkts performance
>
> Error: the simple Tx burst signals a bad packet with a short return,
> which the application cannot distinguish from backpressure.
> for (i = 0; i < nb_pkts; i++) {
> rte_prefetch0(tx_pkts[i]);
> if (unlikely(tx_pkts[i]->data_off < hdr_len)) {
> txvq->stats.errors += nb_pkts - i;
> nb_pkts = i;
> break;
> }
> }
>
> A short return from tx_burst is the backpressure signal (transmit ring
> full, retry later). Here it is also used to mean "packet i is bad",
> and the bad mbuf is left owned by the caller. The application has no
> way to tell the two apart: the usual
>
> for (sent = 0; sent < n; )
> sent += rte_eth_tx_burst(port, q, &pkts[sent], n - sent);
>
> loop treats the short return as backpressure and resubmits pkts[i],
> which fails again every time -- head-of-line blocking, and the good
> packets after i (which had ring space) never go out.
>
> A packet that cannot be sent must be consumed by the driver, not
> handed back. Free it in tx_burst, increment the tx error counter, and
> continue with the rest of the burst. For a burst of 16 where only
> index 3 is bad and the ring has room, tx_burst should return 16, with
> stats showing 15 transmitted and 1 tx error. A short return is then
> reserved for the one case the application is entitled to retry: ring
> full.
Thanks for the review.
zxdh_xmit_pkts_simple is installed only when the application
does not request RTE_ETH_TX_OFFLOAD_MULTI_SEGS.
It is the fast path for single-segment traffic;
zxdh_xmit_pkts_packed is the general path that handles multi-segment,
full per-packet validation, and arbitrary headroom.
The simple path's precondition is data_off >= hdr_len.
static_assert(RTE_PKTMBUF_HEADROOM >= ZXDH_DL_NET_HDR_SIZE)
ensures default headroom fits the header,
so freshly allocated mbufs from a conformant mempool satisfy it.
The runtime break is a defensive guard, not the error path.
A short return signals "this batch is not for this path",not ring backpressure.
The caller should keep MULTI_SEGS enabled (so packed is selected)
or use the tx_pkt_prepare hook (zxdh_xmit_pkts_simple_prepare),
which already validates data_off per packet and reports the offending index.
Adding free-and-compact into the simple path would
reintroduce a per-packet branch and an in-place compaction
loop on every burst — the overhead the fast path exists to avoid.
To make this explicit: zxdh_xmit_pkts_simple is restricted to
single-segment mbufs with data_off >= hdr_len; anything outside the
contract — including reduced-headroom mbufs — can go through
zxdh_xmit_pkts_packed.