Skip to content

Commit

Permalink
net: sched: act_pedit: remove dependency on rtnl lock
Browse files Browse the repository at this point in the history
Rearrange pedit init code to only access pedit action data while holding
tcf spinlock. Change keys allocation type to atomic to allow it to execute
while holding tcf spinlock. Take tcf spinlock in dump function when
accessing pedit action data.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vlad Buslov authored and David S. Miller committed Aug 11, 2018
1 parent ff25276 commit 67b0c1a
Showing 1 changed file with 20 additions and 20 deletions.
40 changes: 20 additions & 20 deletions net/sched/act_pedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,51 +187,48 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
tcf_idr_cleanup(tn, parm->index);
goto out_free;
}
p = to_pedit(*a);
keys = kmalloc(ksize, GFP_KERNEL);
if (!keys) {
tcf_idr_release(*a, bind);
ret = -ENOMEM;
goto out_free;
}
ret = ACT_P_CREATED;
} else if (err > 0) {
if (bind)
goto out_free;
if (!ovr) {
tcf_idr_release(*a, bind);
ret = -EEXIST;
goto out_free;
}
p = to_pedit(*a);
if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) {
keys = kmalloc(ksize, GFP_KERNEL);
if (!keys) {
ret = -ENOMEM;
goto out_free;
}
goto out_release;
}
} else {
return err;
}

p = to_pedit(*a);
spin_lock_bh(&p->tcf_lock);
p->tcfp_flags = parm->flags;
p->tcf_action = parm->action;
if (keys) {

if (ret == ACT_P_CREATED ||
(p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys)) {
keys = kmalloc(ksize, GFP_ATOMIC);
if (!keys) {
spin_unlock_bh(&p->tcf_lock);
ret = -ENOMEM;
goto out_release;
}
kfree(p->tcfp_keys);
p->tcfp_keys = keys;
p->tcfp_nkeys = parm->nkeys;
}
memcpy(p->tcfp_keys, parm->keys, ksize);

p->tcfp_flags = parm->flags;
p->tcf_action = parm->action;

kfree(p->tcfp_keys_ex);
p->tcfp_keys_ex = keys_ex;

spin_unlock_bh(&p->tcf_lock);
if (ret == ACT_P_CREATED)
tcf_idr_insert(tn, *a);
return ret;

out_release:
tcf_idr_release(*a, bind);
out_free:
kfree(keys_ex);
return ret;
Expand Down Expand Up @@ -410,6 +407,7 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
if (unlikely(!opt))
return -ENOBUFS;

spin_lock_bh(&p->tcf_lock);
memcpy(opt->keys, p->tcfp_keys,
p->tcfp_nkeys * sizeof(struct tc_pedit_key));
opt->index = p->tcf_index;
Expand All @@ -432,11 +430,13 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
tcf_tm_dump(&t, &p->tcf_tm);
if (nla_put_64bit(skb, TCA_PEDIT_TM, sizeof(t), &t, TCA_PEDIT_PAD))
goto nla_put_failure;
spin_unlock_bh(&p->tcf_lock);

kfree(opt);
return skb->len;

nla_put_failure:
spin_unlock_bh(&p->tcf_lock);
nlmsg_trim(skb, b);
kfree(opt);
return -1;
Expand Down

0 comments on commit 67b0c1a

Please sign in to comment.