On Fri, Oct 30, 2026 at 4:16 PM Marcin Knap via B4 Relay <[email protected]> wrote: > > From: Marcin Knap <[email protected]> > > When an XDP program redirects a zero-copy buffer to an XSK and the > socket's Rx ring is full, xsk_rcv_zc() frees the buffer and returns > -ENOBUFS to xdp_do_redirect(). > > A failed xdp_do_redirect() leaves the buffer owned by the caller, and > most drivers rely on that: mlx5e treats the failure as XDP_DROP and > releases the buffer when the Rx WQE is refilled, while i40e, ice, > ixgbe, igb, igc, stmmac, idpf and others free it themselves. The > buffer is therefore freed twice. It gets reused for another Rx > descriptor, the second free puts an in-use buffer back on the pool > free list, and the same UMEM frame is later handed to user space > twice. ixgbe and igb keep the buffer in the ring on their need_wakeup > -ENOBUFS (XDP_EXIT) path and run it through XDP again on the next poll, > after the core has freed it. > > Leave the buffer with the caller on both the single-buffer and the > multi-buffer -ENOBUFS paths, as xsk_rcv() and xsk_rcv_check() already > do. A few drivers relied on the core freeing the buffer, so make them > free it: > > - i40e and ice consume the descriptor on XDP_EXIT without freeing it. > - gve DQO counts the redirect error without freeing the buffer. > - octeontx2 returns false on a failed redirect, so the caller goes on > to build an skb from the already freed buffer. Free the buffer and > report it as consumed instead. > > Seen on Mellanox ConnectX-6 DX MT2892 (FW 22.47.1026) with AF_XDP > zero-copy on 7.3.0-rc6 when the user-space consumer could not keep up > with the Rx ring. With this change no duplicate frames were seen with > striding RQ on or off. > > Fixes: 269009893146 ("xsk: recycle buffer in case Rx queue was full") > Signed-off-by: Marcin Knap <[email protected]>
Agreed with Bjorn the contract can be documented as a follow-up patch. Reviewed-by: Jason Xing <[email protected]> Thanks, Jason
