aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_sfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_sfb.c')
-rw-r--r--net/sched/sch_sfb.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 9b0f7093d970..5819dd82630d 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -55,7 +55,7 @@ struct sfb_bins {
55 55
56struct sfb_sched_data { 56struct sfb_sched_data {
57 struct Qdisc *qdisc; 57 struct Qdisc *qdisc;
58 struct tcf_proto *filter_list; 58 struct tcf_proto __rcu *filter_list;
59 unsigned long rehash_interval; 59 unsigned long rehash_interval;
60 unsigned long warmup_time; /* double buffering warmup time in jiffies */ 60 unsigned long warmup_time; /* double buffering warmup time in jiffies */
61 u32 max; 61 u32 max;
@@ -253,13 +253,13 @@ static bool sfb_rate_limit(struct sk_buff *skb, struct sfb_sched_data *q)
253 return false; 253 return false;
254} 254}
255 255
256static bool sfb_classify(struct sk_buff *skb, struct sfb_sched_data *q, 256static bool sfb_classify(struct sk_buff *skb, struct tcf_proto *fl,
257 int *qerr, u32 *salt) 257 int *qerr, u32 *salt)
258{ 258{
259 struct tcf_result res; 259 struct tcf_result res;
260 int result; 260 int result;
261 261
262 result = tc_classify(skb, q->filter_list, &res); 262 result = tc_classify(skb, fl, &res);
263 if (result >= 0) { 263 if (result >= 0) {
264#ifdef CONFIG_NET_CLS_ACT 264#ifdef CONFIG_NET_CLS_ACT
265 switch (result) { 265 switch (result) {
@@ -281,6 +281,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
281 281
282 struct sfb_sched_data *q = qdisc_priv(sch); 282 struct sfb_sched_data *q = qdisc_priv(sch);
283 struct Qdisc *child = q->qdisc; 283 struct Qdisc *child = q->qdisc;
284 struct tcf_proto *fl;
284 int i; 285 int i;
285 u32 p_min = ~0; 286 u32 p_min = ~0;
286 u32 minqlen = ~0; 287 u32 minqlen = ~0;
@@ -289,7 +290,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
289 struct flow_keys keys; 290 struct flow_keys keys;
290 291
291 if (unlikely(sch->q.qlen >= q->limit)) { 292 if (unlikely(sch->q.qlen >= q->limit)) {
292 sch->qstats.overlimits++; 293 qdisc_qstats_overlimit(sch);
293 q->stats.queuedrop++; 294 q->stats.queuedrop++;
294 goto drop; 295 goto drop;
295 } 296 }
@@ -306,9 +307,10 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
306 } 307 }
307 } 308 }
308 309
309 if (q->filter_list) { 310 fl = rcu_dereference_bh(q->filter_list);
311 if (fl) {
310 /* If using external classifiers, get result and record it. */ 312 /* If using external classifiers, get result and record it. */
311 if (!sfb_classify(skb, q, &ret, &salt)) 313 if (!sfb_classify(skb, fl, &ret, &salt))
312 goto other_drop; 314 goto other_drop;
313 keys.src = salt; 315 keys.src = salt;
314 keys.dst = 0; 316 keys.dst = 0;
@@ -346,7 +348,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
346 sfb_skb_cb(skb)->hashes[slot] = 0; 348 sfb_skb_cb(skb)->hashes[slot] = 0;
347 349
348 if (unlikely(minqlen >= q->max)) { 350 if (unlikely(minqlen >= q->max)) {
349 sch->qstats.overlimits++; 351 qdisc_qstats_overlimit(sch);
350 q->stats.bucketdrop++; 352 q->stats.bucketdrop++;
351 goto drop; 353 goto drop;
352 } 354 }
@@ -374,7 +376,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
374 } 376 }
375 } 377 }
376 if (sfb_rate_limit(skb, q)) { 378 if (sfb_rate_limit(skb, q)) {
377 sch->qstats.overlimits++; 379 qdisc_qstats_overlimit(sch);
378 q->stats.penaltydrop++; 380 q->stats.penaltydrop++;
379 goto drop; 381 goto drop;
380 } 382 }
@@ -409,7 +411,7 @@ enqueue:
409 increment_qlen(skb, q); 411 increment_qlen(skb, q);
410 } else if (net_xmit_drop_count(ret)) { 412 } else if (net_xmit_drop_count(ret)) {
411 q->stats.childdrop++; 413 q->stats.childdrop++;
412 sch->qstats.drops++; 414 qdisc_qstats_drop(sch);
413 } 415 }
414 return ret; 416 return ret;
415 417
@@ -418,7 +420,7 @@ drop:
418 return NET_XMIT_CN; 420 return NET_XMIT_CN;
419other_drop: 421other_drop:
420 if (ret & __NET_XMIT_BYPASS) 422 if (ret & __NET_XMIT_BYPASS)
421 sch->qstats.drops++; 423 qdisc_qstats_drop(sch);
422 kfree_skb(skb); 424 kfree_skb(skb);
423 return ret; 425 return ret;
424} 426}
@@ -660,7 +662,8 @@ static void sfb_walk(struct Qdisc *sch, struct qdisc_walker *walker)
660 } 662 }
661} 663}
662 664
663static struct tcf_proto **sfb_find_tcf(struct Qdisc *sch, unsigned long cl) 665static struct tcf_proto __rcu **sfb_find_tcf(struct Qdisc *sch,
666 unsigned long cl)
664{ 667{
665 struct sfb_sched_data *q = qdisc_priv(sch); 668 struct sfb_sched_data *q = qdisc_priv(sch);
666 669