Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net_sched: add back BH safety to tcf_lock

Jamal reported that we had to use BH safety after all,
because stats can be updated from BH handler.

Fixes: 3133d5c15cb5 ("net_sched: remove BH blocking in eight actions")
Fixes: 53df77e78590 ("net_sched: act_skbmod: use RCU in tcf_skbmod_dump()")
Fixes: e97ae742972f ("net_sched: act_tunnel_key: use RCU in tunnel_key_dump()")
Fixes: 48b5e5dbdb23 ("net_sched: act_vlan: use RCU in tcf_vlan_dump()")
Reported-by: Jamal Hadi Salim <jhs@mojatatu.com>
Closes: https://lore.kernel.org/netdev/CAM0EoMmhq66EtVqDEuNik8MVFZqkgxFbMu=fJtbNoYD7YXg4bA@mail.gmail.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20250901092608.2032473-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
3016024d 23313771

+22 -22
+2 -2
net/sched/act_connmark.c
··· 169 169 170 170 nparms->action = parm->action; 171 171 172 - spin_lock(&ci->tcf_lock); 172 + spin_lock_bh(&ci->tcf_lock); 173 173 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 174 174 oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock)); 175 - spin_unlock(&ci->tcf_lock); 175 + spin_unlock_bh(&ci->tcf_lock); 176 176 177 177 if (goto_ch) 178 178 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_csum.c
··· 101 101 params_new->update_flags = parm->update_flags; 102 102 params_new->action = parm->action; 103 103 104 - spin_lock(&p->tcf_lock); 104 + spin_lock_bh(&p->tcf_lock); 105 105 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 106 106 params_new = rcu_replace_pointer(p->params, params_new, 107 107 lockdep_is_held(&p->tcf_lock)); 108 - spin_unlock(&p->tcf_lock); 108 + spin_unlock_bh(&p->tcf_lock); 109 109 110 110 if (goto_ch) 111 111 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_ct.c
··· 1410 1410 goto cleanup; 1411 1411 1412 1412 params->action = parm->action; 1413 - spin_lock(&c->tcf_lock); 1413 + spin_lock_bh(&c->tcf_lock); 1414 1414 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 1415 1415 params = rcu_replace_pointer(c->params, params, 1416 1416 lockdep_is_held(&c->tcf_lock)); 1417 - spin_unlock(&c->tcf_lock); 1417 + spin_unlock_bh(&c->tcf_lock); 1418 1418 1419 1419 if (goto_ch) 1420 1420 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_ctinfo.c
··· 258 258 259 259 cp_new->action = actparm->action; 260 260 261 - spin_lock(&ci->tcf_lock); 261 + spin_lock_bh(&ci->tcf_lock); 262 262 goto_ch = tcf_action_set_ctrlact(*a, actparm->action, goto_ch); 263 263 cp_new = rcu_replace_pointer(ci->params, cp_new, 264 264 lockdep_is_held(&ci->tcf_lock)); 265 - spin_unlock(&ci->tcf_lock); 265 + spin_unlock_bh(&ci->tcf_lock); 266 266 267 267 if (goto_ch) 268 268 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_mpls.c
··· 296 296 htons(ETH_P_MPLS_UC)); 297 297 p->action = parm->action; 298 298 299 - spin_lock(&m->tcf_lock); 299 + spin_lock_bh(&m->tcf_lock); 300 300 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 301 301 p = rcu_replace_pointer(m->mpls_p, p, lockdep_is_held(&m->tcf_lock)); 302 - spin_unlock(&m->tcf_lock); 302 + spin_unlock_bh(&m->tcf_lock); 303 303 304 304 if (goto_ch) 305 305 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_nat.c
··· 95 95 96 96 p = to_tcf_nat(*a); 97 97 98 - spin_lock(&p->tcf_lock); 98 + spin_lock_bh(&p->tcf_lock); 99 99 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 100 100 oparm = rcu_replace_pointer(p->parms, nparm, lockdep_is_held(&p->tcf_lock)); 101 - spin_unlock(&p->tcf_lock); 101 + spin_unlock_bh(&p->tcf_lock); 102 102 103 103 if (goto_ch) 104 104 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_pedit.c
··· 280 280 281 281 p = to_pedit(*a); 282 282 nparms->action = parm->action; 283 - spin_lock(&p->tcf_lock); 283 + spin_lock_bh(&p->tcf_lock); 284 284 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 285 285 oparms = rcu_replace_pointer(p->parms, nparms, 1); 286 - spin_unlock(&p->tcf_lock); 286 + spin_unlock_bh(&p->tcf_lock); 287 287 288 288 if (oparms) 289 289 call_rcu(&oparms->rcu, tcf_pedit_cleanup_rcu);
+2 -2
net/sched/act_skbedit.c
··· 261 261 params_new->mask = *mask; 262 262 263 263 params_new->action = parm->action; 264 - spin_lock(&d->tcf_lock); 264 + spin_lock_bh(&d->tcf_lock); 265 265 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 266 266 params_new = rcu_replace_pointer(d->params, params_new, 267 267 lockdep_is_held(&d->tcf_lock)); 268 - spin_unlock(&d->tcf_lock); 268 + spin_unlock_bh(&d->tcf_lock); 269 269 if (params_new) 270 270 kfree_rcu(params_new, rcu); 271 271 if (goto_ch)
+2 -2
net/sched/act_skbmod.c
··· 194 194 p->flags = lflags; 195 195 p->action = parm->action; 196 196 if (ovr) 197 - spin_lock(&d->tcf_lock); 197 + spin_lock_bh(&d->tcf_lock); 198 198 /* Protected by tcf_lock if overwriting existing action. */ 199 199 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 200 200 p_old = rcu_dereference_protected(d->skbmod_p, 1); ··· 208 208 209 209 rcu_assign_pointer(d->skbmod_p, p); 210 210 if (ovr) 211 - spin_unlock(&d->tcf_lock); 211 + spin_unlock_bh(&d->tcf_lock); 212 212 213 213 if (p_old) 214 214 kfree_rcu(p_old, rcu);
+2 -2
net/sched/act_tunnel_key.c
··· 531 531 params_new->tcft_enc_metadata = metadata; 532 532 533 533 params_new->action = parm->action; 534 - spin_lock(&t->tcf_lock); 534 + spin_lock_bh(&t->tcf_lock); 535 535 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 536 536 params_new = rcu_replace_pointer(t->params, params_new, 537 537 lockdep_is_held(&t->tcf_lock)); 538 - spin_unlock(&t->tcf_lock); 538 + spin_unlock_bh(&t->tcf_lock); 539 539 tunnel_key_release_params(params_new); 540 540 if (goto_ch) 541 541 tcf_chain_put_by_act(goto_ch);
+2 -2
net/sched/act_vlan.c
··· 253 253 } 254 254 255 255 p->action = parm->action; 256 - spin_lock(&v->tcf_lock); 256 + spin_lock_bh(&v->tcf_lock); 257 257 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 258 258 p = rcu_replace_pointer(v->vlan_p, p, lockdep_is_held(&v->tcf_lock)); 259 - spin_unlock(&v->tcf_lock); 259 + spin_unlock_bh(&v->tcf_lock); 260 260 261 261 if (goto_ch) 262 262 tcf_chain_put_by_act(goto_ch);