Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromtorvalds/linux

Commitdfb0555

Browse files
committed
Merge branch 'tc-filter-cleanup-destroy-delete'
Cong Wang says:====================net_sched: clean up tc filter destroy and delete logicThe first patch fixes a potenial race condition, the second oneis pure cleanup.====================Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>Signed-off-by: David S. Miller <davem@davemloft.net>
2 parentsb1d9fc4 +4392053 commitdfb0555

File tree

13 files changed

+134
-148
lines changed

13 files changed

+134
-148
lines changed

‎include/net/sch_generic.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,14 @@ struct tcf_proto_ops {
204204
conststructtcf_proto*,
205205
structtcf_result*);
206206
int(*init)(structtcf_proto*);
207-
bool(*destroy)(structtcf_proto*,bool);
207+
void(*destroy)(structtcf_proto*);
208208

209209
unsigned long(*get)(structtcf_proto*,u32handle);
210210
int(*change)(structnet*net,structsk_buff*,
211211
structtcf_proto*,unsigned long,
212212
u32handle,structnlattr**,
213213
unsigned long*,bool);
214-
int(*delete)(structtcf_proto*,unsigned long);
214+
int(*delete)(structtcf_proto*,unsigned long,bool*);
215215
void(*walk)(structtcf_proto*,structtcf_walker*arg);
216216

217217
/* rtnetlink specific */

‎net/sched/cls_api.c‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,11 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
178178
returnERR_PTR(err);
179179
}
180180

181-
staticbooltcf_proto_destroy(structtcf_proto*tp,boolforce)
181+
staticvoidtcf_proto_destroy(structtcf_proto*tp)
182182
{
183-
if (tp->ops->destroy(tp,force)) {
184-
module_put(tp->ops->owner);
185-
kfree_rcu(tp,rcu);
186-
return true;
187-
}
188-
return false;
183+
tp->ops->destroy(tp);
184+
module_put(tp->ops->owner);
185+
kfree_rcu(tp,rcu);
189186
}
190187

191188
voidtcf_destroy_chain(structtcf_proto__rcu**fl)
@@ -194,7 +191,7 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl)
194191

195192
while ((tp=rtnl_dereference(*fl))!=NULL) {
196193
RCU_INIT_POINTER(*fl,tp->next);
197-
tcf_proto_destroy(tp, true);
194+
tcf_proto_destroy(tp);
198195
}
199196
}
200197
EXPORT_SYMBOL(tcf_destroy_chain);
@@ -361,7 +358,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
361358
RCU_INIT_POINTER(*back,next);
362359
tfilter_notify(net,skb,n,tp,fh,
363360
RTM_DELTFILTER, false);
364-
tcf_proto_destroy(tp, true);
361+
tcf_proto_destroy(tp);
365362
err=0;
366363
gotoerrout;
367364
}
@@ -372,24 +369,28 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
372369
gotoerrout;
373370
}
374371
}else {
372+
boollast;
373+
375374
switch (n->nlmsg_type) {
376375
caseRTM_NEWTFILTER:
377376
if (n->nlmsg_flags&NLM_F_EXCL) {
378377
if (tp_created)
379-
tcf_proto_destroy(tp, true);
378+
tcf_proto_destroy(tp);
380379
err=-EEXIST;
381380
gotoerrout;
382381
}
383382
break;
384383
caseRTM_DELTFILTER:
385-
err=tp->ops->delete(tp,fh);
384+
err=tp->ops->delete(tp,fh,&last);
386385
if (err)
387386
gotoerrout;
388387
next=rtnl_dereference(tp->next);
389388
tfilter_notify(net,skb,n,tp,t->tcm_handle,
390389
RTM_DELTFILTER, false);
391-
if (tcf_proto_destroy(tp, false))
390+
if (last) {
392391
RCU_INIT_POINTER(*back,next);
392+
tcf_proto_destroy(tp);
393+
}
393394
gotoerrout;
394395
caseRTM_GETTFILTER:
395396
err=tfilter_notify(net,skb,n,tp,fh,
@@ -411,7 +412,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
411412
tfilter_notify(net,skb,n,tp,fh,RTM_NEWTFILTER, false);
412413
}else {
413414
if (tp_created)
414-
tcf_proto_destroy(tp, true);
415+
tcf_proto_destroy(tp);
415416
}
416417

417418
errout:

‎net/sched/cls_basic.c‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,30 +93,28 @@ static void basic_delete_filter(struct rcu_head *head)
9393
kfree(f);
9494
}
9595

96-
staticboolbasic_destroy(structtcf_proto*tp,boolforce)
96+
staticvoidbasic_destroy(structtcf_proto*tp)
9797
{
9898
structbasic_head*head=rtnl_dereference(tp->root);
9999
structbasic_filter*f,*n;
100100

101-
if (!force&& !list_empty(&head->flist))
102-
return false;
103-
104101
list_for_each_entry_safe(f,n,&head->flist,link) {
105102
list_del_rcu(&f->link);
106103
tcf_unbind_filter(tp,&f->res);
107104
call_rcu(&f->rcu,basic_delete_filter);
108105
}
109106
kfree_rcu(head,rcu);
110-
return true;
111107
}
112108

113-
staticintbasic_delete(structtcf_proto*tp,unsigned longarg)
109+
staticintbasic_delete(structtcf_proto*tp,unsigned longarg,bool*last)
114110
{
111+
structbasic_head*head=rtnl_dereference(tp->root);
115112
structbasic_filter*f= (structbasic_filter*)arg;
116113

117114
list_del_rcu(&f->link);
118115
tcf_unbind_filter(tp,&f->res);
119116
call_rcu(&f->rcu,basic_delete_filter);
117+
*last=list_empty(&head->flist);
120118
return0;
121119
}
122120

‎net/sched/cls_bpf.c‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,25 +274,24 @@ static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog)
274274
call_rcu(&prog->rcu,cls_bpf_delete_prog_rcu);
275275
}
276276

277-
staticintcls_bpf_delete(structtcf_proto*tp,unsigned longarg)
277+
staticintcls_bpf_delete(structtcf_proto*tp,unsigned longarg,bool*last)
278278
{
279+
structcls_bpf_head*head=rtnl_dereference(tp->root);
280+
279281
__cls_bpf_delete(tp, (structcls_bpf_prog*)arg);
282+
*last=list_empty(&head->plist);
280283
return0;
281284
}
282285

283-
staticboolcls_bpf_destroy(structtcf_proto*tp,boolforce)
286+
staticvoidcls_bpf_destroy(structtcf_proto*tp)
284287
{
285288
structcls_bpf_head*head=rtnl_dereference(tp->root);
286289
structcls_bpf_prog*prog,*tmp;
287290

288-
if (!force&& !list_empty(&head->plist))
289-
return false;
290-
291291
list_for_each_entry_safe(prog,tmp,&head->plist,link)
292292
__cls_bpf_delete(tp,prog);
293293

294294
kfree_rcu(head,rcu);
295-
return true;
296295
}
297296

298297
staticunsigned longcls_bpf_get(structtcf_proto*tp,u32handle)

‎net/sched/cls_cgroup.c‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,16 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
131131
returnerr;
132132
}
133133

134-
staticboolcls_cgroup_destroy(structtcf_proto*tp,boolforce)
134+
staticvoidcls_cgroup_destroy(structtcf_proto*tp)
135135
{
136136
structcls_cgroup_head*head=rtnl_dereference(tp->root);
137137

138-
if (!force)
139-
return false;
140138
/* Head can still be NULL due to cls_cgroup_init(). */
141139
if (head)
142140
call_rcu(&head->rcu,cls_cgroup_destroy_rcu);
143-
144-
return true;
145141
}
146142

147-
staticintcls_cgroup_delete(structtcf_proto*tp,unsigned longarg)
143+
staticintcls_cgroup_delete(structtcf_proto*tp,unsigned longarg,bool*last)
148144
{
149145
return-EOPNOTSUPP;
150146
}

‎net/sched/cls_flow.c‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -562,12 +562,14 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
562562
returnerr;
563563
}
564564

565-
staticintflow_delete(structtcf_proto*tp,unsigned longarg)
565+
staticintflow_delete(structtcf_proto*tp,unsigned longarg,bool*last)
566566
{
567+
structflow_head*head=rtnl_dereference(tp->root);
567568
structflow_filter*f= (structflow_filter*)arg;
568569

569570
list_del_rcu(&f->list);
570571
call_rcu(&f->rcu,flow_destroy_filter);
572+
*last=list_empty(&head->filters);
571573
return0;
572574
}
573575

@@ -583,20 +585,16 @@ static int flow_init(struct tcf_proto *tp)
583585
return0;
584586
}
585587

586-
staticboolflow_destroy(structtcf_proto*tp,boolforce)
588+
staticvoidflow_destroy(structtcf_proto*tp)
587589
{
588590
structflow_head*head=rtnl_dereference(tp->root);
589591
structflow_filter*f,*next;
590592

591-
if (!force&& !list_empty(&head->filters))
592-
return false;
593-
594593
list_for_each_entry_safe(f,next,&head->filters,list) {
595594
list_del_rcu(&f->list);
596595
call_rcu(&f->rcu,flow_destroy_filter);
597596
}
598597
kfree_rcu(head,rcu);
599-
return true;
600598
}
601599

602600
staticunsigned longflow_get(structtcf_proto*tp,u32handle)

‎net/sched/cls_flower.c‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -328,21 +328,16 @@ static void fl_destroy_rcu(struct rcu_head *rcu)
328328
schedule_work(&head->work);
329329
}
330330

331-
staticboolfl_destroy(structtcf_proto*tp,boolforce)
331+
staticvoidfl_destroy(structtcf_proto*tp)
332332
{
333333
structcls_fl_head*head=rtnl_dereference(tp->root);
334334
structcls_fl_filter*f,*next;
335335

336-
if (!force&& !list_empty(&head->filters))
337-
return false;
338-
339336
list_for_each_entry_safe(f,next,&head->filters,list)
340337
__fl_delete(tp,f);
341338

342339
__module_get(THIS_MODULE);
343340
call_rcu(&head->rcu,fl_destroy_rcu);
344-
345-
return true;
346341
}
347342

348343
staticunsigned longfl_get(structtcf_proto*tp,u32handle)
@@ -947,7 +942,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
947942
returnerr;
948943
}
949944

950-
staticintfl_delete(structtcf_proto*tp,unsigned longarg)
945+
staticintfl_delete(structtcf_proto*tp,unsigned longarg,bool*last)
951946
{
952947
structcls_fl_head*head=rtnl_dereference(tp->root);
953948
structcls_fl_filter*f= (structcls_fl_filter*)arg;
@@ -956,6 +951,7 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
956951
rhashtable_remove_fast(&head->ht,&f->ht_node,
957952
head->ht_params);
958953
__fl_delete(tp,f);
954+
*last=list_empty(&head->filters);
959955
return0;
960956
}
961957

‎net/sched/cls_fw.c‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,14 @@ static void fw_delete_filter(struct rcu_head *head)
127127
kfree(f);
128128
}
129129

130-
staticboolfw_destroy(structtcf_proto*tp,boolforce)
130+
staticvoidfw_destroy(structtcf_proto*tp)
131131
{
132132
structfw_head*head=rtnl_dereference(tp->root);
133133
structfw_filter*f;
134134
inth;
135135

136136
if (head==NULL)
137-
return true;
138-
139-
if (!force) {
140-
for (h=0;h<HTSIZE;h++)
141-
if (rcu_access_pointer(head->ht[h]))
142-
return false;
143-
}
137+
return;
144138

145139
for (h=0;h<HTSIZE;h++) {
146140
while ((f=rtnl_dereference(head->ht[h]))!=NULL) {
@@ -150,17 +144,17 @@ static bool fw_destroy(struct tcf_proto *tp, bool force)
150144
call_rcu(&f->rcu,fw_delete_filter);
151145
}
152146
}
153-
RCU_INIT_POINTER(tp->root,NULL);
154147
kfree_rcu(head,rcu);
155-
return true;
156148
}
157149

158-
staticintfw_delete(structtcf_proto*tp,unsigned longarg)
150+
staticintfw_delete(structtcf_proto*tp,unsigned longarg,bool*last)
159151
{
160152
structfw_head*head=rtnl_dereference(tp->root);
161153
structfw_filter*f= (structfw_filter*)arg;
162154
structfw_filter__rcu**fp;
163155
structfw_filter*pfp;
156+
intret=-EINVAL;
157+
inth;
164158

165159
if (head==NULL||f==NULL)
166160
gotoout;
@@ -173,11 +167,21 @@ static int fw_delete(struct tcf_proto *tp, unsigned long arg)
173167
RCU_INIT_POINTER(*fp,rtnl_dereference(f->next));
174168
tcf_unbind_filter(tp,&f->res);
175169
call_rcu(&f->rcu,fw_delete_filter);
176-
return0;
170+
ret=0;
171+
break;
177172
}
178173
}
174+
175+
*last= true;
176+
for (h=0;h<HTSIZE;h++) {
177+
if (rcu_access_pointer(head->ht[h])) {
178+
*last= false;
179+
break;
180+
}
181+
}
182+
179183
out:
180-
return-EINVAL;
184+
returnret;
181185
}
182186

183187
staticconststructnla_policyfw_policy[TCA_FW_MAX+1]= {

‎net/sched/cls_matchall.c‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,18 @@ static void mall_destroy_hw_filter(struct tcf_proto *tp,
9090
&offload);
9191
}
9292

93-
staticboolmall_destroy(structtcf_proto*tp,boolforce)
93+
staticvoidmall_destroy(structtcf_proto*tp)
9494
{
9595
structcls_mall_head*head=rtnl_dereference(tp->root);
9696
structnet_device*dev=tp->q->dev_queue->dev;
9797

9898
if (!head)
99-
return true;
99+
return;
100100

101101
if (tc_should_offload(dev,tp,head->flags))
102102
mall_destroy_hw_filter(tp,head, (unsigned long)head);
103103

104104
call_rcu(&head->rcu,mall_destroy_rcu);
105-
return true;
106105
}
107106

108107
staticunsigned longmall_get(structtcf_proto*tp,u32handle)
@@ -216,7 +215,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
216215
returnerr;
217216
}
218217

219-
staticintmall_delete(structtcf_proto*tp,unsigned longarg)
218+
staticintmall_delete(structtcf_proto*tp,unsigned longarg,bool*last)
220219
{
221220
return-EOPNOTSUPP;
222221
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp