Skip to content

Commit aaa908f

Browse files
congwangdavem330
authored andcommitted
net_sched: switch to rcu_work
Commit 05f0fe6 ("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 <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: Jamal Hadi Salim <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1bb58d2 commit aaa908f

File tree

13 files changed

+85
-221
lines changed

13 files changed

+85
-221
lines changed

include/net/pkt_cls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct tcf_block_ext_info {
3333
};
3434

3535
struct tcf_block_cb;
36-
bool tcf_queue_work(struct work_struct *work);
36+
bool tcf_queue_work(struct rcu_work *rwork, work_func_t func);
3737

3838
#ifdef CONFIG_NET_CLS
3939
struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,

net/sched/cls_api.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,10 @@ int unregister_tcf_proto_ops(struct tcf_proto_ops *ops)
103103
}
104104
EXPORT_SYMBOL(unregister_tcf_proto_ops);
105105

106-
bool tcf_queue_work(struct work_struct *work)
106+
bool tcf_queue_work(struct rcu_work *rwork, work_func_t func)
107107
{
108-
return queue_work(tc_filter_wq, work);
108+
INIT_RCU_WORK(rwork, func);
109+
return queue_rcu_work(tc_filter_wq, rwork);
109110
}
110111
EXPORT_SYMBOL(tcf_queue_work);
111112

net/sched/cls_basic.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ struct basic_filter {
3535
struct tcf_result res;
3636
struct tcf_proto *tp;
3737
struct list_head link;
38-
union {
39-
struct work_struct work;
40-
struct rcu_head rcu;
41-
};
38+
struct rcu_work rwork;
4239
};
4340

4441
static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp,
@@ -97,21 +94,14 @@ static void __basic_delete_filter(struct basic_filter *f)
9794

9895
static void basic_delete_filter_work(struct work_struct *work)
9996
{
100-
struct basic_filter *f = container_of(work, struct basic_filter, work);
101-
97+
struct basic_filter *f = container_of(to_rcu_work(work),
98+
struct basic_filter,
99+
rwork);
102100
rtnl_lock();
103101
__basic_delete_filter(f);
104102
rtnl_unlock();
105103
}
106104

107-
static void basic_delete_filter(struct rcu_head *head)
108-
{
109-
struct basic_filter *f = container_of(head, struct basic_filter, rcu);
110-
111-
INIT_WORK(&f->work, basic_delete_filter_work);
112-
tcf_queue_work(&f->work);
113-
}
114-
115105
static void basic_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
116106
{
117107
struct basic_head *head = rtnl_dereference(tp->root);
@@ -122,7 +112,7 @@ static void basic_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
122112
tcf_unbind_filter(tp, &f->res);
123113
idr_remove(&head->handle_idr, f->handle);
124114
if (tcf_exts_get_net(&f->exts))
125-
call_rcu(&f->rcu, basic_delete_filter);
115+
tcf_queue_work(&f->rwork, basic_delete_filter_work);
126116
else
127117
__basic_delete_filter(f);
128118
}
@@ -140,7 +130,7 @@ static int basic_delete(struct tcf_proto *tp, void *arg, bool *last,
140130
tcf_unbind_filter(tp, &f->res);
141131
idr_remove(&head->handle_idr, f->handle);
142132
tcf_exts_get_net(&f->exts);
143-
call_rcu(&f->rcu, basic_delete_filter);
133+
tcf_queue_work(&f->rwork, basic_delete_filter_work);
144134
*last = list_empty(&head->flist);
145135
return 0;
146136
}
@@ -234,7 +224,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
234224
list_replace_rcu(&fold->link, &fnew->link);
235225
tcf_unbind_filter(tp, &fold->res);
236226
tcf_exts_get_net(&fold->exts);
237-
call_rcu(&fold->rcu, basic_delete_filter);
227+
tcf_queue_work(&fold->rwork, basic_delete_filter_work);
238228
} else {
239229
list_add_rcu(&fnew->link, &head->flist);
240230
}

net/sched/cls_bpf.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@ struct cls_bpf_prog {
4949
struct sock_filter *bpf_ops;
5050
const char *bpf_name;
5151
struct tcf_proto *tp;
52-
union {
53-
struct work_struct work;
54-
struct rcu_head rcu;
55-
};
52+
struct rcu_work rwork;
5653
};
5754

5855
static const struct nla_policy bpf_policy[TCA_BPF_MAX + 1] = {
@@ -275,21 +272,14 @@ static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog)
275272

276273
static void cls_bpf_delete_prog_work(struct work_struct *work)
277274
{
278-
struct cls_bpf_prog *prog = container_of(work, struct cls_bpf_prog, work);
279-
275+
struct cls_bpf_prog *prog = container_of(to_rcu_work(work),
276+
struct cls_bpf_prog,
277+
rwork);
280278
rtnl_lock();
281279
__cls_bpf_delete_prog(prog);
282280
rtnl_unlock();
283281
}
284282

285-
static void cls_bpf_delete_prog_rcu(struct rcu_head *rcu)
286-
{
287-
struct cls_bpf_prog *prog = container_of(rcu, struct cls_bpf_prog, rcu);
288-
289-
INIT_WORK(&prog->work, cls_bpf_delete_prog_work);
290-
tcf_queue_work(&prog->work);
291-
}
292-
293283
static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog,
294284
struct netlink_ext_ack *extack)
295285
{
@@ -300,7 +290,7 @@ static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog,
300290
list_del_rcu(&prog->link);
301291
tcf_unbind_filter(tp, &prog->res);
302292
if (tcf_exts_get_net(&prog->exts))
303-
call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu);
293+
tcf_queue_work(&prog->rwork, cls_bpf_delete_prog_work);
304294
else
305295
__cls_bpf_delete_prog(prog);
306296
}
@@ -526,7 +516,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
526516
list_replace_rcu(&oldprog->link, &prog->link);
527517
tcf_unbind_filter(tp, &oldprog->res);
528518
tcf_exts_get_net(&oldprog->exts);
529-
call_rcu(&oldprog->rcu, cls_bpf_delete_prog_rcu);
519+
tcf_queue_work(&oldprog->rwork, cls_bpf_delete_prog_work);
530520
} else {
531521
list_add_rcu(&prog->link, &head->plist);
532522
}

net/sched/cls_cgroup.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ struct cls_cgroup_head {
2323
struct tcf_exts exts;
2424
struct tcf_ematch_tree ematches;
2525
struct tcf_proto *tp;
26-
union {
27-
struct work_struct work;
28-
struct rcu_head rcu;
29-
};
26+
struct rcu_work rwork;
3027
};
3128

3229
static int cls_cgroup_classify(struct sk_buff *skb, const struct tcf_proto *tp,
@@ -70,24 +67,14 @@ static void __cls_cgroup_destroy(struct cls_cgroup_head *head)
7067

7168
static void cls_cgroup_destroy_work(struct work_struct *work)
7269
{
73-
struct cls_cgroup_head *head = container_of(work,
70+
struct cls_cgroup_head *head = container_of(to_rcu_work(work),
7471
struct cls_cgroup_head,
75-
work);
72+
rwork);
7673
rtnl_lock();
7774
__cls_cgroup_destroy(head);
7875
rtnl_unlock();
7976
}
8077

81-
static void cls_cgroup_destroy_rcu(struct rcu_head *root)
82-
{
83-
struct cls_cgroup_head *head = container_of(root,
84-
struct cls_cgroup_head,
85-
rcu);
86-
87-
INIT_WORK(&head->work, cls_cgroup_destroy_work);
88-
tcf_queue_work(&head->work);
89-
}
90-
9178
static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
9279
struct tcf_proto *tp, unsigned long base,
9380
u32 handle, struct nlattr **tca,
@@ -134,7 +121,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
134121
rcu_assign_pointer(tp->root, new);
135122
if (head) {
136123
tcf_exts_get_net(&head->exts);
137-
call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
124+
tcf_queue_work(&head->rwork, cls_cgroup_destroy_work);
138125
}
139126
return 0;
140127
errout:
@@ -151,7 +138,7 @@ static void cls_cgroup_destroy(struct tcf_proto *tp,
151138
/* Head can still be NULL due to cls_cgroup_init(). */
152139
if (head) {
153140
if (tcf_exts_get_net(&head->exts))
154-
call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
141+
tcf_queue_work(&head->rwork, cls_cgroup_destroy_work);
155142
else
156143
__cls_cgroup_destroy(head);
157144
}

net/sched/cls_flow.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ struct flow_filter {
5757
u32 divisor;
5858
u32 baseclass;
5959
u32 hashrnd;
60-
union {
61-
struct work_struct work;
62-
struct rcu_head rcu;
63-
};
60+
struct rcu_work rwork;
6461
};
6562

6663
static inline u32 addr_fold(void *addr)
@@ -383,21 +380,14 @@ static void __flow_destroy_filter(struct flow_filter *f)
383380

384381
static void flow_destroy_filter_work(struct work_struct *work)
385382
{
386-
struct flow_filter *f = container_of(work, struct flow_filter, work);
387-
383+
struct flow_filter *f = container_of(to_rcu_work(work),
384+
struct flow_filter,
385+
rwork);
388386
rtnl_lock();
389387
__flow_destroy_filter(f);
390388
rtnl_unlock();
391389
}
392390

393-
static void flow_destroy_filter(struct rcu_head *head)
394-
{
395-
struct flow_filter *f = container_of(head, struct flow_filter, rcu);
396-
397-
INIT_WORK(&f->work, flow_destroy_filter_work);
398-
tcf_queue_work(&f->work);
399-
}
400-
401391
static int flow_change(struct net *net, struct sk_buff *in_skb,
402392
struct tcf_proto *tp, unsigned long base,
403393
u32 handle, struct nlattr **tca,
@@ -563,7 +553,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
563553

564554
if (fold) {
565555
tcf_exts_get_net(&fold->exts);
566-
call_rcu(&fold->rcu, flow_destroy_filter);
556+
tcf_queue_work(&fold->rwork, flow_destroy_filter_work);
567557
}
568558
return 0;
569559

@@ -583,7 +573,7 @@ static int flow_delete(struct tcf_proto *tp, void *arg, bool *last,
583573

584574
list_del_rcu(&f->list);
585575
tcf_exts_get_net(&f->exts);
586-
call_rcu(&f->rcu, flow_destroy_filter);
576+
tcf_queue_work(&f->rwork, flow_destroy_filter_work);
587577
*last = list_empty(&head->filters);
588578
return 0;
589579
}
@@ -608,7 +598,7 @@ static void flow_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
608598
list_for_each_entry_safe(f, next, &head->filters, list) {
609599
list_del_rcu(&f->list);
610600
if (tcf_exts_get_net(&f->exts))
611-
call_rcu(&f->rcu, flow_destroy_filter);
601+
tcf_queue_work(&f->rwork, flow_destroy_filter_work);
612602
else
613603
__flow_destroy_filter(f);
614604
}

net/sched/cls_flower.c

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ struct fl_flow_mask {
7373
struct cls_fl_head {
7474
struct rhashtable ht;
7575
struct list_head masks;
76-
union {
77-
struct work_struct work;
78-
struct rcu_head rcu;
79-
};
76+
struct rcu_work rwork;
8077
struct idr handle_idr;
8178
};
8279

@@ -90,10 +87,7 @@ struct cls_fl_filter {
9087
struct list_head list;
9188
u32 handle;
9289
u32 flags;
93-
union {
94-
struct work_struct work;
95-
struct rcu_head rcu;
96-
};
90+
struct rcu_work rwork;
9791
struct net_device *hw_dev;
9892
};
9993

@@ -235,21 +229,14 @@ static void __fl_destroy_filter(struct cls_fl_filter *f)
235229

236230
static void fl_destroy_filter_work(struct work_struct *work)
237231
{
238-
struct cls_fl_filter *f = container_of(work, struct cls_fl_filter, work);
232+
struct cls_fl_filter *f = container_of(to_rcu_work(work),
233+
struct cls_fl_filter, rwork);
239234

240235
rtnl_lock();
241236
__fl_destroy_filter(f);
242237
rtnl_unlock();
243238
}
244239

245-
static void fl_destroy_filter(struct rcu_head *head)
246-
{
247-
struct cls_fl_filter *f = container_of(head, struct cls_fl_filter, rcu);
248-
249-
INIT_WORK(&f->work, fl_destroy_filter_work);
250-
tcf_queue_work(&f->work);
251-
}
252-
253240
static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f,
254241
struct netlink_ext_ack *extack)
255242
{
@@ -327,7 +314,7 @@ static bool __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f,
327314
fl_hw_destroy_filter(tp, f, extack);
328315
tcf_unbind_filter(tp, &f->res);
329316
if (async)
330-
call_rcu(&f->rcu, fl_destroy_filter);
317+
tcf_queue_work(&f->rwork, fl_destroy_filter_work);
331318
else
332319
__fl_destroy_filter(f);
333320

@@ -336,20 +323,13 @@ static bool __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f,
336323

337324
static void fl_destroy_sleepable(struct work_struct *work)
338325
{
339-
struct cls_fl_head *head = container_of(work, struct cls_fl_head,
340-
work);
326+
struct cls_fl_head *head = container_of(to_rcu_work(work),
327+
struct cls_fl_head,
328+
rwork);
341329
kfree(head);
342330
module_put(THIS_MODULE);
343331
}
344332

345-
static void fl_destroy_rcu(struct rcu_head *rcu)
346-
{
347-
struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu);
348-
349-
INIT_WORK(&head->work, fl_destroy_sleepable);
350-
schedule_work(&head->work);
351-
}
352-
353333
static void fl_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
354334
{
355335
struct cls_fl_head *head = rtnl_dereference(tp->root);
@@ -365,7 +345,7 @@ static void fl_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
365345
idr_destroy(&head->handle_idr);
366346

367347
__module_get(THIS_MODULE);
368-
call_rcu(&head->rcu, fl_destroy_rcu);
348+
tcf_queue_work(&head->rwork, fl_destroy_sleepable);
369349
}
370350

371351
static void *fl_get(struct tcf_proto *tp, u32 handle)
@@ -1036,7 +1016,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
10361016
list_replace_rcu(&fold->list, &fnew->list);
10371017
tcf_unbind_filter(tp, &fold->res);
10381018
tcf_exts_get_net(&fold->exts);
1039-
call_rcu(&fold->rcu, fl_destroy_filter);
1019+
tcf_queue_work(&fold->rwork, fl_destroy_filter_work);
10401020
} else {
10411021
list_add_tail_rcu(&fnew->list, &fnew->mask->filters);
10421022
}

0 commit comments

Comments
 (0)