net: page_pool: fix use-after-free in page_pool_recycle_ring_bulk()

With CONFIG_PAGE_POOL_STATS=y, page_pool_recycle_ring_bulk() updates
the recycle stats after dropping the producer lock. If it just recycled
the last inflight netmems of a pool being destroyed, page_pool_release()
can pass its producer-lock barrier and free the pool before
recycle_stat_add() runs.

Commit fcc680a647 ("page_pool: allow mixing PPs within one bulk")
moved this stat update after the unlock. Commit 271683bb2c
("page_pool: Fix use-after-free in page_pool_recycle_in_ring") later
added the barrier, but only fixed page_pool_recycle_in_ring(). Move
the update back under the lock.

Fixes: fcc680a647 ("page_pool: allow mixing PPs within one bulk")
Link: https://lore.kernel.org/r/179028939171.2160803.706522228583664641@kernel.org
Cc: Kaifeng Wang <kaifengw@google.com>
Cc: Dong Chenchen <dongchenchen2@huawei.com>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20260925144127.1445667-1-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Mina Almasry 2026-09-25 14:41:11 +00:00 committed by Jakub Kicinski
parent 512ccd3d0e
commit bdea498018

View File

@ -951,8 +951,8 @@ static void page_pool_recycle_ring_bulk(struct page_pool *pool,
}
}
page_pool_producer_unlock(pool, in_softirq);
recycle_stat_add(pool, ring, i);
page_pool_producer_unlock(pool, in_softirq);
/* Hopefully all pages were returned into ptr_ring */
if (likely(i == bulk_len))