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

net_sched: act_csum: use RCU in tcf_csum_dump()

Also storing tcf_action into struct tcf_csum_params
makes sure there is no discrepancy in tcf_csum_act().

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250709090204.797558-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
ba9dc9c1 0d752877

+10 -9
+1
include/net/tc_act/tc_csum.h
··· 8 8 9 9 struct tcf_csum_params { 10 10 u32 update_flags; 11 + int action; 11 12 struct rcu_head rcu; 12 13 }; 13 14
+9 -9
net/sched/act_csum.c
··· 99 99 goto put_chain; 100 100 } 101 101 params_new->update_flags = parm->update_flags; 102 + params_new->action = parm->action; 102 103 103 104 spin_lock_bh(&p->tcf_lock); 104 105 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); ··· 581 580 tcf_lastuse_update(&p->tcf_tm); 582 581 tcf_action_update_bstats(&p->common, skb); 583 582 584 - action = READ_ONCE(p->tcf_action); 583 + action = params->action; 585 584 if (unlikely(action == TC_ACT_SHOT)) 586 585 goto drop; 587 586 ··· 632 631 static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind, 633 632 int ref) 634 633 { 634 + const struct tcf_csum *p = to_tcf_csum(a); 635 635 unsigned char *b = skb_tail_pointer(skb); 636 - struct tcf_csum *p = to_tcf_csum(a); 637 - struct tcf_csum_params *params; 636 + const struct tcf_csum_params *params; 638 637 struct tc_csum opt = { 639 638 .index = p->tcf_index, 640 639 .refcnt = refcount_read(&p->tcf_refcnt) - ref, ··· 642 641 }; 643 642 struct tcf_t t; 644 643 645 - spin_lock_bh(&p->tcf_lock); 646 - params = rcu_dereference_protected(p->params, 647 - lockdep_is_held(&p->tcf_lock)); 648 - opt.action = p->tcf_action; 644 + rcu_read_lock(); 645 + params = rcu_dereference(p->params); 646 + opt.action = params->action; 649 647 opt.update_flags = params->update_flags; 650 648 651 649 if (nla_put(skb, TCA_CSUM_PARMS, sizeof(opt), &opt)) ··· 653 653 tcf_tm_dump(&t, &p->tcf_tm); 654 654 if (nla_put_64bit(skb, TCA_CSUM_TM, sizeof(t), &t, TCA_CSUM_PAD)) 655 655 goto nla_put_failure; 656 - spin_unlock_bh(&p->tcf_lock); 656 + rcu_read_unlock(); 657 657 658 658 return skb->len; 659 659 660 660 nla_put_failure: 661 - spin_unlock_bh(&p->tcf_lock); 661 + rcu_read_unlock(); 662 662 nlmsg_trim(skb, b); 663 663 return -1; 664 664 }