Skip to content

Commit b6a2b97

Browse files
w1ldptrdavem330
authored andcommitted
net: sched: act_csum: remove dependency on rtnl lock
Use tcf lock to protect csum action struct private data from concurrent modification in init and dump. Use rcu swap operation to reassign params pointer under protection of tcf lock. (old params value is not used by init, so there is no need of standalone rcu dereference step) Remove rtnl assertion that is no longer necessary. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2142236 commit b6a2b97

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

net/sched/act_csum.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
5050
struct netlink_ext_ack *extack)
5151
{
5252
struct tc_action_net *tn = net_generic(net, csum_net_id);
53-
struct tcf_csum_params *params_old, *params_new;
53+
struct tcf_csum_params *params_new;
5454
struct nlattr *tb[TCA_CSUM_MAX + 1];
5555
struct tc_csum *parm;
5656
struct tcf_csum *p;
@@ -88,20 +88,22 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
8888
}
8989

9090
p = to_tcf_csum(*a);
91-
ASSERT_RTNL();
9291

9392
params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
9493
if (unlikely(!params_new)) {
9594
tcf_idr_release(*a, bind);
9695
return -ENOMEM;
9796
}
98-
params_old = rtnl_dereference(p->params);
97+
params_new->update_flags = parm->update_flags;
9998

99+
spin_lock(&p->tcf_lock);
100100
p->tcf_action = parm->action;
101-
params_new->update_flags = parm->update_flags;
102-
rcu_assign_pointer(p->params, params_new);
103-
if (params_old)
104-
kfree_rcu(params_old, rcu);
101+
rcu_swap_protected(p->params, params_new,
102+
lockdep_is_held(&p->tcf_lock));
103+
spin_unlock(&p->tcf_lock);
104+
105+
if (params_new)
106+
kfree_rcu(params_new, rcu);
105107

106108
if (ret == ACT_P_CREATED)
107109
tcf_idr_insert(tn, *a);
@@ -599,11 +601,13 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
599601
.index = p->tcf_index,
600602
.refcnt = refcount_read(&p->tcf_refcnt) - ref,
601603
.bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
602-
.action = p->tcf_action,
603604
};
604605
struct tcf_t t;
605606

606-
params = rtnl_dereference(p->params);
607+
spin_lock(&p->tcf_lock);
608+
params = rcu_dereference_protected(p->params,
609+
lockdep_is_held(&p->tcf_lock));
610+
opt.action = p->tcf_action;
607611
opt.update_flags = params->update_flags;
608612

609613
if (nla_put(skb, TCA_CSUM_PARMS, sizeof(opt), &opt))
@@ -612,10 +616,12 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
612616
tcf_tm_dump(&t, &p->tcf_tm);
613617
if (nla_put_64bit(skb, TCA_CSUM_TM, sizeof(t), &t, TCA_CSUM_PAD))
614618
goto nla_put_failure;
619+
spin_unlock(&p->tcf_lock);
615620

616621
return skb->len;
617622

618623
nla_put_failure:
624+
spin_unlock(&p->tcf_lock);
619625
nlmsg_trim(skb, b);
620626
return -1;
621627
}

0 commit comments

Comments
 (0)