[PATCH v4 net 7/8] net: enetc: fix leak of pending XDP_TX frames when going down
From: vladimir . oltean
Date: Thu Oct 15 2026 - 07:04:47 EST
enetc_stop() calls enetc_disable_tx_bdrs() and this abruptly breaks the
natural flow where enetc_recycle_xdp_tx_buff() returns XDP_TX buffers to
the RX ring.
There are two problems. One is that frames remain stuck in the TX ring,
the other is that enetc_free_tx_ring() removes their DMA mapping but
otherwise loses track of them, i.e. does not do what
enetc_recycle_xdp_tx_buff() does, and leaves the RX ring waiting for
buffers that will never come.
We concentrate only on the latter here. The RX ring refuses to refill
itself because xdp_tx_in_flight is high, but after we bring up the
interface again, in reality we have no buffers. So all ingress traffic
will be dropped.
Fixes: 7ed2bc80074e ("net: enetc: add support for XDP_TX")
Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
---
v3->v4: patch is new
---
drivers/net/ethernet/freescale/enetc/enetc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 15c48c938a4e..fe5db840d2cc 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -165,6 +165,14 @@ static void enetc_free_tx_frame(struct enetc_bdr *tx_ring,
if (tx_swbd->dma)
enetc_unmap_tx_buff(tx_ring, tx_swbd);
+ if (tx_swbd->is_xdp_tx) {
+ struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
+ struct enetc_bdr *rx_ring;
+
+ rx_ring = enetc_rx_ring_from_xdp_tx_ring(priv, tx_ring);
+ rx_ring->xdp.xdp_tx_in_flight--;
+ __free_page(tx_swbd->page);
+ }
if (xdp_frame) {
xdp_return_frame(tx_swbd->xdp_frame);
--
2.43.0