page_pool: unlink from napi during destroy
authorJakub Kicinski <kuba@kernel.org>
Wed, 19 Apr 2023 18:20:06 +0000 (11:20 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 21 Apr 2023 02:13:37 +0000 (19:13 -0700)
commitdd64b232deb8d48812a2ea739d1fedaeaffb59ed
tree6c10b69c274d4057732e42ee8946f0479b8897e2
parent4bb7aac70b5d8a4bddf4ee0791b834f9f56883d2
page_pool: unlink from napi during destroy

Jesper points out that we must prevent recycling into cache
after page_pool_destroy() is called, because page_pool_destroy()
is not synchronized with recycling (some pages may still be
outstanding when destroy() gets called).

I assumed this will not happen because NAPI can't be scheduled
if its page pool is being destroyed. But I missed the fact that
NAPI may get reused. For instance when user changes ring configuration
driver may allocate a new page pool, stop NAPI, swap, start NAPI,
and then destroy the old pool. The NAPI is running so old page
pool will think it can recycle to the cache, but the consumer
at that point is the destroy() path, not NAPI.

To avoid extra synchronization let the drivers do "unlinking"
during the "swap" stage while NAPI is indeed disabled.

Fixes: 8c48eea3adf3 ("page_pool: allow caching from safely localized NAPI")
Reported-by: Jesper Dangaard Brouer <jbrouer@redhat.com>
Link: https://lore.kernel.org/all/e8df2654-6a5b-3c92-489d-2fe5e444135f@redhat.com/
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Link: https://lore.kernel.org/r/20230419182006.719923-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/page_pool.h
net/core/page_pool.c