On Wed 21 Aug 2019 at 01:32, Matthew Wilcox <wi...@infradead.org> wrote: > From: "Matthew Wilcox (Oracle)" <wi...@infradead.org> > > Replace the mutex protecting the IDR with the XArray spinlock. > > Signed-off-by: Matthew Wilcox (Oracle) <wi...@infradead.org> > --- > include/net/act_api.h | 6 +- > net/sched/act_api.c | 127 +++++++++++++++++------------------------- > 2 files changed, 53 insertions(+), 80 deletions(-) > > diff --git a/include/net/act_api.h b/include/net/act_api.h
[...] > @@ -290,10 +283,8 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, > struct sk_buff *skb, > struct nlattr *nest; > int n_i = 0; > int ret = -EINVAL; > - struct idr *idr = &idrinfo->action_idr; > struct tc_action *p; > - unsigned long id = 1; > - unsigned long tmp; > + unsigned long index; > > nest = nla_nest_start_noflag(skb, 0); > if (nest == NULL) > @@ -301,18 +292,18 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, > struct sk_buff *skb, > if (nla_put_string(skb, TCA_KIND, ops->kind)) > goto nla_put_failure; > > - mutex_lock(&idrinfo->lock); > - idr_for_each_entry_ul(idr, p, tmp, id) { > + xa_lock(&idrinfo->actions); > + xa_for_each(&idrinfo->actions, index, p) { > ret = tcf_idr_release_unsafe(p); I like the simplification of reusing builtin xarray spinlock for this, but the reason we are using mutex here is because the following call chain: tcf_idr_release_unsafe() -> tcf_action_cleanup() -> free_tcf() -> tcf_chain_put_by_act() -> __tcf_chain_put() -> mutex_lock(&block->lock);