Hi all, On Wed, 13 Feb 2019 11:13:25 +1100 Stephen Rothwell wrote: > > Today's linux-next merge of the net-next tree got a conflict in: > > net/sched/cls_tcindex.c > > between commits: > > 8015d93ebd27 ("net_sched: fix a race condition in tcindex_destroy()") > 033b228e7f26 ("net_sched: fix a memory leak in cls_tcindex") > > from the net tree and commit: > > 12db03b65c2b ("net: sched: extend proto ops to support unlocked classifiers") > > from the net-next tree. > > I fixed it up (see the final resolution when linux-next is published) > and can carry the fix as necessary. This is now fixed as far as > linux-next is concerned, but any non trivial conflicts should be > mentioned to your upstream maintainer when your tree is submitted for > merging. You may also want to consider cooperating with the maintainer > of the conflicting tree to minimise any particularly complex conflicts. Actually, see the below resolution. -- Cheers, Stephen Rothwell diff --cc net/sched/cls_tcindex.c index 38bb882bb958,14d6b4058045..e6cf20bc8e80 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@@ -559,34 -563,15 +560,34 @@@ static void tcindex_destroy(struct tcf_ struct netlink_ext_ack *extack) { struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcf_walker walker; + int i; pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p); - walker.count = 0; - walker.skip = 0; - walker.fn = tcindex_destroy_element; - tcindex_walk(tp, &walker, true); - call_rcu(&p->rcu, __tcindex_destroy); + if (p->perfect) { + for (i = 0; i < p->hash; i++) { + struct tcindex_filter_result *r = p->perfect + i; + + tcf_unbind_filter(tp, &r->res); + if (tcf_exts_get_net(&r->exts)) + tcf_queue_work(&r->rwork, + tcindex_destroy_rexts_work); + else + __tcindex_destroy_rexts(r); + } + } + + for (i = 0; p->h && i < p->hash; i++) { + struct tcindex_filter *f, *next; + bool last; + + for (f = rtnl_dereference(p->h[i]); f; f = next) { + next = rtnl_dereference(f->next); - tcindex_delete(tp, &f->result, &last, NULL); ++ tcindex_delete(tp, &f->result, &last, false, NULL); + } + } + + tcf_queue_work(&p->rwork, tcindex_destroy_work); }