On Mon, May 28, 2018 at 12:17:23AM +0300, Vlad Buslov wrote: > Implement new action API function that atomically finds and deletes action > from idr by index. Intended to be used by lockless actions that do not rely > on rtnl lock. > > Signed-off-by: Vlad Buslov <vla...@mellanox.com>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leit...@gmail.com> > --- > Changes from V1 to V2: > - Rename tcf_idr_find_delete to tcf_idr_delete_index. > > include/net/act_api.h | 1 + > net/sched/act_api.c | 39 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 40 insertions(+) > > diff --git a/include/net/act_api.h b/include/net/act_api.h > index 888ff471bbf6..d94ec6400673 100644 > --- a/include/net/act_api.h > +++ b/include/net/act_api.h > @@ -153,6 +153,7 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, > struct nlattr *est, > int bind, bool cpustats); > void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a); > > +int tcf_idr_delete_index(struct tc_action_net *tn, u32 index); > int __tcf_idr_release(struct tc_action *a, bool bind, bool strict); > > static inline int tcf_idr_release(struct tc_action *a, bool bind) > diff --git a/net/sched/act_api.c b/net/sched/act_api.c > index aa304d36fee0..0f31f09946ab 100644 > --- a/net/sched/act_api.c > +++ b/net/sched/act_api.c > @@ -319,6 +319,45 @@ bool tcf_idr_check(struct tc_action_net *tn, u32 index, > struct tc_action **a, > } > EXPORT_SYMBOL(tcf_idr_check); > > +int tcf_idr_delete_index(struct tc_action_net *tn, u32 index) > +{ > + struct tcf_idrinfo *idrinfo = tn->idrinfo; > + struct tc_action *p; > + int ret = 0; > + > + spin_lock(&idrinfo->lock); > + p = idr_find(&idrinfo->action_idr, index); > + if (!p) { > + spin_unlock(&idrinfo->lock); > + return -ENOENT; > + } > + > + if (!atomic_read(&p->tcfa_bindcnt)) { > + if (refcount_dec_and_test(&p->tcfa_refcnt)) { > + struct module *owner = p->ops->owner; > + > + WARN_ON(p != idr_remove(&idrinfo->action_idr, > + p->tcfa_index)); > + spin_unlock(&idrinfo->lock); > + > + if (p->ops->cleanup) > + p->ops->cleanup(p); > + > + gen_kill_estimator(&p->tcfa_rate_est); > + free_tcf(p); > + module_put(owner); > + return 0; > + } > + ret = 0; > + } else { > + ret = -EPERM; > + } > + > + spin_unlock(&idrinfo->lock); > + return ret; > +} > +EXPORT_SYMBOL(tcf_idr_delete_index); > + > int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, > struct tc_action **a, const struct tc_action_ops *ops, > int bind, bool cpustats) > -- > 2.7.5 >