aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/pkt_cls.h6
-rw-r--r--net/sched/cls_u32.c10
2 files changed, 7 insertions, 9 deletions
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 73f9532ee581..ef44ad9a6426 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -20,11 +20,7 @@ int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
20static inline unsigned long 20static inline unsigned long
21__cls_set_class(unsigned long *clp, unsigned long cl) 21__cls_set_class(unsigned long *clp, unsigned long cl)
22{ 22{
23 unsigned long old_cl; 23 return xchg(clp, cl);
24
25 old_cl = *clp;
26 *clp = cl;
27 return old_cl;
28} 24}
29 25
30static inline unsigned long 26static inline unsigned long
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 4be3ebf46d67..0472909bb014 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -358,7 +358,6 @@ static int u32_destroy_key(struct tcf_proto *tp,
358 struct tc_u_knode *n, 358 struct tc_u_knode *n,
359 bool free_pf) 359 bool free_pf)
360{ 360{
361 tcf_unbind_filter(tp, &n->res);
362 tcf_exts_destroy(&n->exts); 361 tcf_exts_destroy(&n->exts);
363 if (n->ht_down) 362 if (n->ht_down)
364 n->ht_down->refcnt--; 363 n->ht_down->refcnt--;
@@ -416,6 +415,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
416 if (pkp == key) { 415 if (pkp == key) {
417 RCU_INIT_POINTER(*kp, key->next); 416 RCU_INIT_POINTER(*kp, key->next);
418 417
418 tcf_unbind_filter(tp, &key->res);
419 call_rcu(&key->rcu, u32_delete_key_freepf_rcu); 419 call_rcu(&key->rcu, u32_delete_key_freepf_rcu);
420 return 0; 420 return 0;
421 } 421 }
@@ -425,7 +425,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
425 return 0; 425 return 0;
426} 426}
427 427
428static void u32_clear_hnode(struct tc_u_hnode *ht) 428static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht)
429{ 429{
430 struct tc_u_knode *n; 430 struct tc_u_knode *n;
431 unsigned int h; 431 unsigned int h;
@@ -434,6 +434,7 @@ static void u32_clear_hnode(struct tc_u_hnode *ht)
434 while ((n = rtnl_dereference(ht->ht[h])) != NULL) { 434 while ((n = rtnl_dereference(ht->ht[h])) != NULL) {
435 RCU_INIT_POINTER(ht->ht[h], 435 RCU_INIT_POINTER(ht->ht[h],
436 rtnl_dereference(n->next)); 436 rtnl_dereference(n->next));
437 tcf_unbind_filter(tp, &n->res);
437 call_rcu(&n->rcu, u32_delete_key_freepf_rcu); 438 call_rcu(&n->rcu, u32_delete_key_freepf_rcu);
438 } 439 }
439 } 440 }
@@ -447,7 +448,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht)
447 448
448 WARN_ON(ht->refcnt); 449 WARN_ON(ht->refcnt);
449 450
450 u32_clear_hnode(ht); 451 u32_clear_hnode(tp, ht);
451 452
452 hn = &tp_c->hlist; 453 hn = &tp_c->hlist;
453 for (phn = rtnl_dereference(*hn); 454 for (phn = rtnl_dereference(*hn);
@@ -482,7 +483,7 @@ static void u32_destroy(struct tcf_proto *tp)
482 ht; 483 ht;
483 ht = rtnl_dereference(ht->next)) { 484 ht = rtnl_dereference(ht->next)) {
484 ht->refcnt--; 485 ht->refcnt--;
485 u32_clear_hnode(ht); 486 u32_clear_hnode(tp, ht);
486 } 487 }
487 488
488 while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) { 489 while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
@@ -731,6 +732,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
731 } 732 }
732 733
733 u32_replace_knode(tp, tp_c, new); 734 u32_replace_knode(tp, tp_c, new);
735 tcf_unbind_filter(tp, &n->res);
734 call_rcu(&n->rcu, u32_delete_key_rcu); 736 call_rcu(&n->rcu, u32_delete_key_rcu);
735 return 0; 737 return 0;
736 } 738 }