diff options
-rw-r--r-- | include/net/pkt_cls.h | 6 | ||||
-rw-r--r-- | net/sched/cls_u32.c | 10 |
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); | |||
20 | static inline unsigned long | 20 | static 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 | ||
30 | static inline unsigned long | 26 | static 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 | ||
428 | static void u32_clear_hnode(struct tc_u_hnode *ht) | 428 | static 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 | } |