forked from Minki/linux
net: sched: act_sample: remove dependency on rtnl lock
Use tcf spinlock to protect private sample action data from concurrent modification during dump and init. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
67b0c1a3c9
commit
d772849566
@ -80,11 +80,13 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
|
||||
}
|
||||
s = to_sample(*a);
|
||||
|
||||
spin_lock(&s->tcf_lock);
|
||||
s->tcf_action = parm->action;
|
||||
s->rate = nla_get_u32(tb[TCA_SAMPLE_RATE]);
|
||||
s->psample_group_num = nla_get_u32(tb[TCA_SAMPLE_PSAMPLE_GROUP]);
|
||||
psample_group = psample_group_get(net, s->psample_group_num);
|
||||
if (!psample_group) {
|
||||
spin_unlock(&s->tcf_lock);
|
||||
tcf_idr_release(*a, bind);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -94,6 +96,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
|
||||
s->truncate = true;
|
||||
s->trunc_size = nla_get_u32(tb[TCA_SAMPLE_TRUNC_SIZE]);
|
||||
}
|
||||
spin_unlock(&s->tcf_lock);
|
||||
|
||||
if (ret == ACT_P_CREATED)
|
||||
tcf_idr_insert(tn, *a);
|
||||
@ -105,7 +108,8 @@ static void tcf_sample_cleanup(struct tc_action *a)
|
||||
struct tcf_sample *s = to_sample(a);
|
||||
struct psample_group *psample_group;
|
||||
|
||||
psample_group = rtnl_dereference(s->psample_group);
|
||||
/* last reference to action, no need to lock */
|
||||
psample_group = rcu_dereference_protected(s->psample_group, 1);
|
||||
RCU_INIT_POINTER(s->psample_group, NULL);
|
||||
if (psample_group)
|
||||
psample_group_put(psample_group);
|
||||
@ -174,12 +178,13 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
|
||||
struct tcf_sample *s = to_sample(a);
|
||||
struct tc_sample opt = {
|
||||
.index = s->tcf_index,
|
||||
.action = s->tcf_action,
|
||||
.refcnt = refcount_read(&s->tcf_refcnt) - ref,
|
||||
.bindcnt = atomic_read(&s->tcf_bindcnt) - bind,
|
||||
};
|
||||
struct tcf_t t;
|
||||
|
||||
spin_lock(&s->tcf_lock);
|
||||
opt.action = s->tcf_action;
|
||||
if (nla_put(skb, TCA_SAMPLE_PARMS, sizeof(opt), &opt))
|
||||
goto nla_put_failure;
|
||||
|
||||
@ -196,9 +201,12 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
|
||||
|
||||
if (nla_put_u32(skb, TCA_SAMPLE_PSAMPLE_GROUP, s->psample_group_num))
|
||||
goto nla_put_failure;
|
||||
spin_unlock(&s->tcf_lock);
|
||||
|
||||
return skb->len;
|
||||
|
||||
nla_put_failure:
|
||||
spin_unlock(&s->tcf_lock);
|
||||
nlmsg_trim(skb, b);
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user