net_sched: switch to rcu_work
Commit 05f0fe6b74
("RCU, workqueue: Implement rcu_work") introduces
new API's for dispatching work in a RCU callback. Now we can just
switch to the new API's for tc filters. This could get rid of a lot
of code.
Cc: Tejun Heo <tj@kernel.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
1bb58d2d3c
commit
aaa908ffbe
@@ -68,10 +68,7 @@ struct tc_u_knode {
|
||||
u32 __percpu *pcpu_success;
|
||||
#endif
|
||||
struct tcf_proto *tp;
|
||||
union {
|
||||
struct work_struct work;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
struct rcu_work rwork;
|
||||
/* The 'sel' field MUST be the last field in structure to allow for
|
||||
* tc_u32_keys allocated at end of structure.
|
||||
*/
|
||||
@@ -436,21 +433,14 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
|
||||
*/
|
||||
static void u32_delete_key_work(struct work_struct *work)
|
||||
{
|
||||
struct tc_u_knode *key = container_of(work, struct tc_u_knode, work);
|
||||
|
||||
struct tc_u_knode *key = container_of(to_rcu_work(work),
|
||||
struct tc_u_knode,
|
||||
rwork);
|
||||
rtnl_lock();
|
||||
u32_destroy_key(key->tp, key, false);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static void u32_delete_key_rcu(struct rcu_head *rcu)
|
||||
{
|
||||
struct tc_u_knode *key = container_of(rcu, struct tc_u_knode, rcu);
|
||||
|
||||
INIT_WORK(&key->work, u32_delete_key_work);
|
||||
tcf_queue_work(&key->work);
|
||||
}
|
||||
|
||||
/* u32_delete_key_freepf_rcu is the rcu callback variant
|
||||
* that free's the entire structure including the statistics
|
||||
* 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)
|
||||
*/
|
||||
static void u32_delete_key_freepf_work(struct work_struct *work)
|
||||
{
|
||||
struct tc_u_knode *key = container_of(work, struct tc_u_knode, work);
|
||||
|
||||
struct tc_u_knode *key = container_of(to_rcu_work(work),
|
||||
struct tc_u_knode,
|
||||
rwork);
|
||||
rtnl_lock();
|
||||
u32_destroy_key(key->tp, key, true);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static void u32_delete_key_freepf_rcu(struct rcu_head *rcu)
|
||||
{
|
||||
struct tc_u_knode *key = container_of(rcu, struct tc_u_knode, rcu);
|
||||
|
||||
INIT_WORK(&key->work, u32_delete_key_freepf_work);
|
||||
tcf_queue_work(&key->work);
|
||||
}
|
||||
|
||||
static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
|
||||
{
|
||||
struct tc_u_knode __rcu **kp;
|
||||
@@ -491,7 +474,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
|
||||
tcf_unbind_filter(tp, &key->res);
|
||||
idr_remove(&ht->handle_idr, key->handle);
|
||||
tcf_exts_get_net(&key->exts);
|
||||
call_rcu(&key->rcu, u32_delete_key_freepf_rcu);
|
||||
tcf_queue_work(&key->rwork, u32_delete_key_freepf_work);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -611,7 +594,7 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
|
||||
u32_remove_hw_knode(tp, n, extack);
|
||||
idr_remove(&ht->handle_idr, n->handle);
|
||||
if (tcf_exts_get_net(&n->exts))
|
||||
call_rcu(&n->rcu, u32_delete_key_freepf_rcu);
|
||||
tcf_queue_work(&n->rwork, u32_delete_key_freepf_work);
|
||||
else
|
||||
u32_destroy_key(n->tp, n, true);
|
||||
}
|
||||
@@ -995,7 +978,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
|
||||
u32_replace_knode(tp, tp_c, new);
|
||||
tcf_unbind_filter(tp, &n->res);
|
||||
tcf_exts_get_net(&n->exts);
|
||||
call_rcu(&n->rcu, u32_delete_key_rcu);
|
||||
tcf_queue_work(&n->rwork, u32_delete_key_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user