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:

committed by
David S. Miller

parent
cae422f379
commit
0190c1d452
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user