RE: [EXTERNAL] [RFT] net/netvsc: fix txd leak on chimney buffer alloc failure

Long Li
2026-02-19T21:22:38Z

Thank you.

It seems we need to handle two additional early exits from the loop when hn_flush_txagg(), something like this?

diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c
index 72dab26ede..example 100644
--- a/drivers/net/netvsc/hn_rxtx.c
+++ b/drivers/net/netvsc/hn_rxtx.c
@@ -1589,8 +1589,10 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
if (txq->agg_pktleft == 0 ||
RTE_ALIGN(pkt_size, txq->agg_align) > txq->agg_szleft) {
- if (hn_flush_txagg(txq, &need_sig))
+ if (hn_flush_txagg(txq, &need_sig)) {
+ hn_txd_put(txq, txd);
goto fail;
+ }
}

pkt = hn_try_txagg(hv, txq, txd, pkt_size);
- if (unlikely(!pkt))
+ if (unlikely(!pkt)) {
+ hn_txd_put(txq, txd);
break;
+ }

hn_encap(pkt, queue_id, m);
@@ -1611,8 +1615,10 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
} else {
/* Send any outstanding packets in buffer */
- if (txq->agg_txd && hn_flush_txagg(txq, &need_sig))
+ if (txq->agg_txd && hn_flush_txagg(txq, &need_sig)) {
+ hn_txd_put(txq, txd);
goto fail;
+ }

pkt = txd->rndis_pkt;

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Wednesday, February 18, 2026 5:45 PM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; stable@dpdk.org;
> Long Li <longli@microsoft.com>; Wei Hu <weh@microsoft.com>; Haiyang
> Zhang <haiyangz@microsoft.com>
> Subject: [EXTERNAL] [RFT] net/netvsc: fix txd leak on chimney buffer alloc
> failure
>
> Audit of tx_pkt_burst() code path in drivers found this related bug.
>
> When hn_try_txagg() fails because hn_chim_alloc() cannot allocate a chimney
> buffer slot, it returns NULL without freeing the txd descriptor that was obtained
> earlier from the txd pool. The caller then breaks out of the transmit loop
> without returning the txd either.
>
> Each occurrence leaks one txd descriptor. Under sustained chimney buffer
> pressure this eventually exhausts the txd pool and blocks all transmit on the
> queue.
>
> Add hn_txd_put() before the break to return the txd to the pool.
>
> Fixes: 4e9c73e96e83 ("net/netvsc: add Hyper-V network device")
> Cc: stable@dpdk.org
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> drivers/net/netvsc/hn_rxtx.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c index
> 72dab26ede..3fc54e76b9 100644
> --- a/drivers/net/netvsc/hn_rxtx.c
> +++ b/drivers/net/netvsc/hn_rxtx.c
> @@ -1595,8 +1595,10 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>
>
> pkt = hn_try_txagg(hv, txq, txd, pkt_size);
> - if (unlikely(!pkt))
> + if (unlikely(!pkt)) {
> + hn_txd_put(txq, txd);
> break;
> + }
>
> hn_encap(pkt, queue_id, m);
> hn_append_to_chim(txq, pkt, m);
> --
> 2.51.0