aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/cls_u32.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/cls_u32.c')
-rw-r--r--net/sched/cls_u32.c37
1 files changed, 10 insertions, 27 deletions
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index bac47b5d18fd..fb861f90fde6 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -68,10 +68,7 @@ struct tc_u_knode {
68 u32 __percpu *pcpu_success; 68 u32 __percpu *pcpu_success;
69#endif 69#endif
70 struct tcf_proto *tp; 70 struct tcf_proto *tp;
71 union { 71 struct rcu_work rwork;
72 struct work_struct work;
73 struct rcu_head rcu;
74 };
75 /* The 'sel' field MUST be the last field in structure to allow for 72 /* The 'sel' field MUST be the last field in structure to allow for
76 * tc_u32_keys allocated at end of structure. 73 * tc_u32_keys allocated at end of structure.
77 */ 74 */
@@ -436,21 +433,14 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
436 */ 433 */
437static void u32_delete_key_work(struct work_struct *work) 434static void u32_delete_key_work(struct work_struct *work)
438{ 435{
439 struct tc_u_knode *key = container_of(work, struct tc_u_knode, work); 436 struct tc_u_knode *key = container_of(to_rcu_work(work),
440 437 struct tc_u_knode,
438 rwork);
441 rtnl_lock(); 439 rtnl_lock();
442 u32_destroy_key(key->tp, key, false); 440 u32_destroy_key(key->tp, key, false);
443 rtnl_unlock(); 441 rtnl_unlock();
444} 442}
445 443
446static void u32_delete_key_rcu(struct rcu_head *rcu)
447{
448 struct tc_u_knode *key = container_of(rcu, struct tc_u_knode, rcu);
449
450 INIT_WORK(&key->work, u32_delete_key_work);
451 tcf_queue_work(&key->work);
452}
453
454/* u32_delete_key_freepf_rcu is the rcu callback variant 444/* u32_delete_key_freepf_rcu is the rcu callback variant
455 * that free's the entire structure including the statistics 445 * that free's the entire structure including the statistics
456 * percpu variables. Only use this if the key is not a copy 446 * percpu variables. Only use this if the key is not a copy
@@ -460,21 +450,14 @@ static void u32_delete_key_rcu(struct rcu_head *rcu)
460 */ 450 */
461static void u32_delete_key_freepf_work(struct work_struct *work) 451static void u32_delete_key_freepf_work(struct work_struct *work)
462{ 452{
463 struct tc_u_knode *key = container_of(work, struct tc_u_knode, work); 453 struct tc_u_knode *key = container_of(to_rcu_work(work),
464 454 struct tc_u_knode,
455 rwork);
465 rtnl_lock(); 456 rtnl_lock();
466 u32_destroy_key(key->tp, key, true); 457 u32_destroy_key(key->tp, key, true);
467 rtnl_unlock(); 458 rtnl_unlock();
468} 459}
469 460
470static void u32_delete_key_freepf_rcu(struct rcu_head *rcu)
471{
472 struct tc_u_knode *key = container_of(rcu, struct tc_u_knode, rcu);
473
474 INIT_WORK(&key->work, u32_delete_key_freepf_work);
475 tcf_queue_work(&key->work);
476}
477
478static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key) 461static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
479{ 462{
480 struct tc_u_knode __rcu **kp; 463 struct tc_u_knode __rcu **kp;
@@ -491,7 +474,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
491 tcf_unbind_filter(tp, &key->res); 474 tcf_unbind_filter(tp, &key->res);
492 idr_remove(&ht->handle_idr, key->handle); 475 idr_remove(&ht->handle_idr, key->handle);
493 tcf_exts_get_net(&key->exts); 476 tcf_exts_get_net(&key->exts);
494 call_rcu(&key->rcu, u32_delete_key_freepf_rcu); 477 tcf_queue_work(&key->rwork, u32_delete_key_freepf_work);
495 return 0; 478 return 0;
496 } 479 }
497 } 480 }
@@ -611,7 +594,7 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
611 u32_remove_hw_knode(tp, n, extack); 594 u32_remove_hw_knode(tp, n, extack);
612 idr_remove(&ht->handle_idr, n->handle); 595 idr_remove(&ht->handle_idr, n->handle);
613 if (tcf_exts_get_net(&n->exts)) 596 if (tcf_exts_get_net(&n->exts))
614 call_rcu(&n->rcu, u32_delete_key_freepf_rcu); 597 tcf_queue_work(&n->rwork, u32_delete_key_freepf_work);
615 else 598 else
616 u32_destroy_key(n->tp, n, true); 599 u32_destroy_key(n->tp, n, true);
617 } 600 }
@@ -995,7 +978,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
995 u32_replace_knode(tp, tp_c, new); 978 u32_replace_knode(tp, tp_c, new);
996 tcf_unbind_filter(tp, &n->res); 979 tcf_unbind_filter(tp, &n->res);
997 tcf_exts_get_net(&n->exts); 980 tcf_exts_get_net(&n->exts);
998 call_rcu(&n->rcu, u32_delete_key_rcu); 981 tcf_queue_work(&n->rwork, u32_delete_key_work);
999 return 0; 982 return 0;
1000 } 983 }
1001 984