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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net_sched-act-extend-rcu-use-in-dump-methods'

Eric Dumazet says:

====================
net_sched: act: extend RCU use in dump() methods

We are trying to get away from central RTNL in favor of fine-grained
mutexes. While looking at net/sched, I found that act already uses
RCU in the fast path for the most cases, and could also be used
in dump() methods.

This series is not complete and will be followed by a second one.

v1: https://lore.kernel.org/20250707130110.619822-1-edumazet@google.com
====================

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

+133 -120
+14 -9
include/net/act_api.h
··· 76 76 { 77 77 unsigned long now = jiffies; 78 78 79 - if (tm->lastuse != now) 80 - tm->lastuse = now; 81 - if (unlikely(!tm->firstuse)) 82 - tm->firstuse = now; 79 + if (READ_ONCE(tm->lastuse) != now) 80 + WRITE_ONCE(tm->lastuse, now); 81 + if (unlikely(!READ_ONCE(tm->firstuse))) 82 + WRITE_ONCE(tm->firstuse, now); 83 83 } 84 84 85 85 static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm) 86 86 { 87 - dtm->install = jiffies_to_clock_t(jiffies - stm->install); 88 - dtm->lastuse = jiffies_to_clock_t(jiffies - stm->lastuse); 89 - dtm->firstuse = stm->firstuse ? 90 - jiffies_to_clock_t(jiffies - stm->firstuse) : 0; 91 - dtm->expires = jiffies_to_clock_t(stm->expires); 87 + unsigned long firstuse, now = jiffies; 88 + 89 + dtm->install = jiffies_to_clock_t(now - READ_ONCE(stm->install)); 90 + dtm->lastuse = jiffies_to_clock_t(now - READ_ONCE(stm->lastuse)); 91 + 92 + firstuse = READ_ONCE(stm->firstuse); 93 + dtm->firstuse = firstuse ? 94 + jiffies_to_clock_t(now - firstuse) : 0; 95 + 96 + dtm->expires = jiffies_to_clock_t(READ_ONCE(stm->expires)); 92 97 } 93 98 94 99 static inline enum flow_action_hw_stats tc_act_hw_stats(u8 hw_stats)
+1
include/net/tc_act/tc_connmark.h
··· 7 7 struct tcf_connmark_parms { 8 8 struct net *net; 9 9 u16 zone; 10 + int action; 10 11 struct rcu_head rcu; 11 12 }; 12 13
+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
+1 -1
include/net/tc_act/tc_ct.h
··· 13 13 struct nf_conntrack_helper *helper; 14 14 struct nf_conn *tmpl; 15 15 u16 zone; 16 - 16 + int action; 17 17 u32 mark; 18 18 u32 mark_mask; 19 19
+4 -3
include/net/tc_act/tc_ctinfo.h
··· 7 7 struct tcf_ctinfo_params { 8 8 struct rcu_head rcu; 9 9 struct net *net; 10 + int action; 10 11 u32 dscpmask; 11 12 u32 dscpstatemask; 12 13 u32 cpmarkmask; ··· 19 18 struct tcf_ctinfo { 20 19 struct tc_action common; 21 20 struct tcf_ctinfo_params __rcu *params; 22 - u64 stats_dscp_set; 23 - u64 stats_dscp_error; 24 - u64 stats_cpmark_set; 21 + atomic64_t stats_dscp_set; 22 + atomic64_t stats_dscp_error; 23 + atomic64_t stats_cpmark_set; 25 24 }; 26 25 27 26 enum {
+1
include/net/tc_act/tc_mpls.h
··· 10 10 struct tcf_mpls_params { 11 11 int tcfm_action; 12 12 u32 tcfm_label; 13 + int action; /* tcf_action */ 13 14 u8 tcfm_tc; 14 15 u8 tcfm_ttl; 15 16 u8 tcfm_bos;
+1
include/net/tc_act/tc_nat.h
··· 6 6 #include <net/act_api.h> 7 7 8 8 struct tcf_nat_parms { 9 + int action; 9 10 __be32 old_addr; 10 11 __be32 new_addr; 11 12 __be32 mask;
+1
include/net/tc_act/tc_pedit.h
··· 14 14 struct tcf_pedit_parms { 15 15 struct tc_pedit_key *tcfp_keys; 16 16 struct tcf_pedit_key_ex *tcfp_keys_ex; 17 + int action; 17 18 u32 tcfp_off_max_hint; 18 19 unsigned char tcfp_nkeys; 19 20 unsigned char tcfp_flags;
+2 -1
include/net/tc_act/tc_police.h
··· 5 5 #include <net/act_api.h> 6 6 7 7 struct tcf_police_params { 8 + int action; 8 9 int tcfp_result; 9 10 u32 tcfp_ewma_rate; 10 - s64 tcfp_burst; 11 11 u32 tcfp_mtu; 12 + s64 tcfp_burst; 12 13 s64 tcfp_mtu_ptoks; 13 14 s64 tcfp_pkt_burst; 14 15 struct psched_ratecfg rate;
+1
include/net/tc_act/tc_skbedit.h
··· 12 12 #include <linux/tc_act/tc_skbedit.h> 13 13 14 14 struct tcf_skbedit_params { 15 + int action; 15 16 u32 flags; 16 17 u32 priority; 17 18 u32 mark;
+10 -8
net/sched/act_connmark.c
··· 88 88 /* using overlimits stats to count how many packets marked */ 89 89 tcf_action_inc_overlimit_qstats(&ca->common); 90 90 out: 91 - return READ_ONCE(ca->tcf_action); 91 + return parms->action; 92 92 } 93 93 94 94 static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = { ··· 167 167 if (err < 0) 168 168 goto release_idr; 169 169 170 + nparms->action = parm->action; 171 + 170 172 spin_lock_bh(&ci->tcf_lock); 171 173 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 172 174 oparms = rcu_replace_pointer(ci->parms, nparms, lockdep_is_held(&ci->tcf_lock)); ··· 192 190 static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, 193 191 int bind, int ref) 194 192 { 193 + const struct tcf_connmark_info *ci = to_connmark(a); 195 194 unsigned char *b = skb_tail_pointer(skb); 196 - struct tcf_connmark_info *ci = to_connmark(a); 195 + const struct tcf_connmark_parms *parms; 197 196 struct tc_connmark opt = { 198 197 .index = ci->tcf_index, 199 198 .refcnt = refcount_read(&ci->tcf_refcnt) - ref, 200 199 .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind, 201 200 }; 202 - struct tcf_connmark_parms *parms; 203 201 struct tcf_t t; 204 202 205 - spin_lock_bh(&ci->tcf_lock); 206 - parms = rcu_dereference_protected(ci->parms, lockdep_is_held(&ci->tcf_lock)); 203 + rcu_read_lock(); 204 + parms = rcu_dereference(ci->parms); 207 205 208 - opt.action = ci->tcf_action; 206 + opt.action = parms->action; 209 207 opt.zone = parms->zone; 210 208 if (nla_put(skb, TCA_CONNMARK_PARMS, sizeof(opt), &opt)) 211 209 goto nla_put_failure; ··· 214 212 if (nla_put_64bit(skb, TCA_CONNMARK_TM, sizeof(t), &t, 215 213 TCA_CONNMARK_PAD)) 216 214 goto nla_put_failure; 217 - spin_unlock_bh(&ci->tcf_lock); 215 + rcu_read_unlock(); 218 216 219 217 return skb->len; 220 218 221 219 nla_put_failure: 222 - spin_unlock_bh(&ci->tcf_lock); 220 + rcu_read_unlock(); 223 221 nlmsg_trim(skb, b); 224 222 return -1; 225 223 }
+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 }
+15 -15
net/sched/act_ct.c
··· 977 977 978 978 p = rcu_dereference_bh(c->params); 979 979 980 - retval = READ_ONCE(c->tcf_action); 980 + retval = p->action; 981 981 commit = p->ct_action & TCA_CT_ACT_COMMIT; 982 982 clear = p->ct_action & TCA_CT_ACT_CLEAR; 983 983 tmpl = p->tmpl; ··· 1409 1409 if (err) 1410 1410 goto cleanup; 1411 1411 1412 + params->action = parm->action; 1412 1413 spin_lock_bh(&c->tcf_lock); 1413 1414 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 1414 1415 params = rcu_replace_pointer(c->params, params, ··· 1443 1442 } 1444 1443 1445 1444 static int tcf_ct_dump_key_val(struct sk_buff *skb, 1446 - void *val, int val_type, 1447 - void *mask, int mask_type, 1445 + const void *val, int val_type, 1446 + const void *mask, int mask_type, 1448 1447 int len) 1449 1448 { 1450 1449 int err; ··· 1465 1464 return 0; 1466 1465 } 1467 1466 1468 - static int tcf_ct_dump_nat(struct sk_buff *skb, struct tcf_ct_params *p) 1467 + static int tcf_ct_dump_nat(struct sk_buff *skb, const struct tcf_ct_params *p) 1469 1468 { 1470 - struct nf_nat_range2 *range = &p->range; 1469 + const struct nf_nat_range2 *range = &p->range; 1471 1470 1472 1471 if (!(p->ct_action & TCA_CT_ACT_NAT)) 1473 1472 return 0; ··· 1505 1504 return 0; 1506 1505 } 1507 1506 1508 - static int tcf_ct_dump_helper(struct sk_buff *skb, struct nf_conntrack_helper *helper) 1507 + static int tcf_ct_dump_helper(struct sk_buff *skb, 1508 + const struct nf_conntrack_helper *helper) 1509 1509 { 1510 1510 if (!helper) 1511 1511 return 0; ··· 1523 1521 int bind, int ref) 1524 1522 { 1525 1523 unsigned char *b = skb_tail_pointer(skb); 1526 - struct tcf_ct *c = to_ct(a); 1527 - struct tcf_ct_params *p; 1528 - 1524 + const struct tcf_ct *c = to_ct(a); 1525 + const struct tcf_ct_params *p; 1529 1526 struct tc_ct opt = { 1530 1527 .index = c->tcf_index, 1531 1528 .refcnt = refcount_read(&c->tcf_refcnt) - ref, ··· 1532 1531 }; 1533 1532 struct tcf_t t; 1534 1533 1535 - spin_lock_bh(&c->tcf_lock); 1536 - p = rcu_dereference_protected(c->params, 1537 - lockdep_is_held(&c->tcf_lock)); 1538 - opt.action = c->tcf_action; 1534 + rcu_read_lock(); 1535 + p = rcu_dereference(c->params); 1536 + opt.action = p->action; 1539 1537 1540 1538 if (tcf_ct_dump_key_val(skb, 1541 1539 &p->ct_action, TCA_CT_ACTION, ··· 1579 1579 tcf_tm_dump(&t, &c->tcf_tm); 1580 1580 if (nla_put_64bit(skb, TCA_CT_TM, sizeof(t), &t, TCA_CT_PAD)) 1581 1581 goto nla_put_failure; 1582 - spin_unlock_bh(&c->tcf_lock); 1582 + rcu_read_unlock(); 1583 1583 1584 1584 return skb->len; 1585 1585 nla_put_failure: 1586 - spin_unlock_bh(&c->tcf_lock); 1586 + rcu_read_unlock(); 1587 1587 nlmsg_trim(skb, b); 1588 1588 return -1; 1589 1589 }
+22 -20
net/sched/act_ctinfo.c
··· 44 44 ipv4_change_dsfield(ip_hdr(skb), 45 45 INET_ECN_MASK, 46 46 newdscp); 47 - ca->stats_dscp_set++; 47 + atomic64_inc(&ca->stats_dscp_set); 48 48 } else { 49 - ca->stats_dscp_error++; 49 + atomic64_inc(&ca->stats_dscp_error); 50 50 } 51 51 } 52 52 break; ··· 57 57 ipv6_change_dsfield(ipv6_hdr(skb), 58 58 INET_ECN_MASK, 59 59 newdscp); 60 - ca->stats_dscp_set++; 60 + atomic64_inc(&ca->stats_dscp_set); 61 61 } else { 62 - ca->stats_dscp_error++; 62 + atomic64_inc(&ca->stats_dscp_error); 63 63 } 64 64 } 65 65 break; ··· 72 72 struct tcf_ctinfo_params *cp, 73 73 struct sk_buff *skb) 74 74 { 75 - ca->stats_cpmark_set++; 75 + atomic64_inc(&ca->stats_cpmark_set); 76 76 skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask; 77 77 } 78 78 ··· 88 88 struct tcf_ctinfo_params *cp; 89 89 struct nf_conn *ct; 90 90 int proto, wlen; 91 - int action; 92 91 93 92 cp = rcu_dereference_bh(ca->params); 94 93 95 94 tcf_lastuse_update(&ca->tcf_tm); 96 95 tcf_action_update_bstats(&ca->common, skb); 97 - action = READ_ONCE(ca->tcf_action); 98 96 99 97 wlen = skb_network_offset(skb); 100 98 switch (skb_protocol(skb, true)) { ··· 139 141 if (thash) 140 142 nf_ct_put(ct); 141 143 out: 142 - return action; 144 + return cp->action; 143 145 } 144 146 145 147 static const struct nla_policy ctinfo_policy[TCA_CTINFO_MAX + 1] = { ··· 256 258 cp_new->mode |= CTINFO_MODE_CPMARK; 257 259 } 258 260 261 + cp_new->action = actparm->action; 262 + 259 263 spin_lock_bh(&ci->tcf_lock); 260 264 goto_ch = tcf_action_set_ctrlact(*a, actparm->action, goto_ch); 261 265 cp_new = rcu_replace_pointer(ci->params, cp_new, ··· 282 282 static int tcf_ctinfo_dump(struct sk_buff *skb, struct tc_action *a, 283 283 int bind, int ref) 284 284 { 285 - struct tcf_ctinfo *ci = to_ctinfo(a); 285 + const struct tcf_ctinfo *ci = to_ctinfo(a); 286 + unsigned char *b = skb_tail_pointer(skb); 287 + const struct tcf_ctinfo_params *cp; 286 288 struct tc_ctinfo opt = { 287 289 .index = ci->tcf_index, 288 290 .refcnt = refcount_read(&ci->tcf_refcnt) - ref, 289 291 .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind, 290 292 }; 291 - unsigned char *b = skb_tail_pointer(skb); 292 - struct tcf_ctinfo_params *cp; 293 293 struct tcf_t t; 294 294 295 - spin_lock_bh(&ci->tcf_lock); 296 - cp = rcu_dereference_protected(ci->params, 297 - lockdep_is_held(&ci->tcf_lock)); 295 + rcu_read_lock(); 296 + cp = rcu_dereference(ci->params); 298 297 299 298 tcf_tm_dump(&t, &ci->tcf_tm); 300 299 if (nla_put_64bit(skb, TCA_CTINFO_TM, sizeof(t), &t, TCA_CTINFO_PAD)) 301 300 goto nla_put_failure; 302 301 303 - opt.action = ci->tcf_action; 302 + opt.action = cp->action; 304 303 if (nla_put(skb, TCA_CTINFO_ACT, sizeof(opt), &opt)) 305 304 goto nla_put_failure; 306 305 ··· 322 323 } 323 324 324 325 if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_DSCP_SET, 325 - ci->stats_dscp_set, TCA_CTINFO_PAD)) 326 + atomic64_read(&ci->stats_dscp_set), 327 + TCA_CTINFO_PAD)) 326 328 goto nla_put_failure; 327 329 328 330 if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_DSCP_ERROR, 329 - ci->stats_dscp_error, TCA_CTINFO_PAD)) 331 + atomic64_read(&ci->stats_dscp_error), 332 + TCA_CTINFO_PAD)) 330 333 goto nla_put_failure; 331 334 332 335 if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_CPMARK_SET, 333 - ci->stats_cpmark_set, TCA_CTINFO_PAD)) 336 + atomic64_read(&ci->stats_cpmark_set), 337 + TCA_CTINFO_PAD)) 334 338 goto nla_put_failure; 335 339 336 - spin_unlock_bh(&ci->tcf_lock); 340 + rcu_read_unlock(); 337 341 return skb->len; 338 342 339 343 nla_put_failure: 340 - spin_unlock_bh(&ci->tcf_lock); 344 + rcu_read_unlock(); 341 345 nlmsg_trim(skb, b); 342 346 return -1; 343 347 }
+10 -11
net/sched/act_mpls.c
··· 57 57 struct tcf_mpls *m = to_mpls(a); 58 58 struct tcf_mpls_params *p; 59 59 __be32 new_lse; 60 - int ret, mac_len; 60 + int mac_len; 61 61 62 62 tcf_lastuse_update(&m->tcf_tm); 63 63 bstats_update(this_cpu_ptr(m->common.cpu_bstats), skb); ··· 71 71 } else { 72 72 mac_len = skb_network_offset(skb); 73 73 } 74 - 75 - ret = READ_ONCE(m->tcf_action); 76 74 77 75 p = rcu_dereference_bh(m->mpls_p); 78 76 ··· 120 122 if (skb_at_tc_ingress(skb)) 121 123 skb_pull_rcsum(skb, skb->mac_len); 122 124 123 - return ret; 125 + return p->action; 124 126 125 127 drop: 126 128 qstats_drop_inc(this_cpu_ptr(m->common.cpu_qstats)); ··· 294 296 ACT_MPLS_BOS_NOT_SET); 295 297 p->tcfm_proto = nla_get_be16_default(tb[TCA_MPLS_PROTO], 296 298 htons(ETH_P_MPLS_UC)); 299 + p->action = parm->action; 297 300 298 301 spin_lock_bh(&m->tcf_lock); 299 302 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); ··· 329 330 int bind, int ref) 330 331 { 331 332 unsigned char *b = skb_tail_pointer(skb); 332 - struct tcf_mpls *m = to_mpls(a); 333 - struct tcf_mpls_params *p; 333 + const struct tcf_mpls *m = to_mpls(a); 334 + const struct tcf_mpls_params *p; 334 335 struct tc_mpls opt = { 335 336 .index = m->tcf_index, 336 337 .refcnt = refcount_read(&m->tcf_refcnt) - ref, ··· 338 339 }; 339 340 struct tcf_t t; 340 341 341 - spin_lock_bh(&m->tcf_lock); 342 - opt.action = m->tcf_action; 343 - p = rcu_dereference_protected(m->mpls_p, lockdep_is_held(&m->tcf_lock)); 342 + rcu_read_lock(); 343 + p = rcu_dereference(m->mpls_p); 344 344 opt.m_action = p->tcfm_action; 345 + opt.action = p->action; 345 346 346 347 if (nla_put(skb, TCA_MPLS_PARMS, sizeof(opt), &opt)) 347 348 goto nla_put_failure; ··· 369 370 if (nla_put_64bit(skb, TCA_MPLS_TM, sizeof(t), &t, TCA_MPLS_PAD)) 370 371 goto nla_put_failure; 371 372 372 - spin_unlock_bh(&m->tcf_lock); 373 + rcu_read_unlock(); 373 374 374 375 return skb->len; 375 376 376 377 nla_put_failure: 377 - spin_unlock_bh(&m->tcf_lock); 378 + rcu_read_unlock(); 378 379 nlmsg_trim(skb, b); 379 380 return -EMSGSIZE; 380 381 }
+12 -13
net/sched/act_nat.c
··· 91 91 nparm->new_addr = parm->new_addr; 92 92 nparm->mask = parm->mask; 93 93 nparm->flags = parm->flags; 94 + nparm->action = parm->action; 94 95 95 96 p = to_tcf_nat(*a); 96 97 ··· 131 130 tcf_lastuse_update(&p->tcf_tm); 132 131 tcf_action_update_bstats(&p->common, skb); 133 132 134 - action = READ_ONCE(p->tcf_action); 135 - 136 133 parms = rcu_dereference_bh(p->parms); 134 + action = parms->action; 135 + if (unlikely(action == TC_ACT_SHOT)) 136 + goto drop; 137 + 137 138 old_addr = parms->old_addr; 138 139 new_addr = parms->new_addr; 139 140 mask = parms->mask; 140 141 egress = parms->flags & TCA_NAT_FLAG_EGRESS; 141 - 142 - if (unlikely(action == TC_ACT_SHOT)) 143 - goto drop; 144 142 145 143 noff = skb_network_offset(skb); 146 144 if (!pskb_may_pull(skb, sizeof(*iph) + noff)) ··· 268 268 int bind, int ref) 269 269 { 270 270 unsigned char *b = skb_tail_pointer(skb); 271 - struct tcf_nat *p = to_tcf_nat(a); 271 + const struct tcf_nat *p = to_tcf_nat(a); 272 + const struct tcf_nat_parms *parms; 272 273 struct tc_nat opt = { 273 274 .index = p->tcf_index, 274 275 .refcnt = refcount_read(&p->tcf_refcnt) - ref, 275 276 .bindcnt = atomic_read(&p->tcf_bindcnt) - bind, 276 277 }; 277 - struct tcf_nat_parms *parms; 278 278 struct tcf_t t; 279 279 280 - spin_lock_bh(&p->tcf_lock); 280 + rcu_read_lock(); 281 281 282 - opt.action = p->tcf_action; 282 + parms = rcu_dereference(p->parms); 283 283 284 - parms = rcu_dereference_protected(p->parms, lockdep_is_held(&p->tcf_lock)); 285 - 284 + opt.action = parms->action; 286 285 opt.old_addr = parms->old_addr; 287 286 opt.new_addr = parms->new_addr; 288 287 opt.mask = parms->mask; ··· 293 294 tcf_tm_dump(&t, &p->tcf_tm); 294 295 if (nla_put_64bit(skb, TCA_NAT_TM, sizeof(t), &t, TCA_NAT_PAD)) 295 296 goto nla_put_failure; 296 - spin_unlock_bh(&p->tcf_lock); 297 + rcu_read_unlock(); 297 298 298 299 return skb->len; 299 300 300 301 nla_put_failure: 301 - spin_unlock_bh(&p->tcf_lock); 302 + rcu_read_unlock(); 302 303 nlmsg_trim(skb, b); 303 304 return -1; 304 305 }
+10 -10
net/sched/act_pedit.c
··· 279 279 } 280 280 281 281 p = to_pedit(*a); 282 - 282 + nparms->action = parm->action; 283 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); ··· 483 483 bad: 484 484 tcf_action_inc_overlimit_qstats(&p->common); 485 485 done: 486 - return p->tcf_action; 486 + return parms->action; 487 487 } 488 488 489 489 static void tcf_pedit_stats_update(struct tc_action *a, u64 bytes, u64 packets, ··· 500 500 int bind, int ref) 501 501 { 502 502 unsigned char *b = skb_tail_pointer(skb); 503 - struct tcf_pedit *p = to_pedit(a); 504 - struct tcf_pedit_parms *parms; 503 + const struct tcf_pedit *p = to_pedit(a); 504 + const struct tcf_pedit_parms *parms; 505 505 struct tc_pedit *opt; 506 506 struct tcf_t t; 507 507 int s; 508 508 509 - spin_lock_bh(&p->tcf_lock); 510 - parms = rcu_dereference_protected(p->parms, 1); 509 + rcu_read_lock(); 510 + parms = rcu_dereference(p->parms); 511 511 s = struct_size(opt, keys, parms->tcfp_nkeys); 512 512 513 513 opt = kzalloc(s, GFP_ATOMIC); 514 514 if (unlikely(!opt)) { 515 - spin_unlock_bh(&p->tcf_lock); 515 + rcu_read_unlock(); 516 516 return -ENOBUFS; 517 517 } 518 518 opt->nkeys = parms->tcfp_nkeys; ··· 521 521 flex_array_size(opt, keys, parms->tcfp_nkeys)); 522 522 opt->index = p->tcf_index; 523 523 opt->flags = parms->tcfp_flags; 524 - opt->action = p->tcf_action; 524 + opt->action = parms->action; 525 525 opt->refcnt = refcount_read(&p->tcf_refcnt) - ref; 526 526 opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind; 527 527 ··· 540 540 tcf_tm_dump(&t, &p->tcf_tm); 541 541 if (nla_put_64bit(skb, TCA_PEDIT_TM, sizeof(t), &t, TCA_PEDIT_PAD)) 542 542 goto nla_put_failure; 543 - spin_unlock_bh(&p->tcf_lock); 543 + rcu_read_unlock(); 544 544 545 545 kfree(opt); 546 546 return skb->len; 547 547 548 548 nla_put_failure: 549 - spin_unlock_bh(&p->tcf_lock); 549 + rcu_read_unlock(); 550 550 nlmsg_trim(skb, b); 551 551 kfree(opt); 552 552 return -1;
+9 -9
net/sched/act_police.c
··· 198 198 psched_ppscfg_precompute(&new->ppsrate, pps); 199 199 } 200 200 201 + new->action = parm->action; 201 202 spin_lock_bh(&police->tcf_lock); 202 203 spin_lock_bh(&police->tcfp_lock); 203 204 police->tcfp_t_c = ktime_get_ns(); ··· 255 254 tcf_lastuse_update(&police->tcf_tm); 256 255 bstats_update(this_cpu_ptr(police->common.cpu_bstats), skb); 257 256 258 - ret = READ_ONCE(police->tcf_action); 259 257 p = rcu_dereference_bh(police->params); 258 + ret = p->action; 260 259 261 260 if (p->tcfp_ewma_rate) { 262 261 struct gnet_stats_rate_est64 sample; ··· 339 338 static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a, 340 339 int bind, int ref) 341 340 { 341 + const struct tcf_police *police = to_police(a); 342 342 unsigned char *b = skb_tail_pointer(skb); 343 - struct tcf_police *police = to_police(a); 344 - struct tcf_police_params *p; 343 + const struct tcf_police_params *p; 345 344 struct tc_police opt = { 346 345 .index = police->tcf_index, 347 346 .refcnt = refcount_read(&police->tcf_refcnt) - ref, ··· 349 348 }; 350 349 struct tcf_t t; 351 350 352 - spin_lock_bh(&police->tcf_lock); 353 - opt.action = police->tcf_action; 354 - p = rcu_dereference_protected(police->params, 355 - lockdep_is_held(&police->tcf_lock)); 351 + rcu_read_lock(); 352 + p = rcu_dereference(police->params); 353 + opt.action = p->action; 356 354 opt.mtu = p->tcfp_mtu; 357 355 opt.burst = PSCHED_NS2TICKS(p->tcfp_burst); 358 356 if (p->rate_present) { ··· 392 392 tcf_tm_dump(&t, &police->tcf_tm); 393 393 if (nla_put_64bit(skb, TCA_POLICE_TM, sizeof(t), &t, TCA_POLICE_PAD)) 394 394 goto nla_put_failure; 395 - spin_unlock_bh(&police->tcf_lock); 395 + rcu_read_unlock(); 396 396 397 397 return skb->len; 398 398 399 399 nla_put_failure: 400 - spin_unlock_bh(&police->tcf_lock); 400 + rcu_read_unlock(); 401 401 nlmsg_trim(skb, b); 402 402 return -1; 403 403 }
+9 -11
net/sched/act_skbedit.c
··· 43 43 { 44 44 struct tcf_skbedit *d = to_skbedit(a); 45 45 struct tcf_skbedit_params *params; 46 - int action; 47 46 48 47 tcf_lastuse_update(&d->tcf_tm); 49 48 bstats_update(this_cpu_ptr(d->common.cpu_bstats), skb); 50 49 51 50 params = rcu_dereference_bh(d->params); 52 - action = READ_ONCE(d->tcf_action); 53 51 54 52 if (params->flags & SKBEDIT_F_PRIORITY) 55 53 skb->priority = params->priority; ··· 83 85 } 84 86 if (params->flags & SKBEDIT_F_PTYPE) 85 87 skb->pkt_type = params->ptype; 86 - return action; 88 + return params->action; 87 89 88 90 err: 89 91 qstats_drop_inc(this_cpu_ptr(d->common.cpu_qstats)); ··· 260 262 if (flags & SKBEDIT_F_MASK) 261 263 params_new->mask = *mask; 262 264 265 + params_new->action = parm->action; 263 266 spin_lock_bh(&d->tcf_lock); 264 267 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); 265 268 params_new = rcu_replace_pointer(d->params, params_new, ··· 283 284 static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a, 284 285 int bind, int ref) 285 286 { 287 + const struct tcf_skbedit *d = to_skbedit(a); 286 288 unsigned char *b = skb_tail_pointer(skb); 287 - struct tcf_skbedit *d = to_skbedit(a); 288 - struct tcf_skbedit_params *params; 289 + const struct tcf_skbedit_params *params; 289 290 struct tc_skbedit opt = { 290 291 .index = d->tcf_index, 291 292 .refcnt = refcount_read(&d->tcf_refcnt) - ref, ··· 294 295 u64 pure_flags = 0; 295 296 struct tcf_t t; 296 297 297 - spin_lock_bh(&d->tcf_lock); 298 - params = rcu_dereference_protected(d->params, 299 - lockdep_is_held(&d->tcf_lock)); 300 - opt.action = d->tcf_action; 298 + rcu_read_lock(); 299 + params = rcu_dereference(d->params); 300 + opt.action = params->action; 301 301 302 302 if (nla_put(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt)) 303 303 goto nla_put_failure; ··· 331 333 tcf_tm_dump(&t, &d->tcf_tm); 332 334 if (nla_put_64bit(skb, TCA_SKBEDIT_TM, sizeof(t), &t, TCA_SKBEDIT_PAD)) 333 335 goto nla_put_failure; 334 - spin_unlock_bh(&d->tcf_lock); 336 + rcu_read_unlock(); 335 337 336 338 return skb->len; 337 339 338 340 nla_put_failure: 339 - spin_unlock_bh(&d->tcf_lock); 341 + rcu_read_unlock(); 340 342 nlmsg_trim(skb, b); 341 343 return -1; 342 344 }