net: sched: atomically check-allocate action

Implement function that atomically checks if action exists and either takes
reference to it, or allocates idr slot for action index to prevent
concurrent allocations of actions with same index. Use EBUSY error pointer
to indicate that idr slot is reserved.

Implement cleanup helper function that removes temporary error pointer from
idr. (in case of error between idr allocation and insertion of newly
created action to specified index)

Refactor all action init functions to insert new action to idr using this
API.

Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vlad Buslov
2018-07-05 17:24:32 +03:00
committed by David S. Miller
parent cae422f379
commit 0190c1d452
18 changed files with 216 additions and 59 deletions

View File

@@ -57,19 +57,24 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
return -EINVAL;
parm = nla_data(tb[TCA_NAT_PARMS]);
if (!tcf_idr_check(tn, parm->index, a, bind)) {
err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
if (!err) {
ret = tcf_idr_create(tn, parm->index, est, a,
&act_nat_ops, bind, false);
if (ret)
if (ret) {
tcf_idr_cleanup(tn, parm->index);
return ret;
}
ret = ACT_P_CREATED;
} else {
} else if (err > 0) {
if (bind)
return 0;
if (!ovr) {
tcf_idr_release(*a, bind);
return -EEXIST;
}
} else {
return err;
}
p = to_tcf_nat(*a);