Skip to content

Commit 25718fd

Browse files
Sebastian Andrzej Siewiorkuba-moo
authored andcommitted
net: gro_cells: Use nested-BH locking for gro_cell
The gro_cell data structure is per-CPU variable and relies on disabled BH for its locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT this data structure requires explicit locking. Add a local_lock_t to the data structure and use local_lock_nested_bh() for locking. This change adds only lockdep coverage and does not alter the functional behaviour for !PREEMPT_RT. Reported-by: syzbot+8715dd783e9b0bef43b1@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/68c6c3b1.050a0220.2ff435.0382.GAE@google.com/ Fixes: 3253cb4 ("softirq: Allow to drop the softirq-BKL lock on PREEMPT_RT") Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://patch.msgid.link/20251009094338.j1jyKfjR@linutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent fcb8b32 commit 25718fd

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

net/core/gro_cells.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
struct gro_cell {
99
struct sk_buff_head napi_skbs;
1010
struct napi_struct napi;
11+
local_lock_t bh_lock;
1112
};
1213

1314
int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
1415
{
1516
struct net_device *dev = skb->dev;
17+
bool have_bh_lock = false;
1618
struct gro_cell *cell;
1719
int res;
1820

@@ -25,6 +27,8 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
2527
goto unlock;
2628
}
2729

30+
local_lock_nested_bh(&gcells->cells->bh_lock);
31+
have_bh_lock = true;
2832
cell = this_cpu_ptr(gcells->cells);
2933

3034
if (skb_queue_len(&cell->napi_skbs) > READ_ONCE(net_hotdata.max_backlog)) {
@@ -39,6 +43,9 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
3943
if (skb_queue_len(&cell->napi_skbs) == 1)
4044
napi_schedule(&cell->napi);
4145

46+
if (have_bh_lock)
47+
local_unlock_nested_bh(&gcells->cells->bh_lock);
48+
4249
res = NET_RX_SUCCESS;
4350

4451
unlock:
@@ -54,6 +61,7 @@ static int gro_cell_poll(struct napi_struct *napi, int budget)
5461
struct sk_buff *skb;
5562
int work_done = 0;
5663

64+
__local_lock_nested_bh(&cell->bh_lock);
5765
while (work_done < budget) {
5866
skb = __skb_dequeue(&cell->napi_skbs);
5967
if (!skb)
@@ -64,6 +72,7 @@ static int gro_cell_poll(struct napi_struct *napi, int budget)
6472

6573
if (work_done < budget)
6674
napi_complete_done(napi, work_done);
75+
__local_unlock_nested_bh(&cell->bh_lock);
6776
return work_done;
6877
}
6978

@@ -79,6 +88,7 @@ int gro_cells_init(struct gro_cells *gcells, struct net_device *dev)
7988
struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
8089

8190
__skb_queue_head_init(&cell->napi_skbs);
91+
local_lock_init(&cell->bh_lock);
8292

8393
set_bit(NAPI_STATE_NO_BUSY_POLL, &cell->napi.state);
8494

0 commit comments

Comments
 (0)