idpf_xskrq_poll() stashes a partially received multi-buffer frame in rxq->xsk, with its frags on pool->xskb_list. Nothing frees or clears rxq->xsk on queue release, as idpf_rx_desc_rel() only returns the page stash sharing its storage for non-XSk queues. On ifdown, the buffers are lost to user space and, as the pool outlives the queue, the stale frags are taken as frags of the next frame. If the pool is disabled on a running interface, the queue restarts in page mode with rxq->xdp.data still pointing to an xskb of the pool, which is freed later. The page path then takes it for a partial frame, writes frag info through it and returns it to a page pool. Free the stashed frame and clear the pointer when the XSk state of the queue is cleared, while the pool is still attached. Fixes: 9705d6552f58 ("idpf: implement Rx path for AF_XDP") Signed-off-by: Maciej Fijalkowski --- drivers/net/ethernet/intel/idpf/xsk.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/idpf/xsk.c b/drivers/net/ethernet/intel/idpf/xsk.c index d95d3efdfd36..5a0a1d8a7a86 100644 --- a/drivers/net/ethernet/intel/idpf/xsk.c +++ b/drivers/net/ethernet/intel/idpf/xsk.c @@ -134,6 +134,11 @@ void idpf_xsk_clear_queue(void *q, enum virtchnl2_queue_type type) if (!idpf_queue_has_clear(XSK, rxq)) return; + if (rxq->xsk) { + libeth_xsk_buff_free_slow(rxq->xsk); + rxq->xsk = NULL; + } + rxq->pool = NULL; break; case VIRTCHNL2_QUEUE_TYPE_RX_BUFFER: -- 2.43.0