From: Naman Gulati <[email protected]>
Date: Wed, 4 Nov 2026 01:36:06 +0000
> With header split, idpf_rx_update_bufq_desc() allocates the payload
> buffer for a buffer ID first and its header buffer second. If the header
> buffer allocation fails, it returns -ENOMEM and leaves the new payload
> buffer in bufq->buf[buf_id]. idpf_rx_clean_refillq() then stops without
> consuming the refill queue entry, and the next NAPI poll retries the
> same buffer ID, again starting with the payload buffer.
> libeth_rx_alloc() overwrites bufq->buf[buf_id], and the earlier payload
> buffer is never returned to its page_pool.
>
> Each such failure leaks one payload buffer. The pool's inflight count
> never drops to zero, so when the queues are re-created or the device
> goes away, the pool never finishes shutting down and
> page_pool_release_retry() keeps warning about a stalled pool shutdown.
>
> This happens when the header buffer pool runs dry while the payload pool
> still has pages, for example under memory pressure: a header page holds
> several header buffers and only goes back to its pool once the skbs
> using all of them have been freed.
>
> Release the payload buffer when the header buffer cannot be allocated,
> as ice_alloc_rx_bufs() already does, so that the retry starts from an
> empty slot. idpf_rx_page_rel() also clears the slot, so the buffer queue
> teardown cannot release the buffer a second time.
>
> Fixes: 90912f9f4f2d ("idpf: convert header split mode to libeth +
> napi_build_skb()")
Please add `Cc: [email protected] #` with the minimum affected
version so that it will be picked up for backporting automatically.
Reviewed-by: Alexander Lobakin <[email protected]>
> Signed-off-by: Naman Gulati <[email protected]>
> ---
> drivers/net/ethernet/intel/idpf/idpf_txrx.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> index 885df6294ad94..7383d8241ead5 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> @@ -3745,8 +3745,10 @@ static int idpf_rx_update_bufq_desc(struct
> idpf_buf_queue *bufq, u32 buf_id,
> fq.truesize = bufq->hdr_truesize;
>
> addr = libeth_rx_alloc(&fq, buf_id);
> - if (addr == DMA_MAPPING_ERROR)
> + if (addr == DMA_MAPPING_ERROR) {
> + idpf_rx_page_rel(&bufq->buf[buf_id]);
> return -ENOMEM;
> + }
>
> buf_desc->hdr_addr = cpu_to_le64(addr);
Thanks,
Olek