Skip to content

Commit 368d3cb

Browse files
Yunsheng Linkuba-moo
authored andcommitted
page_pool: fix inconsistency for page_pool_ring_[un]lock()
page_pool_ring_[un]lock() use in_softirq() to decide which spin lock variant to use, and when they are called in the context with in_softirq() being false, spin_lock_bh() is called in page_pool_ring_lock() while spin_unlock() is called in page_pool_ring_unlock(), because spin_lock_bh() has disabled the softirq in page_pool_ring_lock(), which causes inconsistency for spin lock pair calling. This patch fixes it by returning in_softirq state from page_pool_producer_lock(), and use it to decide which spin lock variant to use in page_pool_producer_unlock(). As pool->ring has both producer and consumer lock, so rename it to page_pool_producer_[un]lock() to reflect the actual usage. Also move them to page_pool.c as they are only used there, and remove the 'inline' as the compiler may have better idea to do inlining or not. Fixes: 7886244 ("net: page_pool: Add bulk support for ptr_ring") Signed-off-by: Yunsheng Lin <[email protected]> Acked-by: Jesper Dangaard Brouer <[email protected]> Acked-by: Ilias Apalodimas <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 3632679 commit 368d3cb

File tree

2 files changed

+26
-20
lines changed

2 files changed

+26
-20
lines changed

include/net/page_pool.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -399,22 +399,4 @@ static inline void page_pool_nid_changed(struct page_pool *pool, int new_nid)
399399
page_pool_update_nid(pool, new_nid);
400400
}
401401

402-
static inline void page_pool_ring_lock(struct page_pool *pool)
403-
__acquires(&pool->ring.producer_lock)
404-
{
405-
if (in_softirq())
406-
spin_lock(&pool->ring.producer_lock);
407-
else
408-
spin_lock_bh(&pool->ring.producer_lock);
409-
}
410-
411-
static inline void page_pool_ring_unlock(struct page_pool *pool)
412-
__releases(&pool->ring.producer_lock)
413-
{
414-
if (in_softirq())
415-
spin_unlock(&pool->ring.producer_lock);
416-
else
417-
spin_unlock_bh(&pool->ring.producer_lock);
418-
}
419-
420402
#endif /* _NET_PAGE_POOL_H */

net/core/page_pool.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,29 @@ EXPORT_SYMBOL(page_pool_ethtool_stats_get);
134134
#define recycle_stat_add(pool, __stat, val)
135135
#endif
136136

137+
static bool page_pool_producer_lock(struct page_pool *pool)
138+
__acquires(&pool->ring.producer_lock)
139+
{
140+
bool in_softirq = in_softirq();
141+
142+
if (in_softirq)
143+
spin_lock(&pool->ring.producer_lock);
144+
else
145+
spin_lock_bh(&pool->ring.producer_lock);
146+
147+
return in_softirq;
148+
}
149+
150+
static void page_pool_producer_unlock(struct page_pool *pool,
151+
bool in_softirq)
152+
__releases(&pool->ring.producer_lock)
153+
{
154+
if (in_softirq)
155+
spin_unlock(&pool->ring.producer_lock);
156+
else
157+
spin_unlock_bh(&pool->ring.producer_lock);
158+
}
159+
137160
static int page_pool_init(struct page_pool *pool,
138161
const struct page_pool_params *params)
139162
{
@@ -617,6 +640,7 @@ void page_pool_put_page_bulk(struct page_pool *pool, void **data,
617640
int count)
618641
{
619642
int i, bulk_len = 0;
643+
bool in_softirq;
620644

621645
for (i = 0; i < count; i++) {
622646
struct page *page = virt_to_head_page(data[i]);
@@ -635,7 +659,7 @@ void page_pool_put_page_bulk(struct page_pool *pool, void **data,
635659
return;
636660

637661
/* Bulk producer into ptr_ring page_pool cache */
638-
page_pool_ring_lock(pool);
662+
in_softirq = page_pool_producer_lock(pool);
639663
for (i = 0; i < bulk_len; i++) {
640664
if (__ptr_ring_produce(&pool->ring, data[i])) {
641665
/* ring full */
@@ -644,7 +668,7 @@ void page_pool_put_page_bulk(struct page_pool *pool, void **data,
644668
}
645669
}
646670
recycle_stat_add(pool, ring, i);
647-
page_pool_ring_unlock(pool);
671+
page_pool_producer_unlock(pool, in_softirq);
648672

649673
/* Hopefully all pages was return into ptr_ring */
650674
if (likely(i == bulk_len))

0 commit comments

Comments
 (0)