1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/errno.h>
18#include <linux/skbuff.h>
19#include <net/netlink.h>
20#include <net/pkt_sched.h>
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71struct cbq_sched_data;
72
73
74struct cbq_class
75{
76 struct cbq_class *next;
77 struct cbq_class *next_alive;
78
79
80 u32 classid;
81 unsigned char priority;
82 unsigned char priority2;
83 unsigned char ewma_log;
84 unsigned char ovl_strategy;
85#ifdef CONFIG_NET_CLS_ACT
86 unsigned char police;
87#endif
88
89 u32 defmap;
90
91
92 long maxidle;
93 long offtime;
94 long minidle;
95 u32 avpkt;
96 struct qdisc_rate_table *R_tab;
97
98
99 void (*overlimit)(struct cbq_class *cl);
100 psched_tdiff_t penalty;
101
102
103 long allot;
104 long quantum;
105 long weight;
106
107 struct Qdisc *qdisc;
108 struct cbq_class *split;
109 struct cbq_class *share;
110 struct cbq_class *tparent;
111 struct cbq_class *borrow;
112
113 struct cbq_class *sibling;
114 struct cbq_class *children;
115
116 struct Qdisc *q;
117
118
119
120 unsigned char cpriority;
121 unsigned char delayed;
122 unsigned char level;
123
124
125
126
127 psched_time_t last;
128 psched_time_t undertime;
129 long avgidle;
130 long deficit;
131 psched_time_t penalized;
132 struct gnet_stats_basic bstats;
133 struct gnet_stats_queue qstats;
134 struct gnet_stats_rate_est rate_est;
135 struct tc_cbq_xstats xstats;
136
137 struct tcf_proto *filter_list;
138
139 int refcnt;
140 int filters;
141
142 struct cbq_class *defaults[TC_PRIO_MAX+1];
143};
144
145struct cbq_sched_data
146{
147 struct cbq_class *classes[16];
148 int nclasses[TC_CBQ_MAXPRIO+1];
149 unsigned quanta[TC_CBQ_MAXPRIO+1];
150
151 struct cbq_class link;
152
153 unsigned activemask;
154 struct cbq_class *active[TC_CBQ_MAXPRIO+1];
155
156
157#ifdef CONFIG_NET_CLS_ACT
158 struct cbq_class *rx_class;
159#endif
160 struct cbq_class *tx_class;
161 struct cbq_class *tx_borrowed;
162 int tx_len;
163 psched_time_t now;
164 psched_time_t now_rt;
165 unsigned pmask;
166
167 struct hrtimer delay_timer;
168 struct qdisc_watchdog watchdog;
169
170
171
172 psched_tdiff_t wd_expires;
173 int toplevel;
174 u32 hgenerator;
175};
176
177
178#define L2T(cl,len) qdisc_l2t((cl)->R_tab,len)
179
180
181static __inline__ unsigned cbq_hash(u32 h)
182{
183 h ^= h>>8;
184 h ^= h>>4;
185 return h&0xF;
186}
187
188static __inline__ struct cbq_class *
189cbq_class_lookup(struct cbq_sched_data *q, u32 classid)
190{
191 struct cbq_class *cl;
192
193 for (cl = q->classes[cbq_hash(classid)]; cl; cl = cl->next)
194 if (cl->classid == classid)
195 return cl;
196 return NULL;
197}
198
199#ifdef CONFIG_NET_CLS_ACT
200
201static struct cbq_class *
202cbq_reclassify(struct sk_buff *skb, struct cbq_class *this)
203{
204 struct cbq_class *cl, *new;
205
206 for (cl = this->tparent; cl; cl = cl->tparent)
207 if ((new = cl->defaults[TC_PRIO_BESTEFFORT]) != NULL && new != this)
208 return new;
209
210 return NULL;
211}
212
213#endif
214
215
216
217
218
219
220
221
222
223
224
225static struct cbq_class *
226cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
227{
228 struct cbq_sched_data *q = qdisc_priv(sch);
229 struct cbq_class *head = &q->link;
230 struct cbq_class **defmap;
231 struct cbq_class *cl = NULL;
232 u32 prio = skb->priority;
233 struct tcf_result res;
234
235
236
237
238 if (TC_H_MAJ(prio^sch->handle) == 0 &&
239 (cl = cbq_class_lookup(q, prio)) != NULL)
240 return cl;
241
242 *qerr = NET_XMIT_BYPASS;
243 for (;;) {
244 int result = 0;
245 defmap = head->defaults;
246
247
248
249
250 if (!head->filter_list ||
251 (result = tc_classify_compat(skb, head->filter_list, &res)) < 0)
252 goto fallback;
253
254 if ((cl = (void*)res.class) == NULL) {
255 if (TC_H_MAJ(res.classid))
256 cl = cbq_class_lookup(q, res.classid);
257 else if ((cl = defmap[res.classid&TC_PRIO_MAX]) == NULL)
258 cl = defmap[TC_PRIO_BESTEFFORT];
259
260 if (cl == NULL || cl->level >= head->level)
261 goto fallback;
262 }
263
264#ifdef CONFIG_NET_CLS_ACT
265 switch (result) {
266 case TC_ACT_QUEUED:
267 case TC_ACT_STOLEN:
268 *qerr = NET_XMIT_SUCCESS;
269 case TC_ACT_SHOT:
270 return NULL;
271 case TC_ACT_RECLASSIFY:
272 return cbq_reclassify(skb, cl);
273 }
274#endif
275 if (cl->level == 0)
276 return cl;
277
278
279
280
281
282
283 head = cl;
284 }
285
286fallback:
287 cl = head;
288
289
290
291
292 if (TC_H_MAJ(prio) == 0 &&
293 !(cl = head->defaults[prio&TC_PRIO_MAX]) &&
294 !(cl = head->defaults[TC_PRIO_BESTEFFORT]))
295 return head;
296
297 return cl;
298}
299
300
301
302
303
304
305
306static __inline__ void cbq_activate_class(struct cbq_class *cl)
307{
308 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
309 int prio = cl->cpriority;
310 struct cbq_class *cl_tail;
311
312 cl_tail = q->active[prio];
313 q->active[prio] = cl;
314
315 if (cl_tail != NULL) {
316 cl->next_alive = cl_tail->next_alive;
317 cl_tail->next_alive = cl;
318 } else {
319 cl->next_alive = cl;
320 q->activemask |= (1<<prio);
321 }
322}
323
324
325
326
327
328
329
330static void cbq_deactivate_class(struct cbq_class *this)
331{
332 struct cbq_sched_data *q = qdisc_priv(this->qdisc);
333 int prio = this->cpriority;
334 struct cbq_class *cl;
335 struct cbq_class *cl_prev = q->active[prio];
336
337 do {
338 cl = cl_prev->next_alive;
339 if (cl == this) {
340 cl_prev->next_alive = cl->next_alive;
341 cl->next_alive = NULL;
342
343 if (cl == q->active[prio]) {
344 q->active[prio] = cl_prev;
345 if (cl == q->active[prio]) {
346 q->active[prio] = NULL;
347 q->activemask &= ~(1<<prio);
348 return;
349 }
350 }
351 return;
352 }
353 } while ((cl_prev = cl) != q->active[prio]);
354}
355
356static void
357cbq_mark_toplevel(struct cbq_sched_data *q, struct cbq_class *cl)
358{
359 int toplevel = q->toplevel;
360
361 if (toplevel > cl->level && !(cl->q->flags&TCQ_F_THROTTLED)) {
362 psched_time_t now;
363 psched_tdiff_t incr;
364
365 now = psched_get_time();
366 incr = now - q->now_rt;
367 now = q->now + incr;
368
369 do {
370 if (cl->undertime < now) {
371 q->toplevel = cl->level;
372 return;
373 }
374 } while ((cl=cl->borrow) != NULL && toplevel > cl->level);
375 }
376}
377
378static int
379cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
380{
381 struct cbq_sched_data *q = qdisc_priv(sch);
382 int len = skb->len;
383 int uninitialized_var(ret);
384 struct cbq_class *cl = cbq_classify(skb, sch, &ret);
385
386#ifdef CONFIG_NET_CLS_ACT
387 q->rx_class = cl;
388#endif
389 if (cl == NULL) {
390 if (ret == NET_XMIT_BYPASS)
391 sch->qstats.drops++;
392 kfree_skb(skb);
393 return ret;
394 }
395
396#ifdef CONFIG_NET_CLS_ACT
397 cl->q->__parent = sch;
398#endif
399 if ((ret = cl->q->enqueue(skb, cl->q)) == NET_XMIT_SUCCESS) {
400 sch->q.qlen++;
401 sch->bstats.packets++;
402 sch->bstats.bytes+=len;
403 cbq_mark_toplevel(q, cl);
404 if (!cl->next_alive)
405 cbq_activate_class(cl);
406 return ret;
407 }
408
409 sch->qstats.drops++;
410 cbq_mark_toplevel(q, cl);
411 cl->qstats.drops++;
412 return ret;
413}
414
415static int
416cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
417{
418 struct cbq_sched_data *q = qdisc_priv(sch);
419 struct cbq_class *cl;
420 int ret;
421
422 if ((cl = q->tx_class) == NULL) {
423 kfree_skb(skb);
424 sch->qstats.drops++;
425 return NET_XMIT_CN;
426 }
427 q->tx_class = NULL;
428
429 cbq_mark_toplevel(q, cl);
430
431#ifdef CONFIG_NET_CLS_ACT
432 q->rx_class = cl;
433 cl->q->__parent = sch;
434#endif
435 if ((ret = cl->q->ops->requeue(skb, cl->q)) == 0) {
436 sch->q.qlen++;
437 sch->qstats.requeues++;
438 if (!cl->next_alive)
439 cbq_activate_class(cl);
440 return 0;
441 }
442 sch->qstats.drops++;
443 cl->qstats.drops++;
444 return ret;
445}
446
447
448
449
450
451static void cbq_ovl_classic(struct cbq_class *cl)
452{
453 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
454 psched_tdiff_t delay = cl->undertime - q->now;
455
456 if (!cl->delayed) {
457 delay += cl->offtime;
458
459
460
461
462
463
464
465
466 if (cl->avgidle < 0)
467 delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
468 if (cl->avgidle < cl->minidle)
469 cl->avgidle = cl->minidle;
470 if (delay <= 0)
471 delay = 1;
472 cl->undertime = q->now + delay;
473
474 cl->xstats.overactions++;
475 cl->delayed = 1;
476 }
477 if (q->wd_expires == 0 || q->wd_expires > delay)
478 q->wd_expires = delay;
479
480
481
482
483
484 if (q->toplevel == TC_CBQ_MAXLEVEL) {
485 struct cbq_class *b;
486 psched_tdiff_t base_delay = q->wd_expires;
487
488 for (b = cl->borrow; b; b = b->borrow) {
489 delay = b->undertime - q->now;
490 if (delay < base_delay) {
491 if (delay <= 0)
492 delay = 1;
493 base_delay = delay;
494 }
495 }
496
497 q->wd_expires = base_delay;
498 }
499}
500
501
502
503
504
505static void cbq_ovl_rclassic(struct cbq_class *cl)
506{
507 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
508 struct cbq_class *this = cl;
509
510 do {
511 if (cl->level > q->toplevel) {
512 cl = NULL;
513 break;
514 }
515 } while ((cl = cl->borrow) != NULL);
516
517 if (cl == NULL)
518 cl = this;
519 cbq_ovl_classic(cl);
520}
521
522
523
524static void cbq_ovl_delay(struct cbq_class *cl)
525{
526 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
527 psched_tdiff_t delay = cl->undertime - q->now;
528
529 if (!cl->delayed) {
530 psched_time_t sched = q->now;
531 ktime_t expires;
532
533 delay += cl->offtime;
534 if (cl->avgidle < 0)
535 delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
536 if (cl->avgidle < cl->minidle)
537 cl->avgidle = cl->minidle;
538 cl->undertime = q->now + delay;
539
540 if (delay > 0) {
541 sched += delay + cl->penalty;
542 cl->penalized = sched;
543 cl->cpriority = TC_CBQ_MAXPRIO;
544 q->pmask |= (1<<TC_CBQ_MAXPRIO);
545
546 expires = ktime_set(0, 0);
547 expires = ktime_add_ns(expires, PSCHED_US2NS(sched));
548 if (hrtimer_try_to_cancel(&q->delay_timer) &&
549 ktime_to_ns(ktime_sub(q->delay_timer.expires,
550 expires)) > 0)
551 q->delay_timer.expires = expires;
552 hrtimer_restart(&q->delay_timer);
553 cl->delayed = 1;
554 cl->xstats.overactions++;
555 return;
556 }
557 delay = 1;
558 }
559 if (q->wd_expires == 0 || q->wd_expires > delay)
560 q->wd_expires = delay;
561}
562
563
564
565static void cbq_ovl_lowprio(struct cbq_class *cl)
566{
567 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
568
569 cl->penalized = q->now + cl->penalty;
570
571 if (cl->cpriority != cl->priority2) {
572 cl->cpriority = cl->priority2;
573 q->pmask |= (1<<cl->cpriority);
574 cl->xstats.overactions++;
575 }
576 cbq_ovl_classic(cl);
577}
578
579
580
581static void cbq_ovl_drop(struct cbq_class *cl)
582{
583 if (cl->q->ops->drop)
584 if (cl->q->ops->drop(cl->q))
585 cl->qdisc->q.qlen--;
586 cl->xstats.overactions++;
587 cbq_ovl_classic(cl);
588}
589
590static psched_tdiff_t cbq_undelay_prio(struct cbq_sched_data *q, int prio,
591 psched_time_t now)
592{
593 struct cbq_class *cl;
594 struct cbq_class *cl_prev = q->active[prio];
595 psched_time_t sched = now;
596
597 if (cl_prev == NULL)
598 return 0;
599
600 do {
601 cl = cl_prev->next_alive;
602 if (now - cl->penalized > 0) {
603 cl_prev->next_alive = cl->next_alive;
604 cl->next_alive = NULL;
605 cl->cpriority = cl->priority;
606 cl->delayed = 0;
607 cbq_activate_class(cl);
608
609 if (cl == q->active[prio]) {
610 q->active[prio] = cl_prev;
611 if (cl == q->active[prio]) {
612 q->active[prio] = NULL;
613 return 0;
614 }
615 }
616
617 cl = cl_prev->next_alive;
618 } else if (sched - cl->penalized > 0)
619 sched = cl->penalized;
620 } while ((cl_prev = cl) != q->active[prio]);
621
622 return sched - now;
623}
624
625static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
626{
627 struct cbq_sched_data *q = container_of(timer, struct cbq_sched_data,
628 delay_timer);
629 struct Qdisc *sch = q->watchdog.qdisc;
630 psched_time_t now;
631 psched_tdiff_t delay = 0;
632 unsigned pmask;
633
634 now = psched_get_time();
635
636 pmask = q->pmask;
637 q->pmask = 0;
638
639 while (pmask) {
640 int prio = ffz(~pmask);
641 psched_tdiff_t tmp;
642
643 pmask &= ~(1<<prio);
644
645 tmp = cbq_undelay_prio(q, prio, now);
646 if (tmp > 0) {
647 q->pmask |= 1<<prio;
648 if (tmp < delay || delay == 0)
649 delay = tmp;
650 }
651 }
652
653 if (delay) {
654 ktime_t time;
655
656 time = ktime_set(0, 0);
657 time = ktime_add_ns(time, PSCHED_US2NS(now + delay));
658 hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
659 }
660
661 sch->flags &= ~TCQ_F_THROTTLED;
662 netif_schedule(sch->dev);
663 return HRTIMER_NORESTART;
664}
665
666#ifdef CONFIG_NET_CLS_ACT
667static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
668{
669 int len = skb->len;
670 struct Qdisc *sch = child->__parent;
671 struct cbq_sched_data *q = qdisc_priv(sch);
672 struct cbq_class *cl = q->rx_class;
673
674 q->rx_class = NULL;
675
676 if (cl && (cl = cbq_reclassify(skb, cl)) != NULL) {
677
678 cbq_mark_toplevel(q, cl);
679
680 q->rx_class = cl;
681 cl->q->__parent = sch;
682
683 if (cl->q->enqueue(skb, cl->q) == 0) {
684 sch->q.qlen++;
685 sch->bstats.packets++;
686 sch->bstats.bytes+=len;
687 if (!cl->next_alive)
688 cbq_activate_class(cl);
689 return 0;
690 }
691 sch->qstats.drops++;
692 return 0;
693 }
694
695 sch->qstats.drops++;
696 return -1;
697}
698#endif
699
700
701
702
703
704
705
706
707
708
709static __inline__ void
710cbq_update_toplevel(struct cbq_sched_data *q, struct cbq_class *cl,
711 struct cbq_class *borrowed)
712{
713 if (cl && q->toplevel >= borrowed->level) {
714 if (cl->q->q.qlen > 1) {
715 do {
716 if (borrowed->undertime == PSCHED_PASTPERFECT) {
717 q->toplevel = borrowed->level;
718 return;
719 }
720 } while ((borrowed=borrowed->borrow) != NULL);
721 }
722#if 0
723
724
725
726 q->toplevel = TC_CBQ_MAXLEVEL;
727#endif
728 }
729}
730
731static void
732cbq_update(struct cbq_sched_data *q)
733{
734 struct cbq_class *this = q->tx_class;
735 struct cbq_class *cl = this;
736 int len = q->tx_len;
737
738 q->tx_class = NULL;
739
740 for ( ; cl; cl = cl->share) {
741 long avgidle = cl->avgidle;
742 long idle;
743
744 cl->bstats.packets++;
745 cl->bstats.bytes += len;
746
747
748
749
750
751
752
753
754 idle = q->now - cl->last;
755 if ((unsigned long)idle > 128*1024*1024) {
756 avgidle = cl->maxidle;
757 } else {
758 idle -= L2T(cl, len);
759
760
761
762
763
764
765 avgidle += idle - (avgidle>>cl->ewma_log);
766 }
767
768 if (avgidle <= 0) {
769
770
771 if (avgidle < cl->minidle)
772 avgidle = cl->minidle;
773
774 cl->avgidle = avgidle;
775
776
777
778
779
780
781
782
783
784 idle = (-avgidle) - ((-avgidle) >> cl->ewma_log);
785
786
787
788
789
790
791
792
793
794
795 idle -= L2T(&q->link, len);
796 idle += L2T(cl, len);
797
798 cl->undertime = q->now + idle;
799 } else {
800
801
802 cl->undertime = PSCHED_PASTPERFECT;
803 if (avgidle > cl->maxidle)
804 cl->avgidle = cl->maxidle;
805 else
806 cl->avgidle = avgidle;
807 }
808 cl->last = q->now;
809 }
810
811 cbq_update_toplevel(q, this, q->tx_borrowed);
812}
813
814static __inline__ struct cbq_class *
815cbq_under_limit(struct cbq_class *cl)
816{
817 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
818 struct cbq_class *this_cl = cl;
819
820 if (cl->tparent == NULL)
821 return cl;
822
823 if (cl->undertime == PSCHED_PASTPERFECT || q->now >= cl->undertime) {
824 cl->delayed = 0;
825 return cl;
826 }
827
828 do {
829
830
831
832
833
834
835
836
837
838
839 if ((cl = cl->borrow) == NULL) {
840 this_cl->qstats.overlimits++;
841 this_cl->overlimit(this_cl);
842 return NULL;
843 }
844 if (cl->level > q->toplevel)
845 return NULL;
846 } while (cl->undertime != PSCHED_PASTPERFECT && q->now < cl->undertime);
847
848 cl->delayed = 0;
849 return cl;
850}
851
852static __inline__ struct sk_buff *
853cbq_dequeue_prio(struct Qdisc *sch, int prio)
854{
855 struct cbq_sched_data *q = qdisc_priv(sch);
856 struct cbq_class *cl_tail, *cl_prev, *cl;
857 struct sk_buff *skb;
858 int deficit;
859
860 cl_tail = cl_prev = q->active[prio];
861 cl = cl_prev->next_alive;
862
863 do {
864 deficit = 0;
865
866
867 do {
868 struct cbq_class *borrow = cl;
869
870 if (cl->q->q.qlen &&
871 (borrow = cbq_under_limit(cl)) == NULL)
872 goto skip_class;
873
874 if (cl->deficit <= 0) {
875
876
877
878 deficit = 1;
879 cl->deficit += cl->quantum;
880 goto next_class;
881 }
882
883 skb = cl->q->dequeue(cl->q);
884
885
886
887
888
889 if (skb == NULL)
890 goto skip_class;
891
892 cl->deficit -= skb->len;
893 q->tx_class = cl;
894 q->tx_borrowed = borrow;
895 if (borrow != cl) {
896#ifndef CBQ_XSTATS_BORROWS_BYTES
897 borrow->xstats.borrows++;
898 cl->xstats.borrows++;
899#else
900 borrow->xstats.borrows += skb->len;
901 cl->xstats.borrows += skb->len;
902#endif
903 }
904 q->tx_len = skb->len;
905
906 if (cl->deficit <= 0) {
907 q->active[prio] = cl;
908 cl = cl->next_alive;
909 cl->deficit += cl->quantum;
910 }
911 return skb;
912
913skip_class:
914 if (cl->q->q.qlen == 0 || prio != cl->cpriority) {
915
916
917
918 cl_prev->next_alive = cl->next_alive;
919 cl->next_alive = NULL;
920
921
922 if (cl == cl_tail) {
923
924 cl_tail = cl_prev;
925
926
927 if (cl == cl_tail) {
928
929 q->active[prio] = NULL;
930 q->activemask &= ~(1<<prio);
931 if (cl->q->q.qlen)
932 cbq_activate_class(cl);
933 return NULL;
934 }
935
936 q->active[prio] = cl_tail;
937 }
938 if (cl->q->q.qlen)
939 cbq_activate_class(cl);
940
941 cl = cl_prev;
942 }
943
944next_class:
945 cl_prev = cl;
946 cl = cl->next_alive;
947 } while (cl_prev != cl_tail);
948 } while (deficit);
949
950 q->active[prio] = cl_prev;
951
952 return NULL;
953}
954
955static __inline__ struct sk_buff *
956cbq_dequeue_1(struct Qdisc *sch)
957{
958 struct cbq_sched_data *q = qdisc_priv(sch);
959 struct sk_buff *skb;
960 unsigned activemask;
961
962 activemask = q->activemask&0xFF;
963 while (activemask) {
964 int prio = ffz(~activemask);
965 activemask &= ~(1<<prio);
966 skb = cbq_dequeue_prio(sch, prio);
967 if (skb)
968 return skb;
969 }
970 return NULL;
971}
972
973static struct sk_buff *
974cbq_dequeue(struct Qdisc *sch)
975{
976 struct sk_buff *skb;
977 struct cbq_sched_data *q = qdisc_priv(sch);
978 psched_time_t now;
979 psched_tdiff_t incr;
980
981 now = psched_get_time();
982 incr = now - q->now_rt;
983
984 if (q->tx_class) {
985 psched_tdiff_t incr2;
986
987
988
989
990
991
992
993 incr2 = L2T(&q->link, q->tx_len);
994 q->now += incr2;
995 cbq_update(q);
996 if ((incr -= incr2) < 0)
997 incr = 0;
998 }
999 q->now += incr;
1000 q->now_rt = now;
1001
1002 for (;;) {
1003 q->wd_expires = 0;
1004
1005 skb = cbq_dequeue_1(sch);
1006 if (skb) {
1007 sch->q.qlen--;
1008 sch->flags &= ~TCQ_F_THROTTLED;
1009 return skb;
1010 }
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030 if (q->toplevel == TC_CBQ_MAXLEVEL &&
1031 q->link.undertime == PSCHED_PASTPERFECT)
1032 break;
1033
1034 q->toplevel = TC_CBQ_MAXLEVEL;
1035 q->link.undertime = PSCHED_PASTPERFECT;
1036 }
1037
1038
1039
1040
1041 if (sch->q.qlen) {
1042 sch->qstats.overlimits++;
1043 if (q->wd_expires)
1044 qdisc_watchdog_schedule(&q->watchdog,
1045 now + q->wd_expires);
1046 }
1047 return NULL;
1048}
1049
1050
1051
1052static void cbq_adjust_levels(struct cbq_class *this)
1053{
1054 if (this == NULL)
1055 return;
1056
1057 do {
1058 int level = 0;
1059 struct cbq_class *cl;
1060
1061 if ((cl = this->children) != NULL) {
1062 do {
1063 if (cl->level > level)
1064 level = cl->level;
1065 } while ((cl = cl->sibling) != this->children);
1066 }
1067 this->level = level+1;
1068 } while ((this = this->tparent) != NULL);
1069}
1070
1071static void cbq_normalize_quanta(struct cbq_sched_data *q, int prio)
1072{
1073 struct cbq_class *cl;
1074 unsigned h;
1075
1076 if (q->quanta[prio] == 0)
1077 return;
1078
1079 for (h=0; h<16; h++) {
1080 for (cl = q->classes[h]; cl; cl = cl->next) {
1081
1082
1083
1084 if (cl->priority == prio) {
1085 cl->quantum = (cl->weight*cl->allot*q->nclasses[prio])/
1086 q->quanta[prio];
1087 }
1088 if (cl->quantum <= 0 || cl->quantum>32*cl->qdisc->dev->mtu) {
1089 printk(KERN_WARNING "CBQ: class %08x has bad quantum==%ld, repaired.\n", cl->classid, cl->quantum);
1090 cl->quantum = cl->qdisc->dev->mtu/2 + 1;
1091 }
1092 }
1093 }
1094}
1095
1096static void cbq_sync_defmap(struct cbq_class *cl)
1097{
1098 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
1099 struct cbq_class *split = cl->split;
1100 unsigned h;
1101 int i;
1102
1103 if (split == NULL)
1104 return;
1105
1106 for (i=0; i<=TC_PRIO_MAX; i++) {
1107 if (split->defaults[i] == cl && !(cl->defmap&(1<<i)))
1108 split->defaults[i] = NULL;
1109 }
1110
1111 for (i=0; i<=TC_PRIO_MAX; i++) {
1112 int level = split->level;
1113
1114 if (split->defaults[i])
1115 continue;
1116
1117 for (h=0; h<16; h++) {
1118 struct cbq_class *c;
1119
1120 for (c = q->classes[h]; c; c = c->next) {
1121 if (c->split == split && c->level < level &&
1122 c->defmap&(1<<i)) {
1123 split->defaults[i] = c;
1124 level = c->level;
1125 }
1126 }
1127 }
1128 }
1129}
1130
1131static void cbq_change_defmap(struct cbq_class *cl, u32 splitid, u32 def, u32 mask)
1132{
1133 struct cbq_class *split = NULL;
1134
1135 if (splitid == 0) {
1136 if ((split = cl->split) == NULL)
1137 return;
1138 splitid = split->classid;
1139 }
1140
1141 if (split == NULL || split->classid != splitid) {
1142 for (split = cl->tparent; split; split = split->tparent)
1143 if (split->classid == splitid)
1144 break;
1145 }
1146
1147 if (split == NULL)
1148 return;
1149
1150 if (cl->split != split) {
1151 cl->defmap = 0;
1152 cbq_sync_defmap(cl);
1153 cl->split = split;
1154 cl->defmap = def&mask;
1155 } else
1156 cl->defmap = (cl->defmap&~mask)|(def&mask);
1157
1158 cbq_sync_defmap(cl);
1159}
1160
1161static void cbq_unlink_class(struct cbq_class *this)
1162{
1163 struct cbq_class *cl, **clp;
1164 struct cbq_sched_data *q = qdisc_priv(this->qdisc);
1165
1166 for (clp = &q->classes[cbq_hash(this->classid)]; (cl = *clp) != NULL; clp = &cl->next) {
1167 if (cl == this) {
1168 *clp = cl->next;
1169 cl->next = NULL;
1170 break;
1171 }
1172 }
1173
1174 if (this->tparent) {
1175 clp=&this->sibling;
1176 cl = *clp;
1177 do {
1178 if (cl == this) {
1179 *clp = cl->sibling;
1180 break;
1181 }
1182 clp = &cl->sibling;
1183 } while ((cl = *clp) != this->sibling);
1184
1185 if (this->tparent->children == this) {
1186 this->tparent->children = this->sibling;
1187 if (this->sibling == this)
1188 this->tparent->children = NULL;
1189 }
1190 } else {
1191 BUG_TRAP(this->sibling == this);
1192 }
1193}
1194
1195static void cbq_link_class(struct cbq_class *this)
1196{
1197 struct cbq_sched_data *q = qdisc_priv(this->qdisc);
1198 unsigned h = cbq_hash(this->classid);
1199 struct cbq_class *parent = this->tparent;
1200
1201 this->sibling = this;
1202 this->next = q->classes[h];
1203 q->classes[h] = this;
1204
1205 if (parent == NULL)
1206 return;
1207
1208 if (parent->children == NULL) {
1209 parent->children = this;
1210 } else {
1211 this->sibling = parent->children->sibling;
1212 parent->children->sibling = this;
1213 }
1214}
1215
1216static unsigned int cbq_drop(struct Qdisc* sch)
1217{
1218 struct cbq_sched_data *q = qdisc_priv(sch);
1219 struct cbq_class *cl, *cl_head;
1220 int prio;
1221 unsigned int len;
1222
1223 for (prio = TC_CBQ_MAXPRIO; prio >= 0; prio--) {
1224 if ((cl_head = q->active[prio]) == NULL)
1225 continue;
1226
1227 cl = cl_head;
1228 do {
1229 if (cl->q->ops->drop && (len = cl->q->ops->drop(cl->q))) {
1230 sch->q.qlen--;
1231 if (!cl->q->q.qlen)
1232 cbq_deactivate_class(cl);
1233 return len;
1234 }
1235 } while ((cl = cl->next_alive) != cl_head);
1236 }
1237 return 0;
1238}
1239
1240static void
1241cbq_reset(struct Qdisc* sch)
1242{
1243 struct cbq_sched_data *q = qdisc_priv(sch);
1244 struct cbq_class *cl;
1245 int prio;
1246 unsigned h;
1247
1248 q->activemask = 0;
1249 q->pmask = 0;
1250 q->tx_class = NULL;
1251 q->tx_borrowed = NULL;
1252 qdisc_watchdog_cancel(&q->watchdog);
1253 hrtimer_cancel(&q->delay_timer);
1254 q->toplevel = TC_CBQ_MAXLEVEL;
1255 q->now = psched_get_time();
1256 q->now_rt = q->now;
1257
1258 for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++)
1259 q->active[prio] = NULL;
1260
1261 for (h = 0; h < 16; h++) {
1262 for (cl = q->classes[h]; cl; cl = cl->next) {
1263 qdisc_reset(cl->q);
1264
1265 cl->next_alive = NULL;
1266 cl->undertime = PSCHED_PASTPERFECT;
1267 cl->avgidle = cl->maxidle;
1268 cl->deficit = cl->quantum;
1269 cl->cpriority = cl->priority;
1270 }
1271 }
1272 sch->q.qlen = 0;
1273}
1274
1275
1276static int cbq_set_lss(struct cbq_class *cl, struct tc_cbq_lssopt *lss)
1277{
1278 if (lss->change&TCF_CBQ_LSS_FLAGS) {
1279 cl->share = (lss->flags&TCF_CBQ_LSS_ISOLATED) ? NULL : cl->tparent;
1280 cl->borrow = (lss->flags&TCF_CBQ_LSS_BOUNDED) ? NULL : cl->tparent;
1281 }
1282 if (lss->change&TCF_CBQ_LSS_EWMA)
1283 cl->ewma_log = lss->ewma_log;
1284 if (lss->change&TCF_CBQ_LSS_AVPKT)
1285 cl->avpkt = lss->avpkt;
1286 if (lss->change&TCF_CBQ_LSS_MINIDLE)
1287 cl->minidle = -(long)lss->minidle;
1288 if (lss->change&TCF_CBQ_LSS_MAXIDLE) {
1289 cl->maxidle = lss->maxidle;
1290 cl->avgidle = lss->maxidle;
1291 }
1292 if (lss->change&TCF_CBQ_LSS_OFFTIME)
1293 cl->offtime = lss->offtime;
1294 return 0;
1295}
1296
1297static void cbq_rmprio(struct cbq_sched_data *q, struct cbq_class *cl)
1298{
1299 q->nclasses[cl->priority]--;
1300 q->quanta[cl->priority] -= cl->weight;
1301 cbq_normalize_quanta(q, cl->priority);
1302}
1303
1304static void cbq_addprio(struct cbq_sched_data *q, struct cbq_class *cl)
1305{
1306 q->nclasses[cl->priority]++;
1307 q->quanta[cl->priority] += cl->weight;
1308 cbq_normalize_quanta(q, cl->priority);
1309}
1310
1311static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr)
1312{
1313 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
1314
1315 if (wrr->allot)
1316 cl->allot = wrr->allot;
1317 if (wrr->weight)
1318 cl->weight = wrr->weight;
1319 if (wrr->priority) {
1320 cl->priority = wrr->priority-1;
1321 cl->cpriority = cl->priority;
1322 if (cl->priority >= cl->priority2)
1323 cl->priority2 = TC_CBQ_MAXPRIO-1;
1324 }
1325
1326 cbq_addprio(q, cl);
1327 return 0;
1328}
1329
1330static int cbq_set_overlimit(struct cbq_class *cl, struct tc_cbq_ovl *ovl)
1331{
1332 switch (ovl->strategy) {
1333 case TC_CBQ_OVL_CLASSIC:
1334 cl->overlimit = cbq_ovl_classic;
1335 break;
1336 case TC_CBQ_OVL_DELAY:
1337 cl->overlimit = cbq_ovl_delay;
1338 break;
1339 case TC_CBQ_OVL_LOWPRIO:
1340 if (ovl->priority2-1 >= TC_CBQ_MAXPRIO ||
1341 ovl->priority2-1 <= cl->priority)
1342 return -EINVAL;
1343 cl->priority2 = ovl->priority2-1;
1344 cl->overlimit = cbq_ovl_lowprio;
1345 break;
1346 case TC_CBQ_OVL_DROP:
1347 cl->overlimit = cbq_ovl_drop;
1348 break;
1349 case TC_CBQ_OVL_RCLASSIC:
1350 cl->overlimit = cbq_ovl_rclassic;
1351 break;
1352 default:
1353 return -EINVAL;
1354 }
1355 cl->penalty = ovl->penalty;
1356 return 0;
1357}
1358
1359#ifdef CONFIG_NET_CLS_ACT
1360static int cbq_set_police(struct cbq_class *cl, struct tc_cbq_police *p)
1361{
1362 cl->police = p->police;
1363
1364 if (cl->q->handle) {
1365 if (p->police == TC_POLICE_RECLASSIFY)
1366 cl->q->reshape_fail = cbq_reshape_fail;
1367 else
1368 cl->q->reshape_fail = NULL;
1369 }
1370 return 0;
1371}
1372#endif
1373
1374static int cbq_set_fopt(struct cbq_class *cl, struct tc_cbq_fopt *fopt)
1375{
1376 cbq_change_defmap(cl, fopt->split, fopt->defmap, fopt->defchange);
1377 return 0;
1378}
1379
1380static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
1381 [TCA_CBQ_LSSOPT] = { .len = sizeof(struct tc_cbq_lssopt) },
1382 [TCA_CBQ_WRROPT] = { .len = sizeof(struct tc_cbq_wrropt) },
1383 [TCA_CBQ_FOPT] = { .len = sizeof(struct tc_cbq_fopt) },
1384 [TCA_CBQ_OVL_STRATEGY] = { .len = sizeof(struct tc_cbq_ovl) },
1385 [TCA_CBQ_RATE] = { .len = sizeof(struct tc_ratespec) },
1386 [TCA_CBQ_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
1387 [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) },
1388};
1389
1390static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
1391{
1392 struct cbq_sched_data *q = qdisc_priv(sch);
1393 struct nlattr *tb[TCA_CBQ_MAX + 1];
1394 struct tc_ratespec *r;
1395 int err;
1396
1397 err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
1398 if (err < 0)
1399 return err;
1400
1401 if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL)
1402 return -EINVAL;
1403
1404 r = nla_data(tb[TCA_CBQ_RATE]);
1405
1406 if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB])) == NULL)
1407 return -EINVAL;
1408
1409 q->link.refcnt = 1;
1410 q->link.sibling = &q->link;
1411 q->link.classid = sch->handle;
1412 q->link.qdisc = sch;
1413 if (!(q->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1414 sch->handle)))
1415 q->link.q = &noop_qdisc;
1416
1417 q->link.priority = TC_CBQ_MAXPRIO-1;
1418 q->link.priority2 = TC_CBQ_MAXPRIO-1;
1419 q->link.cpriority = TC_CBQ_MAXPRIO-1;
1420 q->link.ovl_strategy = TC_CBQ_OVL_CLASSIC;
1421 q->link.overlimit = cbq_ovl_classic;
1422 q->link.allot = psched_mtu(sch->dev);
1423 q->link.quantum = q->link.allot;
1424 q->link.weight = q->link.R_tab->rate.rate;
1425
1426 q->link.ewma_log = TC_CBQ_DEF_EWMA;
1427 q->link.avpkt = q->link.allot/2;
1428 q->link.minidle = -0x7FFFFFFF;
1429
1430 qdisc_watchdog_init(&q->watchdog, sch);
1431 hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1432 q->delay_timer.function = cbq_undelay;
1433 q->toplevel = TC_CBQ_MAXLEVEL;
1434 q->now = psched_get_time();
1435 q->now_rt = q->now;
1436
1437 cbq_link_class(&q->link);
1438
1439 if (tb[TCA_CBQ_LSSOPT])
1440 cbq_set_lss(&q->link, nla_data(tb[TCA_CBQ_LSSOPT]));
1441
1442 cbq_addprio(q, &q->link);
1443 return 0;
1444}
1445
1446static __inline__ int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl)
1447{
1448 unsigned char *b = skb_tail_pointer(skb);
1449
1450 NLA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
1451 return skb->len;
1452
1453nla_put_failure:
1454 nlmsg_trim(skb, b);
1455 return -1;
1456}
1457
1458static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
1459{
1460 unsigned char *b = skb_tail_pointer(skb);
1461 struct tc_cbq_lssopt opt;
1462
1463 opt.flags = 0;
1464 if (cl->borrow == NULL)
1465 opt.flags |= TCF_CBQ_LSS_BOUNDED;
1466 if (cl->share == NULL)
1467 opt.flags |= TCF_CBQ_LSS_ISOLATED;
1468 opt.ewma_log = cl->ewma_log;
1469 opt.level = cl->level;
1470 opt.avpkt = cl->avpkt;
1471 opt.maxidle = cl->maxidle;
1472 opt.minidle = (u32)(-cl->minidle);
1473 opt.offtime = cl->offtime;
1474 opt.change = ~0;
1475 NLA_PUT(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt);
1476 return skb->len;
1477
1478nla_put_failure:
1479 nlmsg_trim(skb, b);
1480 return -1;
1481}
1482
1483static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
1484{
1485 unsigned char *b = skb_tail_pointer(skb);
1486 struct tc_cbq_wrropt opt;
1487
1488 opt.flags = 0;
1489 opt.allot = cl->allot;
1490 opt.priority = cl->priority+1;
1491 opt.cpriority = cl->cpriority+1;
1492 opt.weight = cl->weight;
1493 NLA_PUT(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt);
1494 return skb->len;
1495
1496nla_put_failure:
1497 nlmsg_trim(skb, b);
1498 return -1;
1499}
1500
1501static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
1502{
1503 unsigned char *b = skb_tail_pointer(skb);
1504 struct tc_cbq_ovl opt;
1505
1506 opt.strategy = cl->ovl_strategy;
1507 opt.priority2 = cl->priority2+1;
1508 opt.pad = 0;
1509 opt.penalty = cl->penalty;
1510 NLA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
1511 return skb->len;
1512
1513nla_put_failure:
1514 nlmsg_trim(skb, b);
1515 return -1;
1516}
1517
1518static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
1519{
1520 unsigned char *b = skb_tail_pointer(skb);
1521 struct tc_cbq_fopt opt;
1522
1523 if (cl->split || cl->defmap) {
1524 opt.split = cl->split ? cl->split->classid : 0;
1525 opt.defmap = cl->defmap;
1526 opt.defchange = ~0;
1527 NLA_PUT(skb, TCA_CBQ_FOPT, sizeof(opt), &opt);
1528 }
1529 return skb->len;
1530
1531nla_put_failure:
1532 nlmsg_trim(skb, b);
1533 return -1;
1534}
1535
1536#ifdef CONFIG_NET_CLS_ACT
1537static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
1538{
1539 unsigned char *b = skb_tail_pointer(skb);
1540 struct tc_cbq_police opt;
1541
1542 if (cl->police) {
1543 opt.police = cl->police;
1544 opt.__res1 = 0;
1545 opt.__res2 = 0;
1546 NLA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
1547 }
1548 return skb->len;
1549
1550nla_put_failure:
1551 nlmsg_trim(skb, b);
1552 return -1;
1553}
1554#endif
1555
1556static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
1557{
1558 if (cbq_dump_lss(skb, cl) < 0 ||
1559 cbq_dump_rate(skb, cl) < 0 ||
1560 cbq_dump_wrr(skb, cl) < 0 ||
1561 cbq_dump_ovl(skb, cl) < 0 ||
1562#ifdef CONFIG_NET_CLS_ACT
1563 cbq_dump_police(skb, cl) < 0 ||
1564#endif
1565 cbq_dump_fopt(skb, cl) < 0)
1566 return -1;
1567 return 0;
1568}
1569
1570static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
1571{
1572 struct cbq_sched_data *q = qdisc_priv(sch);
1573 struct nlattr *nest;
1574
1575 nest = nla_nest_start(skb, TCA_OPTIONS);
1576 if (nest == NULL)
1577 goto nla_put_failure;
1578 if (cbq_dump_attr(skb, &q->link) < 0)
1579 goto nla_put_failure;
1580 nla_nest_end(skb, nest);
1581 return skb->len;
1582
1583nla_put_failure:
1584 nla_nest_cancel(skb, nest);
1585 return -1;
1586}
1587
1588static int
1589cbq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
1590{
1591 struct cbq_sched_data *q = qdisc_priv(sch);
1592
1593 q->link.xstats.avgidle = q->link.avgidle;
1594 return gnet_stats_copy_app(d, &q->link.xstats, sizeof(q->link.xstats));
1595}
1596
1597static int
1598cbq_dump_class(struct Qdisc *sch, unsigned long arg,
1599 struct sk_buff *skb, struct tcmsg *tcm)
1600{
1601 struct cbq_class *cl = (struct cbq_class*)arg;
1602 struct nlattr *nest;
1603
1604 if (cl->tparent)
1605 tcm->tcm_parent = cl->tparent->classid;
1606 else
1607 tcm->tcm_parent = TC_H_ROOT;
1608 tcm->tcm_handle = cl->classid;
1609 tcm->tcm_info = cl->q->handle;
1610
1611 nest = nla_nest_start(skb, TCA_OPTIONS);
1612 if (nest == NULL)
1613 goto nla_put_failure;
1614 if (cbq_dump_attr(skb, cl) < 0)
1615 goto nla_put_failure;
1616 nla_nest_end(skb, nest);
1617 return skb->len;
1618
1619nla_put_failure:
1620 nla_nest_cancel(skb, nest);
1621 return -1;
1622}
1623
1624static int
1625cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
1626 struct gnet_dump *d)
1627{
1628 struct cbq_sched_data *q = qdisc_priv(sch);
1629 struct cbq_class *cl = (struct cbq_class*)arg;
1630
1631 cl->qstats.qlen = cl->q->q.qlen;
1632 cl->xstats.avgidle = cl->avgidle;
1633 cl->xstats.undertime = 0;
1634
1635 if (cl->undertime != PSCHED_PASTPERFECT)
1636 cl->xstats.undertime = cl->undertime - q->now;
1637
1638 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
1639 gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
1640 gnet_stats_copy_queue(d, &cl->qstats) < 0)
1641 return -1;
1642
1643 return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
1644}
1645
1646static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1647 struct Qdisc **old)
1648{
1649 struct cbq_class *cl = (struct cbq_class*)arg;
1650
1651 if (cl) {
1652 if (new == NULL) {
1653 if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1654 cl->classid)) == NULL)
1655 return -ENOBUFS;
1656 } else {
1657#ifdef CONFIG_NET_CLS_ACT
1658 if (cl->police == TC_POLICE_RECLASSIFY)
1659 new->reshape_fail = cbq_reshape_fail;
1660#endif
1661 }
1662 sch_tree_lock(sch);
1663 *old = xchg(&cl->q, new);
1664 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1665 qdisc_reset(*old);
1666 sch_tree_unlock(sch);
1667
1668 return 0;
1669 }
1670 return -ENOENT;
1671}
1672
1673static struct Qdisc *
1674cbq_leaf(struct Qdisc *sch, unsigned long arg)
1675{
1676 struct cbq_class *cl = (struct cbq_class*)arg;
1677
1678 return cl ? cl->q : NULL;
1679}
1680
1681static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg)
1682{
1683 struct cbq_class *cl = (struct cbq_class *)arg;
1684
1685 if (cl->q->q.qlen == 0)
1686 cbq_deactivate_class(cl);
1687}
1688
1689static unsigned long cbq_get(struct Qdisc *sch, u32 classid)
1690{
1691 struct cbq_sched_data *q = qdisc_priv(sch);
1692 struct cbq_class *cl = cbq_class_lookup(q, classid);
1693
1694 if (cl) {
1695 cl->refcnt++;
1696 return (unsigned long)cl;
1697 }
1698 return 0;
1699}
1700
1701static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
1702{
1703 struct cbq_sched_data *q = qdisc_priv(sch);
1704
1705 BUG_TRAP(!cl->filters);
1706
1707 tcf_destroy_chain(cl->filter_list);
1708 qdisc_destroy(cl->q);
1709 qdisc_put_rtab(cl->R_tab);
1710 gen_kill_estimator(&cl->bstats, &cl->rate_est);
1711 if (cl != &q->link)
1712 kfree(cl);
1713}
1714
1715static void
1716cbq_destroy(struct Qdisc* sch)
1717{
1718 struct cbq_sched_data *q = qdisc_priv(sch);
1719 struct cbq_class *cl;
1720 unsigned h;
1721
1722#ifdef CONFIG_NET_CLS_ACT
1723 q->rx_class = NULL;
1724#endif
1725
1726
1727
1728
1729
1730 for (h = 0; h < 16; h++) {
1731 for (cl = q->classes[h]; cl; cl = cl->next) {
1732 tcf_destroy_chain(cl->filter_list);
1733 cl->filter_list = NULL;
1734 }
1735 }
1736 for (h = 0; h < 16; h++) {
1737 struct cbq_class *next;
1738
1739 for (cl = q->classes[h]; cl; cl = next) {
1740 next = cl->next;
1741 cbq_destroy_class(sch, cl);
1742 }
1743 }
1744}
1745
1746static void cbq_put(struct Qdisc *sch, unsigned long arg)
1747{
1748 struct cbq_class *cl = (struct cbq_class*)arg;
1749
1750 if (--cl->refcnt == 0) {
1751#ifdef CONFIG_NET_CLS_ACT
1752 struct cbq_sched_data *q = qdisc_priv(sch);
1753
1754 spin_lock_bh(&sch->dev->queue_lock);
1755 if (q->rx_class == cl)
1756 q->rx_class = NULL;
1757 spin_unlock_bh(&sch->dev->queue_lock);
1758#endif
1759
1760 cbq_destroy_class(sch, cl);
1761 }
1762}
1763
1764static int
1765cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca,
1766 unsigned long *arg)
1767{
1768 int err;
1769 struct cbq_sched_data *q = qdisc_priv(sch);
1770 struct cbq_class *cl = (struct cbq_class*)*arg;
1771 struct nlattr *opt = tca[TCA_OPTIONS];
1772 struct nlattr *tb[TCA_CBQ_MAX + 1];
1773 struct cbq_class *parent;
1774 struct qdisc_rate_table *rtab = NULL;
1775
1776 if (opt == NULL)
1777 return -EINVAL;
1778
1779 err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
1780 if (err < 0)
1781 return err;
1782
1783 if (cl) {
1784
1785 if (parentid) {
1786 if (cl->tparent && cl->tparent->classid != parentid)
1787 return -EINVAL;
1788 if (!cl->tparent && parentid != TC_H_ROOT)
1789 return -EINVAL;
1790 }
1791
1792 if (tb[TCA_CBQ_RATE]) {
1793 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
1794 if (rtab == NULL)
1795 return -EINVAL;
1796 }
1797
1798
1799 sch_tree_lock(sch);
1800
1801 if (cl->next_alive != NULL)
1802 cbq_deactivate_class(cl);
1803
1804 if (rtab) {
1805 rtab = xchg(&cl->R_tab, rtab);
1806 qdisc_put_rtab(rtab);
1807 }
1808
1809 if (tb[TCA_CBQ_LSSOPT])
1810 cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
1811
1812 if (tb[TCA_CBQ_WRROPT]) {
1813 cbq_rmprio(q, cl);
1814 cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
1815 }
1816
1817 if (tb[TCA_CBQ_OVL_STRATEGY])
1818 cbq_set_overlimit(cl, nla_data(tb[TCA_CBQ_OVL_STRATEGY]));
1819
1820#ifdef CONFIG_NET_CLS_ACT
1821 if (tb[TCA_CBQ_POLICE])
1822 cbq_set_police(cl, nla_data(tb[TCA_CBQ_POLICE]));
1823#endif
1824
1825 if (tb[TCA_CBQ_FOPT])
1826 cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
1827
1828 if (cl->q->q.qlen)
1829 cbq_activate_class(cl);
1830
1831 sch_tree_unlock(sch);
1832
1833 if (tca[TCA_RATE])
1834 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1835 &sch->dev->queue_lock,
1836 tca[TCA_RATE]);
1837 return 0;
1838 }
1839
1840 if (parentid == TC_H_ROOT)
1841 return -EINVAL;
1842
1843 if (tb[TCA_CBQ_WRROPT] == NULL || tb[TCA_CBQ_RATE] == NULL ||
1844 tb[TCA_CBQ_LSSOPT] == NULL)
1845 return -EINVAL;
1846
1847 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
1848 if (rtab == NULL)
1849 return -EINVAL;
1850
1851 if (classid) {
1852 err = -EINVAL;
1853 if (TC_H_MAJ(classid^sch->handle) || cbq_class_lookup(q, classid))
1854 goto failure;
1855 } else {
1856 int i;
1857 classid = TC_H_MAKE(sch->handle,0x8000);
1858
1859 for (i=0; i<0x8000; i++) {
1860 if (++q->hgenerator >= 0x8000)
1861 q->hgenerator = 1;
1862 if (cbq_class_lookup(q, classid|q->hgenerator) == NULL)
1863 break;
1864 }
1865 err = -ENOSR;
1866 if (i >= 0x8000)
1867 goto failure;
1868 classid = classid|q->hgenerator;
1869 }
1870
1871 parent = &q->link;
1872 if (parentid) {
1873 parent = cbq_class_lookup(q, parentid);
1874 err = -EINVAL;
1875 if (parent == NULL)
1876 goto failure;
1877 }
1878
1879 err = -ENOBUFS;
1880 cl = kzalloc(sizeof(*cl), GFP_KERNEL);
1881 if (cl == NULL)
1882 goto failure;
1883 cl->R_tab = rtab;
1884 rtab = NULL;
1885 cl->refcnt = 1;
1886 if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid)))
1887 cl->q = &noop_qdisc;
1888 cl->classid = classid;
1889 cl->tparent = parent;
1890 cl->qdisc = sch;
1891 cl->allot = parent->allot;
1892 cl->quantum = cl->allot;
1893 cl->weight = cl->R_tab->rate.rate;
1894
1895 sch_tree_lock(sch);
1896 cbq_link_class(cl);
1897 cl->borrow = cl->tparent;
1898 if (cl->tparent != &q->link)
1899 cl->share = cl->tparent;
1900 cbq_adjust_levels(parent);
1901 cl->minidle = -0x7FFFFFFF;
1902 cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
1903 cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
1904 if (cl->ewma_log==0)
1905 cl->ewma_log = q->link.ewma_log;
1906 if (cl->maxidle==0)
1907 cl->maxidle = q->link.maxidle;
1908 if (cl->avpkt==0)
1909 cl->avpkt = q->link.avpkt;
1910 cl->overlimit = cbq_ovl_classic;
1911 if (tb[TCA_CBQ_OVL_STRATEGY])
1912 cbq_set_overlimit(cl, nla_data(tb[TCA_CBQ_OVL_STRATEGY]));
1913#ifdef CONFIG_NET_CLS_ACT
1914 if (tb[TCA_CBQ_POLICE])
1915 cbq_set_police(cl, nla_data(tb[TCA_CBQ_POLICE]));
1916#endif
1917 if (tb[TCA_CBQ_FOPT])
1918 cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
1919 sch_tree_unlock(sch);
1920
1921 if (tca[TCA_RATE])
1922 gen_new_estimator(&cl->bstats, &cl->rate_est,
1923 &sch->dev->queue_lock, tca[TCA_RATE]);
1924
1925 *arg = (unsigned long)cl;
1926 return 0;
1927
1928failure:
1929 qdisc_put_rtab(rtab);
1930 return err;
1931}
1932
1933static int cbq_delete(struct Qdisc *sch, unsigned long arg)
1934{
1935 struct cbq_sched_data *q = qdisc_priv(sch);
1936 struct cbq_class *cl = (struct cbq_class*)arg;
1937 unsigned int qlen;
1938
1939 if (cl->filters || cl->children || cl == &q->link)
1940 return -EBUSY;
1941
1942 sch_tree_lock(sch);
1943
1944 qlen = cl->q->q.qlen;
1945 qdisc_reset(cl->q);
1946 qdisc_tree_decrease_qlen(cl->q, qlen);
1947
1948 if (cl->next_alive)
1949 cbq_deactivate_class(cl);
1950
1951 if (q->tx_borrowed == cl)
1952 q->tx_borrowed = q->tx_class;
1953 if (q->tx_class == cl) {
1954 q->tx_class = NULL;
1955 q->tx_borrowed = NULL;
1956 }
1957#ifdef CONFIG_NET_CLS_ACT
1958 if (q->rx_class == cl)
1959 q->rx_class = NULL;
1960#endif
1961
1962 cbq_unlink_class(cl);
1963 cbq_adjust_levels(cl->tparent);
1964 cl->defmap = 0;
1965 cbq_sync_defmap(cl);
1966
1967 cbq_rmprio(q, cl);
1968 sch_tree_unlock(sch);
1969
1970 if (--cl->refcnt == 0)
1971 cbq_destroy_class(sch, cl);
1972
1973 return 0;
1974}
1975
1976static struct tcf_proto **cbq_find_tcf(struct Qdisc *sch, unsigned long arg)
1977{
1978 struct cbq_sched_data *q = qdisc_priv(sch);
1979 struct cbq_class *cl = (struct cbq_class *)arg;
1980
1981 if (cl == NULL)
1982 cl = &q->link;
1983
1984 return &cl->filter_list;
1985}
1986
1987static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent,
1988 u32 classid)
1989{
1990 struct cbq_sched_data *q = qdisc_priv(sch);
1991 struct cbq_class *p = (struct cbq_class*)parent;
1992 struct cbq_class *cl = cbq_class_lookup(q, classid);
1993
1994 if (cl) {
1995 if (p && p->level <= cl->level)
1996 return 0;
1997 cl->filters++;
1998 return (unsigned long)cl;
1999 }
2000 return 0;
2001}
2002
2003static void cbq_unbind_filter(struct Qdisc *sch, unsigned long arg)
2004{
2005 struct cbq_class *cl = (struct cbq_class*)arg;
2006
2007 cl->filters--;
2008}
2009
2010static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
2011{
2012 struct cbq_sched_data *q = qdisc_priv(sch);
2013 unsigned h;
2014
2015 if (arg->stop)
2016 return;
2017
2018 for (h = 0; h < 16; h++) {
2019 struct cbq_class *cl;
2020
2021 for (cl = q->classes[h]; cl; cl = cl->next) {
2022 if (arg->count < arg->skip) {
2023 arg->count++;
2024 continue;
2025 }
2026 if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
2027 arg->stop = 1;
2028 return;
2029 }
2030 arg->count++;
2031 }
2032 }
2033}
2034
2035static const struct Qdisc_class_ops cbq_class_ops = {
2036 .graft = cbq_graft,
2037 .leaf = cbq_leaf,
2038 .qlen_notify = cbq_qlen_notify,
2039 .get = cbq_get,
2040 .put = cbq_put,
2041 .change = cbq_change_class,
2042 .delete = cbq_delete,
2043 .walk = cbq_walk,
2044 .tcf_chain = cbq_find_tcf,
2045 .bind_tcf = cbq_bind_filter,
2046 .unbind_tcf = cbq_unbind_filter,
2047 .dump = cbq_dump_class,
2048 .dump_stats = cbq_dump_class_stats,
2049};
2050
2051static struct Qdisc_ops cbq_qdisc_ops __read_mostly = {
2052 .next = NULL,
2053 .cl_ops = &cbq_class_ops,
2054 .id = "cbq",
2055 .priv_size = sizeof(struct cbq_sched_data),
2056 .enqueue = cbq_enqueue,
2057 .dequeue = cbq_dequeue,
2058 .requeue = cbq_requeue,
2059 .drop = cbq_drop,
2060 .init = cbq_init,
2061 .reset = cbq_reset,
2062 .destroy = cbq_destroy,
2063 .change = NULL,
2064 .dump = cbq_dump,
2065 .dump_stats = cbq_dump_stats,
2066 .owner = THIS_MODULE,
2067};
2068
2069static int __init cbq_module_init(void)
2070{
2071 return register_qdisc(&cbq_qdisc_ops);
2072}
2073static void __exit cbq_module_exit(void)
2074{
2075 unregister_qdisc(&cbq_qdisc_ops);
2076}
2077module_init(cbq_module_init)
2078module_exit(cbq_module_exit)
2079MODULE_LICENSE("GPL");
2080