diff --git a/net/core/page_pool.c b/net/core/page_pool.c index 4ec7e6229f69..b3047197a5e8 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -414,14 +414,14 @@ static void page_pool_return_page(struct page_pool *pool, struct page *page) static bool page_pool_recycle_in_ring(struct page_pool *pool, struct page *page) { - int ret; - /* BH protection not needed if current is softirq */ - if (in_softirq()) - ret = ptr_ring_produce(&pool->ring, page); - else - ret = ptr_ring_produce_bh(&pool->ring, page); + bool in_softirq, ret; - return (ret == 0) ? true : false; + /* BH protection not needed if current is softirq */ + in_softirq = page_pool_producer_lock(pool); + ret = !__ptr_ring_produce(&pool->ring, page); + page_pool_producer_unlock(pool, in_softirq); + + return ret; } /* Only allow direct recycling in special circumstances, into the @@ -684,10 +684,14 @@ static void page_pool_scrub(struct page_pool *pool) static int page_pool_release(struct page_pool *pool) { + bool in_softirq; int inflight; page_pool_scrub(pool); inflight = page_pool_inflight(pool); + /* Acquire producer lock to make sure producers have exited. */ + in_softirq = page_pool_producer_lock(pool); + page_pool_producer_unlock(pool, in_softirq); if (!inflight) page_pool_free(pool);