From: David S. Miller Date: Fri, 10 Nov 2017 01:00:18 +0000 (+0900) Subject: Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net X-Git-Tag: v4.15-rc1~84^2~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4dc6758d7824a6d25717ccceefc488cafdb07210;p=thirdparty%2Flinux.git Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net Simple cases of overlapping changes in the packet scheduler. Must easier to resolve this time. Which probably means that I screwed it up somehow. Signed-off-by: David S. Miller --- 4dc6758d7824a6d25717ccceefc488cafdb07210 diff --cc net/sched/cls_basic.c index 871351358c10d,e43c56d5b96a2..5f169ded347e8 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@@ -115,10 -118,11 +120,13 @@@ static void basic_destroy(struct tcf_pr list_for_each_entry_safe(f, n, &head->flist, link) { list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); + idr_remove_ext(&head->handle_idr, f->handle); - call_rcu(&f->rcu, basic_delete_filter); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, basic_delete_filter); + else + __basic_delete_filter(f); } + idr_destroy(&head->handle_idr); kfree_rcu(head, rcu); } @@@ -129,7 -133,7 +137,8 @@@ static int basic_delete(struct tcf_prot list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); + idr_remove_ext(&head->handle_idr, f->handle); + tcf_exts_get_net(&f->exts); call_rcu(&f->rcu, basic_delete_filter); *last = list_empty(&head->flist); return 0; @@@ -222,9 -226,9 +231,10 @@@ static int basic_change(struct net *net *arg = fnew; if (fold) { + idr_replace_ext(&head->handle_idr, fnew, fnew->handle); list_replace_rcu(&fold->link, &fnew->link); tcf_unbind_filter(tp, &fold->res); + tcf_exts_get_net(&fold->exts); call_rcu(&fold->rcu, basic_delete_filter); } else { list_add_rcu(&fnew->link, &head->flist); diff --cc net/sched/cls_bpf.c index dc9bd9a0070b5,990eb4d91d542..fb680dafac5a2 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@@ -523,9 -518,9 +527,10 @@@ static int cls_bpf_change(struct net *n prog->gen_flags |= TCA_CLS_FLAGS_NOT_IN_HW; if (oldprog) { + idr_replace_ext(&head->handle_idr, prog, handle); list_replace_rcu(&oldprog->link, &prog->link); tcf_unbind_filter(tp, &oldprog->res); + tcf_exts_get_net(&oldprog->exts); call_rcu(&oldprog->rcu, cls_bpf_delete_prog_rcu); } else { list_add_rcu(&prog->link, &head->plist); diff --cc net/sched/cls_matchall.c index 95dc997873e8e,3684153cd8a9e..66d4e00991583 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@@ -113,10 -112,13 +119,13 @@@ static void mall_destroy(struct tcf_pro if (!head) return; - if (tc_should_offload(dev, head->flags)) + if (!tc_skip_hw(head->flags)) mall_destroy_hw_filter(tp, head, (unsigned long) head); - call_rcu(&head->rcu, mall_destroy_rcu); + if (tcf_exts_get_net(&head->exts)) + call_rcu(&head->rcu, mall_destroy_rcu); + else + __mall_destroy(head); } static void *mall_get(struct tcf_proto *tp, u32 handle) diff --cc net/sched/cls_u32.c index 2737b71854c97,b58eccb21f039..ac152b4f4247d --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@@ -589,8 -590,10 +591,11 @@@ static void u32_clear_hnode(struct tcf_ rtnl_dereference(n->next)); tcf_unbind_filter(tp, &n->res); u32_remove_hw_knode(tp, n->handle); + idr_remove_ext(&ht->handle_idr, n->handle); - call_rcu(&n->rcu, u32_delete_key_freepf_rcu); + if (tcf_exts_get_net(&n->exts)) + call_rcu(&n->rcu, u32_delete_key_freepf_rcu); + else + u32_destroy_key(n->tp, n, true); } } }