> -----Original Message----- > From: Paul Moses <[email protected]> > Sent: Wednesday, October 28, 2026 9:50 AM > To: [email protected] > Cc: [email protected]; Nguyen, Anthony L > <[email protected]>; Kitszel, Przemyslaw > <[email protected]>; [email protected]; > [email protected]; [email protected]; [email protected]; > [email protected]; [email protected]; [email protected]; > [email protected]; [email protected]; [email protected]; Fijalkowski, > Maciej <[email protected]>; [email protected]; > [email protected]; [email protected]; linux- > [email protected]; [email protected]; [email protected] > Subject: [PATCH net v2] igc: return XSK frame copies on XDP_TX failure > > Converting an XSK buffer to an XDP frame allocates a page and returns > the original buffer to its pool. If the TX ring is full or DMA mapping > fails, igc_xdp_xmit_back() returns an error without freeing the copy. > The RX cleaner cannot release it, so the page leaks. > > Return the copied frame on TX failure. Use the RX memory type so native > frames remain RX-owned on failure. > > Fixes: fc9df2a0b520 ("igc: Enable RX via AF_XDP zero-copy") > Cc: [email protected] > Signed-off-by: Paul Moses <[email protected]> > Reviewed-by: Maciej Fijalkowski <[email protected]> > --- > v1..v2 > - Sort declarations > - Update the description to match the initialization order > > v1: https://lore.kernel.org/all/[email protected]/ > > v1 testing: > Tested on Intel I225-V with baseline and patched kernels. Physical > pause-frame backpressure caused 46 leaked copies on the baseline. > With the fix, all 72 rejected copies were returned once and freed, and > all 192 copies were accounted for. > > drivers/net/ethernet/intel/igc/igc_main.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/drivers/net/ethernet/intel/igc/igc_main.c > b/drivers/net/ethernet/intel/igc/igc_main.c > index 1fb5f3cbe..d10dfbdb1 100644 > --- a/drivers/net/ethernet/intel/igc/igc_main.c > +++ b/drivers/net/ethernet/intel/igc/igc_main.c > @@ -2488,6 +2488,7 @@ struct igc_ring *igc_get_tx_ring(struct > igc_adapter *adapter, int cpu) static int igc_xdp_xmit_back(struct > igc_adapter *adapter, struct xdp_buff *xdp) { > struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp); > + enum xdp_mem_type mem_type = xdp->rxq->mem.type; > int cpu = smp_processor_id(); > struct netdev_queue *nq; > struct igc_ring *ring; > @@ -2504,6 +2505,10 @@ static int igc_xdp_xmit_back(struct igc_adapter > *adapter, struct xdp_buff *xdp) > txq_trans_cond_update(nq); > res = igc_xdp_init_tx_descriptor(ring, xdpf); > __netif_tx_unlock(nq); > + > + if (res && mem_type == MEM_TYPE_XSK_BUFF_POOL) > + xdp_return_frame(xdpf); > + > return res; > } > > -- > 2.56.GIT >
Reviewed-by: Aleksandr Loktionov <[email protected]>
