2 * net/sched/sch_cbq.c Class-Based Queueing discipline.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/types.h>
16 #include <linux/kernel.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
19 #include <linux/skbuff.h>
20 #include <net/netlink.h>
21 #include <net/pkt_sched.h>
24 /* Class-Based Queueing (CBQ) algorithm.
25 =======================================
27 Sources: [1] Sally Floyd and Van Jacobson, "Link-sharing and Resource
28 Management Models for Packet Networks",
29 IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995
31 [2] Sally Floyd, "Notes on CBQ and Guaranteed Service", 1995
33 [3] Sally Floyd, "Notes on Class-Based Queueing: Setting
36 [4] Sally Floyd and Michael Speer, "Experimental Results
37 for Class-Based Queueing", 1998, not published.
39 -----------------------------------------------------------------------
41 Algorithm skeleton was taken from NS simulator cbq.cc.
42 If someone wants to check this code against the LBL version,
43 he should take into account that ONLY the skeleton was borrowed,
44 the implementation is different. Particularly:
46 --- The WRR algorithm is different. Our version looks more
47 reasonable (I hope) and works when quanta are allowed to be
48 less than MTU, which is always the case when real time classes
49 have small rates. Note, that the statement of [3] is
50 incomplete, delay may actually be estimated even if class
51 per-round allotment is less than MTU. Namely, if per-round
52 allotment is W*r_i, and r_1+...+r_k = r < 1
54 delay_i <= ([MTU/(W*r_i)]*W*r + W*r + k*MTU)/B
56 In the worst case we have IntServ estimate with D = W*r+k*MTU
57 and C = MTU*r. The proof (if correct at all) is trivial.
60 --- It seems that cbq-2.0 is not very accurate. At least, I cannot
61 interpret some places, which look like wrong translations
62 from NS. Anyone is advised to find these differences
63 and explain to me, why I am wrong 8).
65 --- Linux has no EOI event, so that we cannot estimate true class
66 idle time. Workaround is to consider the next dequeue event
67 as sign that previous packet is finished. This is wrong because of
68 internal device queueing, but on a permanently loaded link it is true.
69 Moreover, combined with clock integrator, this scheme looks
70 very close to an ideal solution. */
72 struct cbq_sched_data
;
76 struct Qdisc_class_common common
;
77 struct cbq_class
*next_alive
; /* next class with backlog in this priority band */
80 unsigned char priority
; /* class priority */
81 unsigned char priority2
; /* priority to be used after overlimit */
82 unsigned char ewma_log
; /* time constant for idle time calculation */
86 /* Link-sharing scheduler parameters */
87 long maxidle
; /* Class parameters: see below. */
91 struct qdisc_rate_table
*R_tab
;
93 /* General scheduler (WRR) parameters */
95 long quantum
; /* Allotment per WRR round */
96 long weight
; /* Relative allotment: see below */
98 struct Qdisc
*qdisc
; /* Ptr to CBQ discipline */
99 struct cbq_class
*split
; /* Ptr to split node */
100 struct cbq_class
*share
; /* Ptr to LS parent in the class tree */
101 struct cbq_class
*tparent
; /* Ptr to tree parent in the class tree */
102 struct cbq_class
*borrow
; /* NULL if class is bandwidth limited;
104 struct cbq_class
*sibling
; /* Sibling chain */
105 struct cbq_class
*children
; /* Pointer to children chain */
107 struct Qdisc
*q
; /* Elementary queueing discipline */
111 unsigned char cpriority
; /* Effective priority */
112 unsigned char delayed
;
113 unsigned char level
; /* level of the class in hierarchy:
114 0 for leaf classes, and maximal
115 level of children + 1 for nodes.
118 psched_time_t last
; /* Last end of service */
119 psched_time_t undertime
;
121 long deficit
; /* Saved deficit for WRR */
122 psched_time_t penalized
;
123 struct gnet_stats_basic_packed bstats
;
124 struct gnet_stats_queue qstats
;
125 struct gnet_stats_rate_est64 rate_est
;
126 struct tc_cbq_xstats xstats
;
128 struct tcf_proto __rcu
*filter_list
;
133 struct cbq_class
*defaults
[TC_PRIO_MAX
+ 1];
136 struct cbq_sched_data
{
137 struct Qdisc_class_hash clhash
; /* Hash table of all classes */
138 int nclasses
[TC_CBQ_MAXPRIO
+ 1];
139 unsigned int quanta
[TC_CBQ_MAXPRIO
+ 1];
141 struct cbq_class link
;
143 unsigned int activemask
;
144 struct cbq_class
*active
[TC_CBQ_MAXPRIO
+ 1]; /* List of all classes
147 #ifdef CONFIG_NET_CLS_ACT
148 struct cbq_class
*rx_class
;
150 struct cbq_class
*tx_class
;
151 struct cbq_class
*tx_borrowed
;
153 psched_time_t now
; /* Cached timestamp */
156 struct hrtimer delay_timer
;
157 struct qdisc_watchdog watchdog
; /* Watchdog timer,
161 psched_tdiff_t wd_expires
;
167 #define L2T(cl, len) qdisc_l2t((cl)->R_tab, len)
169 static inline struct cbq_class
*
170 cbq_class_lookup(struct cbq_sched_data
*q
, u32 classid
)
172 struct Qdisc_class_common
*clc
;
174 clc
= qdisc_class_find(&q
->clhash
, classid
);
177 return container_of(clc
, struct cbq_class
, common
);
180 #ifdef CONFIG_NET_CLS_ACT
182 static struct cbq_class
*
183 cbq_reclassify(struct sk_buff
*skb
, struct cbq_class
*this)
185 struct cbq_class
*cl
;
187 for (cl
= this->tparent
; cl
; cl
= cl
->tparent
) {
188 struct cbq_class
*new = cl
->defaults
[TC_PRIO_BESTEFFORT
];
190 if (new != NULL
&& new != this)
198 /* Classify packet. The procedure is pretty complicated, but
199 * it allows us to combine link sharing and priority scheduling
202 * Namely, you can put link sharing rules (f.e. route based) at root of CBQ,
203 * so that it resolves to split nodes. Then packets are classified
204 * by logical priority, or a more specific classifier may be attached
208 static struct cbq_class
*
209 cbq_classify(struct sk_buff
*skb
, struct Qdisc
*sch
, int *qerr
)
211 struct cbq_sched_data
*q
= qdisc_priv(sch
);
212 struct cbq_class
*head
= &q
->link
;
213 struct cbq_class
**defmap
;
214 struct cbq_class
*cl
= NULL
;
215 u32 prio
= skb
->priority
;
216 struct tcf_proto
*fl
;
217 struct tcf_result res
;
220 * Step 1. If skb->priority points to one of our classes, use it.
222 if (TC_H_MAJ(prio
^ sch
->handle
) == 0 &&
223 (cl
= cbq_class_lookup(q
, prio
)) != NULL
)
226 *qerr
= NET_XMIT_SUCCESS
| __NET_XMIT_BYPASS
;
229 defmap
= head
->defaults
;
231 fl
= rcu_dereference_bh(head
->filter_list
);
233 * Step 2+n. Apply classifier.
235 result
= tc_classify(skb
, fl
, &res
, true);
236 if (!fl
|| result
< 0)
239 cl
= (void *)res
.class;
241 if (TC_H_MAJ(res
.classid
))
242 cl
= cbq_class_lookup(q
, res
.classid
);
243 else if ((cl
= defmap
[res
.classid
& TC_PRIO_MAX
]) == NULL
)
244 cl
= defmap
[TC_PRIO_BESTEFFORT
];
249 if (cl
->level
>= head
->level
)
251 #ifdef CONFIG_NET_CLS_ACT
255 *qerr
= NET_XMIT_SUCCESS
| __NET_XMIT_STOLEN
;
258 case TC_ACT_RECLASSIFY
:
259 return cbq_reclassify(skb
, cl
);
266 * Step 3+n. If classifier selected a link sharing class,
267 * apply agency specific classifier.
268 * Repeat this procdure until we hit a leaf node.
277 * Step 4. No success...
279 if (TC_H_MAJ(prio
) == 0 &&
280 !(cl
= head
->defaults
[prio
& TC_PRIO_MAX
]) &&
281 !(cl
= head
->defaults
[TC_PRIO_BESTEFFORT
]))
288 * A packet has just been enqueued on the empty class.
289 * cbq_activate_class adds it to the tail of active class list
290 * of its priority band.
293 static inline void cbq_activate_class(struct cbq_class
*cl
)
295 struct cbq_sched_data
*q
= qdisc_priv(cl
->qdisc
);
296 int prio
= cl
->cpriority
;
297 struct cbq_class
*cl_tail
;
299 cl_tail
= q
->active
[prio
];
300 q
->active
[prio
] = cl
;
302 if (cl_tail
!= NULL
) {
303 cl
->next_alive
= cl_tail
->next_alive
;
304 cl_tail
->next_alive
= cl
;
307 q
->activemask
|= (1<<prio
);
312 * Unlink class from active chain.
313 * Note that this same procedure is done directly in cbq_dequeue*
314 * during round-robin procedure.
317 static void cbq_deactivate_class(struct cbq_class
*this)
319 struct cbq_sched_data
*q
= qdisc_priv(this->qdisc
);
320 int prio
= this->cpriority
;
321 struct cbq_class
*cl
;
322 struct cbq_class
*cl_prev
= q
->active
[prio
];
325 cl
= cl_prev
->next_alive
;
327 cl_prev
->next_alive
= cl
->next_alive
;
328 cl
->next_alive
= NULL
;
330 if (cl
== q
->active
[prio
]) {
331 q
->active
[prio
] = cl_prev
;
332 if (cl
== q
->active
[prio
]) {
333 q
->active
[prio
] = NULL
;
334 q
->activemask
&= ~(1<<prio
);
340 } while ((cl_prev
= cl
) != q
->active
[prio
]);
344 cbq_mark_toplevel(struct cbq_sched_data
*q
, struct cbq_class
*cl
)
346 int toplevel
= q
->toplevel
;
348 if (toplevel
> cl
->level
) {
349 psched_time_t now
= psched_get_time();
352 if (cl
->undertime
< now
) {
353 q
->toplevel
= cl
->level
;
356 } while ((cl
= cl
->borrow
) != NULL
&& toplevel
> cl
->level
);
361 cbq_enqueue(struct sk_buff
*skb
, struct Qdisc
*sch
)
363 struct cbq_sched_data
*q
= qdisc_priv(sch
);
364 int uninitialized_var(ret
);
365 struct cbq_class
*cl
= cbq_classify(skb
, sch
, &ret
);
367 #ifdef CONFIG_NET_CLS_ACT
371 if (ret
& __NET_XMIT_BYPASS
)
372 qdisc_qstats_drop(sch
);
377 ret
= qdisc_enqueue(skb
, cl
->q
);
378 if (ret
== NET_XMIT_SUCCESS
) {
380 cbq_mark_toplevel(q
, cl
);
382 cbq_activate_class(cl
);
386 if (net_xmit_drop_count(ret
)) {
387 qdisc_qstats_drop(sch
);
388 cbq_mark_toplevel(q
, cl
);
394 /* Overlimit action: penalize leaf class by adding offtime */
395 static void cbq_overlimit(struct cbq_class
*cl
)
397 struct cbq_sched_data
*q
= qdisc_priv(cl
->qdisc
);
398 psched_tdiff_t delay
= cl
->undertime
- q
->now
;
401 delay
+= cl
->offtime
;
404 * Class goes to sleep, so that it will have no
405 * chance to work avgidle. Let's forgive it 8)
407 * BTW cbq-2.0 has a crap in this
408 * place, apparently they forgot to shift it by cl->ewma_log.
411 delay
-= (-cl
->avgidle
) - ((-cl
->avgidle
) >> cl
->ewma_log
);
412 if (cl
->avgidle
< cl
->minidle
)
413 cl
->avgidle
= cl
->minidle
;
416 cl
->undertime
= q
->now
+ delay
;
418 cl
->xstats
.overactions
++;
421 if (q
->wd_expires
== 0 || q
->wd_expires
> delay
)
422 q
->wd_expires
= delay
;
424 /* Dirty work! We must schedule wakeups based on
425 * real available rate, rather than leaf rate,
426 * which may be tiny (even zero).
428 if (q
->toplevel
== TC_CBQ_MAXLEVEL
) {
430 psched_tdiff_t base_delay
= q
->wd_expires
;
432 for (b
= cl
->borrow
; b
; b
= b
->borrow
) {
433 delay
= b
->undertime
- q
->now
;
434 if (delay
< base_delay
) {
441 q
->wd_expires
= base_delay
;
445 static psched_tdiff_t
cbq_undelay_prio(struct cbq_sched_data
*q
, int prio
,
448 struct cbq_class
*cl
;
449 struct cbq_class
*cl_prev
= q
->active
[prio
];
450 psched_time_t sched
= now
;
456 cl
= cl_prev
->next_alive
;
457 if (now
- cl
->penalized
> 0) {
458 cl_prev
->next_alive
= cl
->next_alive
;
459 cl
->next_alive
= NULL
;
460 cl
->cpriority
= cl
->priority
;
462 cbq_activate_class(cl
);
464 if (cl
== q
->active
[prio
]) {
465 q
->active
[prio
] = cl_prev
;
466 if (cl
== q
->active
[prio
]) {
467 q
->active
[prio
] = NULL
;
472 cl
= cl_prev
->next_alive
;
473 } else if (sched
- cl
->penalized
> 0)
474 sched
= cl
->penalized
;
475 } while ((cl_prev
= cl
) != q
->active
[prio
]);
480 static enum hrtimer_restart
cbq_undelay(struct hrtimer
*timer
)
482 struct cbq_sched_data
*q
= container_of(timer
, struct cbq_sched_data
,
484 struct Qdisc
*sch
= q
->watchdog
.qdisc
;
486 psched_tdiff_t delay
= 0;
489 now
= psched_get_time();
495 int prio
= ffz(~pmask
);
500 tmp
= cbq_undelay_prio(q
, prio
, now
);
503 if (tmp
< delay
|| delay
== 0)
511 time
= ktime_set(0, 0);
512 time
= ktime_add_ns(time
, PSCHED_TICKS2NS(now
+ delay
));
513 hrtimer_start(&q
->delay_timer
, time
, HRTIMER_MODE_ABS_PINNED
);
516 __netif_schedule(qdisc_root(sch
));
517 return HRTIMER_NORESTART
;
521 * It is mission critical procedure.
523 * We "regenerate" toplevel cutoff, if transmitting class
524 * has backlog and it is not regulated. It is not part of
525 * original CBQ description, but looks more reasonable.
526 * Probably, it is wrong. This question needs further investigation.
530 cbq_update_toplevel(struct cbq_sched_data
*q
, struct cbq_class
*cl
,
531 struct cbq_class
*borrowed
)
533 if (cl
&& q
->toplevel
>= borrowed
->level
) {
534 if (cl
->q
->q
.qlen
> 1) {
536 if (borrowed
->undertime
== PSCHED_PASTPERFECT
) {
537 q
->toplevel
= borrowed
->level
;
540 } while ((borrowed
= borrowed
->borrow
) != NULL
);
543 /* It is not necessary now. Uncommenting it
544 will save CPU cycles, but decrease fairness.
546 q
->toplevel
= TC_CBQ_MAXLEVEL
;
552 cbq_update(struct cbq_sched_data
*q
)
554 struct cbq_class
*this = q
->tx_class
;
555 struct cbq_class
*cl
= this;
560 /* Time integrator. We calculate EOS time
561 * by adding expected packet transmission time.
563 now
= q
->now
+ L2T(&q
->link
, len
);
565 for ( ; cl
; cl
= cl
->share
) {
566 long avgidle
= cl
->avgidle
;
569 cl
->bstats
.packets
++;
570 cl
->bstats
.bytes
+= len
;
573 * (now - last) is total time between packet right edges.
574 * (last_pktlen/rate) is "virtual" busy time, so that
576 * idle = (now - last) - last_pktlen/rate
579 idle
= now
- cl
->last
;
580 if ((unsigned long)idle
> 128*1024*1024) {
581 avgidle
= cl
->maxidle
;
583 idle
-= L2T(cl
, len
);
585 /* true_avgidle := (1-W)*true_avgidle + W*idle,
586 * where W=2^{-ewma_log}. But cl->avgidle is scaled:
587 * cl->avgidle == true_avgidle/W,
590 avgidle
+= idle
- (avgidle
>>cl
->ewma_log
);
594 /* Overlimit or at-limit */
596 if (avgidle
< cl
->minidle
)
597 avgidle
= cl
->minidle
;
599 cl
->avgidle
= avgidle
;
601 /* Calculate expected time, when this class
602 * will be allowed to send.
603 * It will occur, when:
604 * (1-W)*true_avgidle + W*delay = 0, i.e.
605 * idle = (1/W - 1)*(-true_avgidle)
607 * idle = (1 - W)*(-cl->avgidle);
609 idle
= (-avgidle
) - ((-avgidle
) >> cl
->ewma_log
);
613 * To maintain the rate allocated to the class,
614 * we add to undertime virtual clock,
615 * necessary to complete transmitted packet.
616 * (len/phys_bandwidth has been already passed
617 * to the moment of cbq_update)
620 idle
-= L2T(&q
->link
, len
);
621 idle
+= L2T(cl
, len
);
623 cl
->undertime
= now
+ idle
;
627 cl
->undertime
= PSCHED_PASTPERFECT
;
628 if (avgidle
> cl
->maxidle
)
629 cl
->avgidle
= cl
->maxidle
;
631 cl
->avgidle
= avgidle
;
633 if ((s64
)(now
- cl
->last
) > 0)
637 cbq_update_toplevel(q
, this, q
->tx_borrowed
);
640 static inline struct cbq_class
*
641 cbq_under_limit(struct cbq_class
*cl
)
643 struct cbq_sched_data
*q
= qdisc_priv(cl
->qdisc
);
644 struct cbq_class
*this_cl
= cl
;
646 if (cl
->tparent
== NULL
)
649 if (cl
->undertime
== PSCHED_PASTPERFECT
|| q
->now
>= cl
->undertime
) {
655 /* It is very suspicious place. Now overlimit
656 * action is generated for not bounded classes
657 * only if link is completely congested.
658 * Though it is in agree with ancestor-only paradigm,
659 * it looks very stupid. Particularly,
660 * it means that this chunk of code will either
661 * never be called or result in strong amplification
662 * of burstiness. Dangerous, silly, and, however,
663 * no another solution exists.
667 this_cl
->qstats
.overlimits
++;
668 cbq_overlimit(this_cl
);
671 if (cl
->level
> q
->toplevel
)
673 } while (cl
->undertime
!= PSCHED_PASTPERFECT
&& q
->now
< cl
->undertime
);
679 static inline struct sk_buff
*
680 cbq_dequeue_prio(struct Qdisc
*sch
, int prio
)
682 struct cbq_sched_data
*q
= qdisc_priv(sch
);
683 struct cbq_class
*cl_tail
, *cl_prev
, *cl
;
687 cl_tail
= cl_prev
= q
->active
[prio
];
688 cl
= cl_prev
->next_alive
;
695 struct cbq_class
*borrow
= cl
;
698 (borrow
= cbq_under_limit(cl
)) == NULL
)
701 if (cl
->deficit
<= 0) {
702 /* Class exhausted its allotment per
703 * this round. Switch to the next one.
706 cl
->deficit
+= cl
->quantum
;
710 skb
= cl
->q
->dequeue(cl
->q
);
712 /* Class did not give us any skb :-(
713 * It could occur even if cl->q->q.qlen != 0
714 * f.e. if cl->q == "tbf"
719 cl
->deficit
-= qdisc_pkt_len(skb
);
721 q
->tx_borrowed
= borrow
;
723 #ifndef CBQ_XSTATS_BORROWS_BYTES
724 borrow
->xstats
.borrows
++;
725 cl
->xstats
.borrows
++;
727 borrow
->xstats
.borrows
+= qdisc_pkt_len(skb
);
728 cl
->xstats
.borrows
+= qdisc_pkt_len(skb
);
731 q
->tx_len
= qdisc_pkt_len(skb
);
733 if (cl
->deficit
<= 0) {
734 q
->active
[prio
] = cl
;
736 cl
->deficit
+= cl
->quantum
;
741 if (cl
->q
->q
.qlen
== 0 || prio
!= cl
->cpriority
) {
742 /* Class is empty or penalized.
743 * Unlink it from active chain.
745 cl_prev
->next_alive
= cl
->next_alive
;
746 cl
->next_alive
= NULL
;
748 /* Did cl_tail point to it? */
753 /* Was it the last class in this band? */
756 q
->active
[prio
] = NULL
;
757 q
->activemask
&= ~(1<<prio
);
759 cbq_activate_class(cl
);
763 q
->active
[prio
] = cl_tail
;
766 cbq_activate_class(cl
);
774 } while (cl_prev
!= cl_tail
);
777 q
->active
[prio
] = cl_prev
;
782 static inline struct sk_buff
*
783 cbq_dequeue_1(struct Qdisc
*sch
)
785 struct cbq_sched_data
*q
= qdisc_priv(sch
);
787 unsigned int activemask
;
789 activemask
= q
->activemask
& 0xFF;
791 int prio
= ffz(~activemask
);
792 activemask
&= ~(1<<prio
);
793 skb
= cbq_dequeue_prio(sch
, prio
);
800 static struct sk_buff
*
801 cbq_dequeue(struct Qdisc
*sch
)
804 struct cbq_sched_data
*q
= qdisc_priv(sch
);
807 now
= psched_get_time();
817 skb
= cbq_dequeue_1(sch
);
819 qdisc_bstats_update(sch
, skb
);
824 /* All the classes are overlimit.
826 * It is possible, if:
828 * 1. Scheduler is empty.
829 * 2. Toplevel cutoff inhibited borrowing.
830 * 3. Root class is overlimit.
832 * Reset 2d and 3d conditions and retry.
834 * Note, that NS and cbq-2.0 are buggy, peeking
835 * an arbitrary class is appropriate for ancestor-only
836 * sharing, but not for toplevel algorithm.
838 * Our version is better, but slower, because it requires
839 * two passes, but it is unavoidable with top-level sharing.
842 if (q
->toplevel
== TC_CBQ_MAXLEVEL
&&
843 q
->link
.undertime
== PSCHED_PASTPERFECT
)
846 q
->toplevel
= TC_CBQ_MAXLEVEL
;
847 q
->link
.undertime
= PSCHED_PASTPERFECT
;
850 /* No packets in scheduler or nobody wants to give them to us :-(
851 * Sigh... start watchdog timer in the last case.
855 qdisc_qstats_overlimit(sch
);
857 qdisc_watchdog_schedule(&q
->watchdog
,
858 now
+ q
->wd_expires
);
863 /* CBQ class maintanance routines */
865 static void cbq_adjust_levels(struct cbq_class
*this)
872 struct cbq_class
*cl
;
877 if (cl
->level
> level
)
879 } while ((cl
= cl
->sibling
) != this->children
);
881 this->level
= level
+ 1;
882 } while ((this = this->tparent
) != NULL
);
885 static void cbq_normalize_quanta(struct cbq_sched_data
*q
, int prio
)
887 struct cbq_class
*cl
;
890 if (q
->quanta
[prio
] == 0)
893 for (h
= 0; h
< q
->clhash
.hashsize
; h
++) {
894 hlist_for_each_entry(cl
, &q
->clhash
.hash
[h
], common
.hnode
) {
895 /* BUGGGG... Beware! This expression suffer of
896 * arithmetic overflows!
898 if (cl
->priority
== prio
) {
899 cl
->quantum
= (cl
->weight
*cl
->allot
*q
->nclasses
[prio
])/
902 if (cl
->quantum
<= 0 ||
903 cl
->quantum
> 32*qdisc_dev(cl
->qdisc
)->mtu
) {
904 pr_warn("CBQ: class %08x has bad quantum==%ld, repaired.\n",
905 cl
->common
.classid
, cl
->quantum
);
906 cl
->quantum
= qdisc_dev(cl
->qdisc
)->mtu
/2 + 1;
912 static void cbq_sync_defmap(struct cbq_class
*cl
)
914 struct cbq_sched_data
*q
= qdisc_priv(cl
->qdisc
);
915 struct cbq_class
*split
= cl
->split
;
922 for (i
= 0; i
<= TC_PRIO_MAX
; i
++) {
923 if (split
->defaults
[i
] == cl
&& !(cl
->defmap
& (1<<i
)))
924 split
->defaults
[i
] = NULL
;
927 for (i
= 0; i
<= TC_PRIO_MAX
; i
++) {
928 int level
= split
->level
;
930 if (split
->defaults
[i
])
933 for (h
= 0; h
< q
->clhash
.hashsize
; h
++) {
936 hlist_for_each_entry(c
, &q
->clhash
.hash
[h
],
938 if (c
->split
== split
&& c
->level
< level
&&
939 c
->defmap
& (1<<i
)) {
940 split
->defaults
[i
] = c
;
948 static void cbq_change_defmap(struct cbq_class
*cl
, u32 splitid
, u32 def
, u32 mask
)
950 struct cbq_class
*split
= NULL
;
956 splitid
= split
->common
.classid
;
959 if (split
== NULL
|| split
->common
.classid
!= splitid
) {
960 for (split
= cl
->tparent
; split
; split
= split
->tparent
)
961 if (split
->common
.classid
== splitid
)
968 if (cl
->split
!= split
) {
972 cl
->defmap
= def
& mask
;
974 cl
->defmap
= (cl
->defmap
& ~mask
) | (def
& mask
);
979 static void cbq_unlink_class(struct cbq_class
*this)
981 struct cbq_class
*cl
, **clp
;
982 struct cbq_sched_data
*q
= qdisc_priv(this->qdisc
);
984 qdisc_class_hash_remove(&q
->clhash
, &this->common
);
987 clp
= &this->sibling
;
995 } while ((cl
= *clp
) != this->sibling
);
997 if (this->tparent
->children
== this) {
998 this->tparent
->children
= this->sibling
;
999 if (this->sibling
== this)
1000 this->tparent
->children
= NULL
;
1003 WARN_ON(this->sibling
!= this);
1007 static void cbq_link_class(struct cbq_class
*this)
1009 struct cbq_sched_data
*q
= qdisc_priv(this->qdisc
);
1010 struct cbq_class
*parent
= this->tparent
;
1012 this->sibling
= this;
1013 qdisc_class_hash_insert(&q
->clhash
, &this->common
);
1018 if (parent
->children
== NULL
) {
1019 parent
->children
= this;
1021 this->sibling
= parent
->children
->sibling
;
1022 parent
->children
->sibling
= this;
1027 cbq_reset(struct Qdisc
*sch
)
1029 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1030 struct cbq_class
*cl
;
1037 q
->tx_borrowed
= NULL
;
1038 qdisc_watchdog_cancel(&q
->watchdog
);
1039 hrtimer_cancel(&q
->delay_timer
);
1040 q
->toplevel
= TC_CBQ_MAXLEVEL
;
1041 q
->now
= psched_get_time();
1043 for (prio
= 0; prio
<= TC_CBQ_MAXPRIO
; prio
++)
1044 q
->active
[prio
] = NULL
;
1046 for (h
= 0; h
< q
->clhash
.hashsize
; h
++) {
1047 hlist_for_each_entry(cl
, &q
->clhash
.hash
[h
], common
.hnode
) {
1050 cl
->next_alive
= NULL
;
1051 cl
->undertime
= PSCHED_PASTPERFECT
;
1052 cl
->avgidle
= cl
->maxidle
;
1053 cl
->deficit
= cl
->quantum
;
1054 cl
->cpriority
= cl
->priority
;
1061 static int cbq_set_lss(struct cbq_class
*cl
, struct tc_cbq_lssopt
*lss
)
1063 if (lss
->change
& TCF_CBQ_LSS_FLAGS
) {
1064 cl
->share
= (lss
->flags
& TCF_CBQ_LSS_ISOLATED
) ? NULL
: cl
->tparent
;
1065 cl
->borrow
= (lss
->flags
& TCF_CBQ_LSS_BOUNDED
) ? NULL
: cl
->tparent
;
1067 if (lss
->change
& TCF_CBQ_LSS_EWMA
)
1068 cl
->ewma_log
= lss
->ewma_log
;
1069 if (lss
->change
& TCF_CBQ_LSS_AVPKT
)
1070 cl
->avpkt
= lss
->avpkt
;
1071 if (lss
->change
& TCF_CBQ_LSS_MINIDLE
)
1072 cl
->minidle
= -(long)lss
->minidle
;
1073 if (lss
->change
& TCF_CBQ_LSS_MAXIDLE
) {
1074 cl
->maxidle
= lss
->maxidle
;
1075 cl
->avgidle
= lss
->maxidle
;
1077 if (lss
->change
& TCF_CBQ_LSS_OFFTIME
)
1078 cl
->offtime
= lss
->offtime
;
1082 static void cbq_rmprio(struct cbq_sched_data
*q
, struct cbq_class
*cl
)
1084 q
->nclasses
[cl
->priority
]--;
1085 q
->quanta
[cl
->priority
] -= cl
->weight
;
1086 cbq_normalize_quanta(q
, cl
->priority
);
1089 static void cbq_addprio(struct cbq_sched_data
*q
, struct cbq_class
*cl
)
1091 q
->nclasses
[cl
->priority
]++;
1092 q
->quanta
[cl
->priority
] += cl
->weight
;
1093 cbq_normalize_quanta(q
, cl
->priority
);
1096 static int cbq_set_wrr(struct cbq_class
*cl
, struct tc_cbq_wrropt
*wrr
)
1098 struct cbq_sched_data
*q
= qdisc_priv(cl
->qdisc
);
1101 cl
->allot
= wrr
->allot
;
1103 cl
->weight
= wrr
->weight
;
1104 if (wrr
->priority
) {
1105 cl
->priority
= wrr
->priority
- 1;
1106 cl
->cpriority
= cl
->priority
;
1107 if (cl
->priority
>= cl
->priority2
)
1108 cl
->priority2
= TC_CBQ_MAXPRIO
- 1;
1115 static int cbq_set_fopt(struct cbq_class
*cl
, struct tc_cbq_fopt
*fopt
)
1117 cbq_change_defmap(cl
, fopt
->split
, fopt
->defmap
, fopt
->defchange
);
1121 static const struct nla_policy cbq_policy
[TCA_CBQ_MAX
+ 1] = {
1122 [TCA_CBQ_LSSOPT
] = { .len
= sizeof(struct tc_cbq_lssopt
) },
1123 [TCA_CBQ_WRROPT
] = { .len
= sizeof(struct tc_cbq_wrropt
) },
1124 [TCA_CBQ_FOPT
] = { .len
= sizeof(struct tc_cbq_fopt
) },
1125 [TCA_CBQ_OVL_STRATEGY
] = { .len
= sizeof(struct tc_cbq_ovl
) },
1126 [TCA_CBQ_RATE
] = { .len
= sizeof(struct tc_ratespec
) },
1127 [TCA_CBQ_RTAB
] = { .type
= NLA_BINARY
, .len
= TC_RTAB_SIZE
},
1128 [TCA_CBQ_POLICE
] = { .len
= sizeof(struct tc_cbq_police
) },
1131 static int cbq_init(struct Qdisc
*sch
, struct nlattr
*opt
)
1133 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1134 struct nlattr
*tb
[TCA_CBQ_MAX
+ 1];
1135 struct tc_ratespec
*r
;
1138 err
= nla_parse_nested(tb
, TCA_CBQ_MAX
, opt
, cbq_policy
);
1142 if (tb
[TCA_CBQ_RTAB
] == NULL
|| tb
[TCA_CBQ_RATE
] == NULL
)
1145 r
= nla_data(tb
[TCA_CBQ_RATE
]);
1147 if ((q
->link
.R_tab
= qdisc_get_rtab(r
, tb
[TCA_CBQ_RTAB
])) == NULL
)
1150 err
= qdisc_class_hash_init(&q
->clhash
);
1155 q
->link
.sibling
= &q
->link
;
1156 q
->link
.common
.classid
= sch
->handle
;
1157 q
->link
.qdisc
= sch
;
1158 q
->link
.q
= qdisc_create_dflt(sch
->dev_queue
, &pfifo_qdisc_ops
,
1161 q
->link
.q
= &noop_qdisc
;
1163 q
->link
.priority
= TC_CBQ_MAXPRIO
- 1;
1164 q
->link
.priority2
= TC_CBQ_MAXPRIO
- 1;
1165 q
->link
.cpriority
= TC_CBQ_MAXPRIO
- 1;
1166 q
->link
.allot
= psched_mtu(qdisc_dev(sch
));
1167 q
->link
.quantum
= q
->link
.allot
;
1168 q
->link
.weight
= q
->link
.R_tab
->rate
.rate
;
1170 q
->link
.ewma_log
= TC_CBQ_DEF_EWMA
;
1171 q
->link
.avpkt
= q
->link
.allot
/2;
1172 q
->link
.minidle
= -0x7FFFFFFF;
1174 qdisc_watchdog_init(&q
->watchdog
, sch
);
1175 hrtimer_init(&q
->delay_timer
, CLOCK_MONOTONIC
, HRTIMER_MODE_ABS_PINNED
);
1176 q
->delay_timer
.function
= cbq_undelay
;
1177 q
->toplevel
= TC_CBQ_MAXLEVEL
;
1178 q
->now
= psched_get_time();
1180 cbq_link_class(&q
->link
);
1182 if (tb
[TCA_CBQ_LSSOPT
])
1183 cbq_set_lss(&q
->link
, nla_data(tb
[TCA_CBQ_LSSOPT
]));
1185 cbq_addprio(q
, &q
->link
);
1189 qdisc_put_rtab(q
->link
.R_tab
);
1193 static int cbq_dump_rate(struct sk_buff
*skb
, struct cbq_class
*cl
)
1195 unsigned char *b
= skb_tail_pointer(skb
);
1197 if (nla_put(skb
, TCA_CBQ_RATE
, sizeof(cl
->R_tab
->rate
), &cl
->R_tab
->rate
))
1198 goto nla_put_failure
;
1206 static int cbq_dump_lss(struct sk_buff
*skb
, struct cbq_class
*cl
)
1208 unsigned char *b
= skb_tail_pointer(skb
);
1209 struct tc_cbq_lssopt opt
;
1212 if (cl
->borrow
== NULL
)
1213 opt
.flags
|= TCF_CBQ_LSS_BOUNDED
;
1214 if (cl
->share
== NULL
)
1215 opt
.flags
|= TCF_CBQ_LSS_ISOLATED
;
1216 opt
.ewma_log
= cl
->ewma_log
;
1217 opt
.level
= cl
->level
;
1218 opt
.avpkt
= cl
->avpkt
;
1219 opt
.maxidle
= cl
->maxidle
;
1220 opt
.minidle
= (u32
)(-cl
->minidle
);
1221 opt
.offtime
= cl
->offtime
;
1223 if (nla_put(skb
, TCA_CBQ_LSSOPT
, sizeof(opt
), &opt
))
1224 goto nla_put_failure
;
1232 static int cbq_dump_wrr(struct sk_buff
*skb
, struct cbq_class
*cl
)
1234 unsigned char *b
= skb_tail_pointer(skb
);
1235 struct tc_cbq_wrropt opt
;
1237 memset(&opt
, 0, sizeof(opt
));
1239 opt
.allot
= cl
->allot
;
1240 opt
.priority
= cl
->priority
+ 1;
1241 opt
.cpriority
= cl
->cpriority
+ 1;
1242 opt
.weight
= cl
->weight
;
1243 if (nla_put(skb
, TCA_CBQ_WRROPT
, sizeof(opt
), &opt
))
1244 goto nla_put_failure
;
1252 static int cbq_dump_fopt(struct sk_buff
*skb
, struct cbq_class
*cl
)
1254 unsigned char *b
= skb_tail_pointer(skb
);
1255 struct tc_cbq_fopt opt
;
1257 if (cl
->split
|| cl
->defmap
) {
1258 opt
.split
= cl
->split
? cl
->split
->common
.classid
: 0;
1259 opt
.defmap
= cl
->defmap
;
1261 if (nla_put(skb
, TCA_CBQ_FOPT
, sizeof(opt
), &opt
))
1262 goto nla_put_failure
;
1271 static int cbq_dump_attr(struct sk_buff
*skb
, struct cbq_class
*cl
)
1273 if (cbq_dump_lss(skb
, cl
) < 0 ||
1274 cbq_dump_rate(skb
, cl
) < 0 ||
1275 cbq_dump_wrr(skb
, cl
) < 0 ||
1276 cbq_dump_fopt(skb
, cl
) < 0)
1281 static int cbq_dump(struct Qdisc
*sch
, struct sk_buff
*skb
)
1283 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1284 struct nlattr
*nest
;
1286 nest
= nla_nest_start(skb
, TCA_OPTIONS
);
1288 goto nla_put_failure
;
1289 if (cbq_dump_attr(skb
, &q
->link
) < 0)
1290 goto nla_put_failure
;
1291 return nla_nest_end(skb
, nest
);
1294 nla_nest_cancel(skb
, nest
);
1299 cbq_dump_stats(struct Qdisc
*sch
, struct gnet_dump
*d
)
1301 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1303 q
->link
.xstats
.avgidle
= q
->link
.avgidle
;
1304 return gnet_stats_copy_app(d
, &q
->link
.xstats
, sizeof(q
->link
.xstats
));
1308 cbq_dump_class(struct Qdisc
*sch
, unsigned long arg
,
1309 struct sk_buff
*skb
, struct tcmsg
*tcm
)
1311 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1312 struct nlattr
*nest
;
1315 tcm
->tcm_parent
= cl
->tparent
->common
.classid
;
1317 tcm
->tcm_parent
= TC_H_ROOT
;
1318 tcm
->tcm_handle
= cl
->common
.classid
;
1319 tcm
->tcm_info
= cl
->q
->handle
;
1321 nest
= nla_nest_start(skb
, TCA_OPTIONS
);
1323 goto nla_put_failure
;
1324 if (cbq_dump_attr(skb
, cl
) < 0)
1325 goto nla_put_failure
;
1326 return nla_nest_end(skb
, nest
);
1329 nla_nest_cancel(skb
, nest
);
1334 cbq_dump_class_stats(struct Qdisc
*sch
, unsigned long arg
,
1335 struct gnet_dump
*d
)
1337 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1338 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1340 cl
->xstats
.avgidle
= cl
->avgidle
;
1341 cl
->xstats
.undertime
= 0;
1343 if (cl
->undertime
!= PSCHED_PASTPERFECT
)
1344 cl
->xstats
.undertime
= cl
->undertime
- q
->now
;
1346 if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch
),
1347 d
, NULL
, &cl
->bstats
) < 0 ||
1348 gnet_stats_copy_rate_est(d
, &cl
->bstats
, &cl
->rate_est
) < 0 ||
1349 gnet_stats_copy_queue(d
, NULL
, &cl
->qstats
, cl
->q
->q
.qlen
) < 0)
1352 return gnet_stats_copy_app(d
, &cl
->xstats
, sizeof(cl
->xstats
));
1355 static int cbq_graft(struct Qdisc
*sch
, unsigned long arg
, struct Qdisc
*new,
1358 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1361 new = qdisc_create_dflt(sch
->dev_queue
,
1362 &pfifo_qdisc_ops
, cl
->common
.classid
);
1367 *old
= qdisc_replace(sch
, new, &cl
->q
);
1371 static struct Qdisc
*cbq_leaf(struct Qdisc
*sch
, unsigned long arg
)
1373 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1378 static void cbq_qlen_notify(struct Qdisc
*sch
, unsigned long arg
)
1380 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1382 if (cl
->q
->q
.qlen
== 0)
1383 cbq_deactivate_class(cl
);
1386 static unsigned long cbq_get(struct Qdisc
*sch
, u32 classid
)
1388 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1389 struct cbq_class
*cl
= cbq_class_lookup(q
, classid
);
1393 return (unsigned long)cl
;
1398 static void cbq_destroy_class(struct Qdisc
*sch
, struct cbq_class
*cl
)
1400 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1402 WARN_ON(cl
->filters
);
1404 tcf_destroy_chain(&cl
->filter_list
);
1405 qdisc_destroy(cl
->q
);
1406 qdisc_put_rtab(cl
->R_tab
);
1407 gen_kill_estimator(&cl
->bstats
, &cl
->rate_est
);
1412 static void cbq_destroy(struct Qdisc
*sch
)
1414 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1415 struct hlist_node
*next
;
1416 struct cbq_class
*cl
;
1419 #ifdef CONFIG_NET_CLS_ACT
1423 * Filters must be destroyed first because we don't destroy the
1424 * classes from root to leafs which means that filters can still
1425 * be bound to classes which have been destroyed already. --TGR '04
1427 for (h
= 0; h
< q
->clhash
.hashsize
; h
++) {
1428 hlist_for_each_entry(cl
, &q
->clhash
.hash
[h
], common
.hnode
)
1429 tcf_destroy_chain(&cl
->filter_list
);
1431 for (h
= 0; h
< q
->clhash
.hashsize
; h
++) {
1432 hlist_for_each_entry_safe(cl
, next
, &q
->clhash
.hash
[h
],
1434 cbq_destroy_class(sch
, cl
);
1436 qdisc_class_hash_destroy(&q
->clhash
);
1439 static void cbq_put(struct Qdisc
*sch
, unsigned long arg
)
1441 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1443 if (--cl
->refcnt
== 0) {
1444 #ifdef CONFIG_NET_CLS_ACT
1445 spinlock_t
*root_lock
= qdisc_root_sleeping_lock(sch
);
1446 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1448 spin_lock_bh(root_lock
);
1449 if (q
->rx_class
== cl
)
1451 spin_unlock_bh(root_lock
);
1454 cbq_destroy_class(sch
, cl
);
1459 cbq_change_class(struct Qdisc
*sch
, u32 classid
, u32 parentid
, struct nlattr
**tca
,
1463 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1464 struct cbq_class
*cl
= (struct cbq_class
*)*arg
;
1465 struct nlattr
*opt
= tca
[TCA_OPTIONS
];
1466 struct nlattr
*tb
[TCA_CBQ_MAX
+ 1];
1467 struct cbq_class
*parent
;
1468 struct qdisc_rate_table
*rtab
= NULL
;
1473 err
= nla_parse_nested(tb
, TCA_CBQ_MAX
, opt
, cbq_policy
);
1477 if (tb
[TCA_CBQ_OVL_STRATEGY
] || tb
[TCA_CBQ_POLICE
])
1484 cl
->tparent
->common
.classid
!= parentid
)
1486 if (!cl
->tparent
&& parentid
!= TC_H_ROOT
)
1490 if (tb
[TCA_CBQ_RATE
]) {
1491 rtab
= qdisc_get_rtab(nla_data(tb
[TCA_CBQ_RATE
]),
1497 if (tca
[TCA_RATE
]) {
1498 err
= gen_replace_estimator(&cl
->bstats
, NULL
,
1501 qdisc_root_sleeping_running(sch
),
1504 qdisc_put_rtab(rtab
);
1509 /* Change class parameters */
1512 if (cl
->next_alive
!= NULL
)
1513 cbq_deactivate_class(cl
);
1516 qdisc_put_rtab(cl
->R_tab
);
1520 if (tb
[TCA_CBQ_LSSOPT
])
1521 cbq_set_lss(cl
, nla_data(tb
[TCA_CBQ_LSSOPT
]));
1523 if (tb
[TCA_CBQ_WRROPT
]) {
1525 cbq_set_wrr(cl
, nla_data(tb
[TCA_CBQ_WRROPT
]));
1528 if (tb
[TCA_CBQ_FOPT
])
1529 cbq_set_fopt(cl
, nla_data(tb
[TCA_CBQ_FOPT
]));
1532 cbq_activate_class(cl
);
1534 sch_tree_unlock(sch
);
1539 if (parentid
== TC_H_ROOT
)
1542 if (tb
[TCA_CBQ_WRROPT
] == NULL
|| tb
[TCA_CBQ_RATE
] == NULL
||
1543 tb
[TCA_CBQ_LSSOPT
] == NULL
)
1546 rtab
= qdisc_get_rtab(nla_data(tb
[TCA_CBQ_RATE
]), tb
[TCA_CBQ_RTAB
]);
1552 if (TC_H_MAJ(classid
^ sch
->handle
) ||
1553 cbq_class_lookup(q
, classid
))
1557 classid
= TC_H_MAKE(sch
->handle
, 0x8000);
1559 for (i
= 0; i
< 0x8000; i
++) {
1560 if (++q
->hgenerator
>= 0x8000)
1562 if (cbq_class_lookup(q
, classid
|q
->hgenerator
) == NULL
)
1568 classid
= classid
|q
->hgenerator
;
1573 parent
= cbq_class_lookup(q
, parentid
);
1580 cl
= kzalloc(sizeof(*cl
), GFP_KERNEL
);
1584 if (tca
[TCA_RATE
]) {
1585 err
= gen_new_estimator(&cl
->bstats
, NULL
, &cl
->rate_est
,
1587 qdisc_root_sleeping_running(sch
),
1598 cl
->q
= qdisc_create_dflt(sch
->dev_queue
, &pfifo_qdisc_ops
, classid
);
1600 cl
->q
= &noop_qdisc
;
1601 cl
->common
.classid
= classid
;
1602 cl
->tparent
= parent
;
1604 cl
->allot
= parent
->allot
;
1605 cl
->quantum
= cl
->allot
;
1606 cl
->weight
= cl
->R_tab
->rate
.rate
;
1610 cl
->borrow
= cl
->tparent
;
1611 if (cl
->tparent
!= &q
->link
)
1612 cl
->share
= cl
->tparent
;
1613 cbq_adjust_levels(parent
);
1614 cl
->minidle
= -0x7FFFFFFF;
1615 cbq_set_lss(cl
, nla_data(tb
[TCA_CBQ_LSSOPT
]));
1616 cbq_set_wrr(cl
, nla_data(tb
[TCA_CBQ_WRROPT
]));
1617 if (cl
->ewma_log
== 0)
1618 cl
->ewma_log
= q
->link
.ewma_log
;
1619 if (cl
->maxidle
== 0)
1620 cl
->maxidle
= q
->link
.maxidle
;
1622 cl
->avpkt
= q
->link
.avpkt
;
1623 if (tb
[TCA_CBQ_FOPT
])
1624 cbq_set_fopt(cl
, nla_data(tb
[TCA_CBQ_FOPT
]));
1625 sch_tree_unlock(sch
);
1627 qdisc_class_hash_grow(sch
, &q
->clhash
);
1629 *arg
= (unsigned long)cl
;
1633 qdisc_put_rtab(rtab
);
1637 static int cbq_delete(struct Qdisc
*sch
, unsigned long arg
)
1639 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1640 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1641 unsigned int qlen
, backlog
;
1643 if (cl
->filters
|| cl
->children
|| cl
== &q
->link
)
1648 qlen
= cl
->q
->q
.qlen
;
1649 backlog
= cl
->q
->qstats
.backlog
;
1651 qdisc_tree_reduce_backlog(cl
->q
, qlen
, backlog
);
1654 cbq_deactivate_class(cl
);
1656 if (q
->tx_borrowed
== cl
)
1657 q
->tx_borrowed
= q
->tx_class
;
1658 if (q
->tx_class
== cl
) {
1660 q
->tx_borrowed
= NULL
;
1662 #ifdef CONFIG_NET_CLS_ACT
1663 if (q
->rx_class
== cl
)
1667 cbq_unlink_class(cl
);
1668 cbq_adjust_levels(cl
->tparent
);
1670 cbq_sync_defmap(cl
);
1673 sch_tree_unlock(sch
);
1675 BUG_ON(--cl
->refcnt
== 0);
1677 * This shouldn't happen: we "hold" one cops->get() when called
1678 * from tc_ctl_tclass; the destroy method is done from cops->put().
1684 static struct tcf_proto __rcu
**cbq_find_tcf(struct Qdisc
*sch
,
1687 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1688 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1693 return &cl
->filter_list
;
1696 static unsigned long cbq_bind_filter(struct Qdisc
*sch
, unsigned long parent
,
1699 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1700 struct cbq_class
*p
= (struct cbq_class
*)parent
;
1701 struct cbq_class
*cl
= cbq_class_lookup(q
, classid
);
1704 if (p
&& p
->level
<= cl
->level
)
1707 return (unsigned long)cl
;
1712 static void cbq_unbind_filter(struct Qdisc
*sch
, unsigned long arg
)
1714 struct cbq_class
*cl
= (struct cbq_class
*)arg
;
1719 static void cbq_walk(struct Qdisc
*sch
, struct qdisc_walker
*arg
)
1721 struct cbq_sched_data
*q
= qdisc_priv(sch
);
1722 struct cbq_class
*cl
;
1728 for (h
= 0; h
< q
->clhash
.hashsize
; h
++) {
1729 hlist_for_each_entry(cl
, &q
->clhash
.hash
[h
], common
.hnode
) {
1730 if (arg
->count
< arg
->skip
) {
1734 if (arg
->fn(sch
, (unsigned long)cl
, arg
) < 0) {
1743 static const struct Qdisc_class_ops cbq_class_ops
= {
1746 .qlen_notify
= cbq_qlen_notify
,
1749 .change
= cbq_change_class
,
1750 .delete = cbq_delete
,
1752 .tcf_chain
= cbq_find_tcf
,
1753 .bind_tcf
= cbq_bind_filter
,
1754 .unbind_tcf
= cbq_unbind_filter
,
1755 .dump
= cbq_dump_class
,
1756 .dump_stats
= cbq_dump_class_stats
,
1759 static struct Qdisc_ops cbq_qdisc_ops __read_mostly
= {
1761 .cl_ops
= &cbq_class_ops
,
1763 .priv_size
= sizeof(struct cbq_sched_data
),
1764 .enqueue
= cbq_enqueue
,
1765 .dequeue
= cbq_dequeue
,
1766 .peek
= qdisc_peek_dequeued
,
1769 .destroy
= cbq_destroy
,
1772 .dump_stats
= cbq_dump_stats
,
1773 .owner
= THIS_MODULE
,
1776 static int __init
cbq_module_init(void)
1778 return register_qdisc(&cbq_qdisc_ops
);
1780 static void __exit
cbq_module_exit(void)
1782 unregister_qdisc(&cbq_qdisc_ops
);
1784 module_init(cbq_module_init
)
1785 module_exit(cbq_module_exit
)
1786 MODULE_LICENSE("GPL");