Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[firefly-linux-kernel-4.4.55.git] / net / sched / cls_fw.c
index da805aeeb65c7dafa272ad4e138548fdeb66569d..dbfdfd1f1a9f8cc6d2364bed4c700eef4a029ed3 100644 (file)
@@ -123,9 +123,7 @@ static int fw_init(struct tcf_proto *tp)
 static void fw_delete_filter(struct rcu_head *head)
 {
        struct fw_filter *f = container_of(head, struct fw_filter, rcu);
-       struct tcf_proto *tp = f->tp;
 
-       tcf_unbind_filter(tp, &f->res);
        tcf_exts_destroy(&f->exts);
        kfree(f);
 }
@@ -143,6 +141,7 @@ static void fw_destroy(struct tcf_proto *tp)
                while ((f = rtnl_dereference(head->ht[h])) != NULL) {
                        RCU_INIT_POINTER(head->ht[h],
                                         rtnl_dereference(f->next));
+                       tcf_unbind_filter(tp, &f->res);
                        call_rcu(&f->rcu, fw_delete_filter);
                }
        }
@@ -166,6 +165,7 @@ static int fw_delete(struct tcf_proto *tp, unsigned long arg)
             fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
                if (pfp == f) {
                        RCU_INIT_POINTER(*fp, rtnl_dereference(f->next));
+                       tcf_unbind_filter(tp, &f->res);
                        call_rcu(&f->rcu, fw_delete_filter);
                        return 0;
                }
@@ -280,6 +280,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 
                RCU_INIT_POINTER(fnew->next, rtnl_dereference(pfp->next));
                rcu_assign_pointer(*fp, fnew);
+               tcf_unbind_filter(tp, &f->res);
                call_rcu(&f->rcu, fw_delete_filter);
 
                *arg = (unsigned long)fnew;