Diff markup
1 /* 1 /*
2 * net/sched/sch_cbq.c Class-Based Queueing d 2 * net/sched/sch_cbq.c Class-Based Queueing discipline.
3 * 3 *
4 * This program is free software; 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of t 5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Softw 6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your 7 * 2 of the License, or (at your option) any later version.
8 * 8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2. 9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 * 10 *
11 */ 11 */
12 12
13 #include <linux/module.h> 13 #include <linux/module.h>
14 #include <linux/types.h> 14 #include <linux/types.h>
15 #include <linux/kernel.h> 15 #include <linux/kernel.h>
16 #include <linux/string.h> 16 #include <linux/string.h>
17 #include <linux/errno.h> 17 #include <linux/errno.h>
18 #include <linux/skbuff.h> 18 #include <linux/skbuff.h>
19 #include <net/netlink.h> 19 #include <net/netlink.h>
20 #include <net/pkt_sched.h> 20 #include <net/pkt_sched.h>
21 21
22 22
23 /* Class-Based Queueing (CBQ) algorithm. 23 /* Class-Based Queueing (CBQ) algorithm.
24 ====================================== 24 =======================================
25 25
26 Sources: [1] Sally Floyd and Van Jacob 26 Sources: [1] Sally Floyd and Van Jacobson, "Link-sharing and Resource
27 Management Models for Packet 27 Management Models for Packet Networks",
28 IEEE/ACM Transactions on Netw 28 IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995
29 29
30 [2] Sally Floyd, "Notes on CB 30 [2] Sally Floyd, "Notes on CBQ and Guaranteed Service", 1995
31 31
32 [3] Sally Floyd, "Notes on Cl 32 [3] Sally Floyd, "Notes on Class-Based Queueing: Setting
33 Parameters", 1996 33 Parameters", 1996
34 34
35 [4] Sally Floyd and Michael S 35 [4] Sally Floyd and Michael Speer, "Experimental Results
36 for Class-Based Queueing", 19 36 for Class-Based Queueing", 1998, not published.
37 37
38 -------------------------------------- 38 -----------------------------------------------------------------------
39 39
40 Algorithm skeleton was taken from NS s 40 Algorithm skeleton was taken from NS simulator cbq.cc.
41 If someone wants to check this code ag 41 If someone wants to check this code against the LBL version,
42 he should take into account that ONLY 42 he should take into account that ONLY the skeleton was borrowed,
43 the implementation is different. Parti 43 the implementation is different. Particularly:
44 44
45 --- The WRR algorithm is different. Ou 45 --- The WRR algorithm is different. Our version looks more
46 reasonable (I hope) and works when qua 46 reasonable (I hope) and works when quanta are allowed to be
47 less than MTU, which is always the cas 47 less than MTU, which is always the case when real time classes
48 have small rates. Note, that the state 48 have small rates. Note, that the statement of [3] is
49 incomplete, delay may actually be esti 49 incomplete, delay may actually be estimated even if class
50 per-round allotment is less than MTU. 50 per-round allotment is less than MTU. Namely, if per-round
51 allotment is W*r_i, and r_1+...+r_k = 51 allotment is W*r_i, and r_1+...+r_k = r < 1
52 52
53 delay_i <= ([MTU/(W*r_i)]*W*r + W*r + 53 delay_i <= ([MTU/(W*r_i)]*W*r + W*r + k*MTU)/B
54 54
55 In the worst case we have IntServ esti 55 In the worst case we have IntServ estimate with D = W*r+k*MTU
56 and C = MTU*r. The proof (if correct a 56 and C = MTU*r. The proof (if correct at all) is trivial.
57 57
58 58
59 --- It seems that cbq-2.0 is not very 59 --- It seems that cbq-2.0 is not very accurate. At least, I cannot
60 interpret some places, which look like 60 interpret some places, which look like wrong translations
61 from NS. Anyone is advised to find the 61 from NS. Anyone is advised to find these differences
62 and explain to me, why I am wrong 8). 62 and explain to me, why I am wrong 8).
63 63
64 --- Linux has no EOI event, so that we 64 --- Linux has no EOI event, so that we cannot estimate true class
65 idle time. Workaround is to consider t 65 idle time. Workaround is to consider the next dequeue event
66 as sign that previous packet is finish 66 as sign that previous packet is finished. This is wrong because of
67 internal device queueing, but on a per 67 internal device queueing, but on a permanently loaded link it is true.
68 Moreover, combined with clock integrat 68 Moreover, combined with clock integrator, this scheme looks
69 very close to an ideal solution. */ 69 very close to an ideal solution. */
70 70
71 struct cbq_sched_data; 71 struct cbq_sched_data;
72 72
73 73
74 struct cbq_class 74 struct cbq_class
75 { 75 {
76 struct cbq_class *next; 76 struct cbq_class *next; /* hash table link */
77 struct cbq_class *next_alive; 77 struct cbq_class *next_alive; /* next class with backlog in this priority band */
78 78
79 /* Parameters */ 79 /* Parameters */
80 u32 classid; 80 u32 classid;
81 unsigned char priority; 81 unsigned char priority; /* class priority */
82 unsigned char priority2; 82 unsigned char priority2; /* priority to be used after overlimit */
83 unsigned char ewma_log; 83 unsigned char ewma_log; /* time constant for idle time calculation */
84 unsigned char ovl_strategy; 84 unsigned char ovl_strategy;
85 #ifdef CONFIG_NET_CLS_ACT 85 #ifdef CONFIG_NET_CLS_ACT
86 unsigned char police; 86 unsigned char police;
87 #endif 87 #endif
88 88
89 u32 defmap; 89 u32 defmap;
90 90
91 /* Link-sharing scheduler parameters * 91 /* Link-sharing scheduler parameters */
92 long maxidle; 92 long maxidle; /* Class parameters: see below. */
93 long offtime; 93 long offtime;
94 long minidle; 94 long minidle;
95 u32 avpkt; 95 u32 avpkt;
96 struct qdisc_rate_table *R_tab; 96 struct qdisc_rate_table *R_tab;
97 97
98 /* Overlimit strategy parameters */ 98 /* Overlimit strategy parameters */
99 void (*overlimit)(s 99 void (*overlimit)(struct cbq_class *cl);
100 psched_tdiff_t penalty; 100 psched_tdiff_t penalty;
101 101
102 /* General scheduler (WRR) parameters 102 /* General scheduler (WRR) parameters */
103 long allot; 103 long allot;
104 long quantum; 104 long quantum; /* Allotment per WRR round */
105 long weight; 105 long weight; /* Relative allotment: see below */
106 106
107 struct Qdisc *qdisc; 107 struct Qdisc *qdisc; /* Ptr to CBQ discipline */
108 struct cbq_class *split; 108 struct cbq_class *split; /* Ptr to split node */
109 struct cbq_class *share; 109 struct cbq_class *share; /* Ptr to LS parent in the class tree */
110 struct cbq_class *tparent; 110 struct cbq_class *tparent; /* Ptr to tree parent in the class tree */
111 struct cbq_class *borrow; 111 struct cbq_class *borrow; /* NULL if class is bandwidth limited;
112 112 parent otherwise */
113 struct cbq_class *sibling; 113 struct cbq_class *sibling; /* Sibling chain */
114 struct cbq_class *children; 114 struct cbq_class *children; /* Pointer to children chain */
115 115
116 struct Qdisc *q; 116 struct Qdisc *q; /* Elementary queueing discipline */
117 117
118 118
119 /* Variables */ 119 /* Variables */
120 unsigned char cpriority; 120 unsigned char cpriority; /* Effective priority */
121 unsigned char delayed; 121 unsigned char delayed;
122 unsigned char level; 122 unsigned char level; /* level of the class in hierarchy:
123 123 0 for leaf classes, and maximal
124 124 level of children + 1 for nodes.
125 125 */
126 126
127 psched_time_t last; 127 psched_time_t last; /* Last end of service */
128 psched_time_t undertime; 128 psched_time_t undertime;
129 long avgidle; 129 long avgidle;
130 long deficit; 130 long deficit; /* Saved deficit for WRR */
131 psched_time_t penalized; 131 psched_time_t penalized;
132 struct gnet_stats_basic bstats; 132 struct gnet_stats_basic bstats;
133 struct gnet_stats_queue qstats; 133 struct gnet_stats_queue qstats;
134 struct gnet_stats_rate_est rate_est; 134 struct gnet_stats_rate_est rate_est;
135 struct tc_cbq_xstats xstats; 135 struct tc_cbq_xstats xstats;
136 136
137 struct tcf_proto *filter_list; 137 struct tcf_proto *filter_list;
138 138
139 int refcnt; 139 int refcnt;
140 int filters; 140 int filters;
141 141
142 struct cbq_class *defaults[TC_P 142 struct cbq_class *defaults[TC_PRIO_MAX+1];
143 }; 143 };
144 144
145 struct cbq_sched_data 145 struct cbq_sched_data
146 { 146 {
147 struct cbq_class *classes[16]; 147 struct cbq_class *classes[16]; /* Hash table of all classes */
148 int nclasses[TC_CB 148 int nclasses[TC_CBQ_MAXPRIO+1];
149 unsigned quanta[TC_CBQ_ 149 unsigned quanta[TC_CBQ_MAXPRIO+1];
150 150
151 struct cbq_class link; 151 struct cbq_class link;
152 152
153 unsigned activemask; 153 unsigned activemask;
154 struct cbq_class *active[TC_CBQ 154 struct cbq_class *active[TC_CBQ_MAXPRIO+1]; /* List of all classes
155 155 with backlog */
156 156
157 #ifdef CONFIG_NET_CLS_ACT 157 #ifdef CONFIG_NET_CLS_ACT
158 struct cbq_class *rx_class; 158 struct cbq_class *rx_class;
159 #endif 159 #endif
160 struct cbq_class *tx_class; 160 struct cbq_class *tx_class;
161 struct cbq_class *tx_borrowed; 161 struct cbq_class *tx_borrowed;
162 int tx_len; 162 int tx_len;
163 psched_time_t now; 163 psched_time_t now; /* Cached timestamp */
164 psched_time_t now_rt; 164 psched_time_t now_rt; /* Cached real time */
165 unsigned pmask; 165 unsigned pmask;
166 166
167 struct hrtimer delay_timer; 167 struct hrtimer delay_timer;
168 struct qdisc_watchdog watchdog; 168 struct qdisc_watchdog watchdog; /* Watchdog timer,
169 169 started when CBQ has
170 170 backlog, but cannot
171 171 transmit just now */
172 psched_tdiff_t wd_expires; 172 psched_tdiff_t wd_expires;
173 int toplevel; 173 int toplevel;
174 u32 hgenerator; 174 u32 hgenerator;
175 }; 175 };
176 176
177 177
178 #define L2T(cl,len) qdisc_l2t((cl)->R_tab, 178 #define L2T(cl,len) qdisc_l2t((cl)->R_tab,len)
179 179
180 180
181 static __inline__ unsigned cbq_hash(u32 h) 181 static __inline__ unsigned cbq_hash(u32 h)
182 { 182 {
183 h ^= h>>8; 183 h ^= h>>8;
184 h ^= h>>4; 184 h ^= h>>4;
185 return h&0xF; 185 return h&0xF;
186 } 186 }
187 187
188 static __inline__ struct cbq_class * 188 static __inline__ struct cbq_class *
189 cbq_class_lookup(struct cbq_sched_data *q, u32 189 cbq_class_lookup(struct cbq_sched_data *q, u32 classid)
190 { 190 {
191 struct cbq_class *cl; 191 struct cbq_class *cl;
192 192
193 for (cl = q->classes[cbq_hash(classid) 193 for (cl = q->classes[cbq_hash(classid)]; cl; cl = cl->next)
194 if (cl->classid == classid) 194 if (cl->classid == classid)
195 return cl; 195 return cl;
196 return NULL; 196 return NULL;
197 } 197 }
198 198
199 #ifdef CONFIG_NET_CLS_ACT 199 #ifdef CONFIG_NET_CLS_ACT
200 200
201 static struct cbq_class * 201 static struct cbq_class *
202 cbq_reclassify(struct sk_buff *skb, struct cbq 202 cbq_reclassify(struct sk_buff *skb, struct cbq_class *this)
203 { 203 {
204 struct cbq_class *cl, *new; 204 struct cbq_class *cl, *new;
205 205
206 for (cl = this->tparent; cl; cl = cl-> 206 for (cl = this->tparent; cl; cl = cl->tparent)
207 if ((new = cl->defaults[TC_PRI 207 if ((new = cl->defaults[TC_PRIO_BESTEFFORT]) != NULL && new != this)
208 return new; 208 return new;
209 209
210 return NULL; 210 return NULL;
211 } 211 }
212 212
213 #endif 213 #endif
214 214
215 /* Classify packet. The procedure is pretty co 215 /* Classify packet. The procedure is pretty complicated, but
216 it allows us to combine link sharing and pr 216 it allows us to combine link sharing and priority scheduling
217 transparently. 217 transparently.
218 218
219 Namely, you can put link sharing rules (f.e 219 Namely, you can put link sharing rules (f.e. route based) at root of CBQ,
220 so that it resolves to split nodes. Then pa 220 so that it resolves to split nodes. Then packets are classified
221 by logical priority, or a more specific cla 221 by logical priority, or a more specific classifier may be attached
222 to the split node. 222 to the split node.
223 */ 223 */
224 224
225 static struct cbq_class * 225 static struct cbq_class *
226 cbq_classify(struct sk_buff *skb, struct Qdisc 226 cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
227 { 227 {
228 struct cbq_sched_data *q = qdisc_priv( 228 struct cbq_sched_data *q = qdisc_priv(sch);
229 struct cbq_class *head = &q->link; 229 struct cbq_class *head = &q->link;
230 struct cbq_class **defmap; 230 struct cbq_class **defmap;
231 struct cbq_class *cl = NULL; 231 struct cbq_class *cl = NULL;
232 u32 prio = skb->priority; 232 u32 prio = skb->priority;
233 struct tcf_result res; 233 struct tcf_result res;
234 234
235 /* 235 /*
236 * Step 1. If skb->priority points to 236 * Step 1. If skb->priority points to one of our classes, use it.
237 */ 237 */
238 if (TC_H_MAJ(prio^sch->handle) == 0 && 238 if (TC_H_MAJ(prio^sch->handle) == 0 &&
239 (cl = cbq_class_lookup(q, prio)) ! 239 (cl = cbq_class_lookup(q, prio)) != NULL)
240 return cl; 240 return cl;
241 241
242 *qerr = NET_XMIT_BYPASS; 242 *qerr = NET_XMIT_BYPASS;
243 for (;;) { 243 for (;;) {
244 int result = 0; 244 int result = 0;
245 defmap = head->defaults; 245 defmap = head->defaults;
246 246
247 /* 247 /*
248 * Step 2+n. Apply classifier. 248 * Step 2+n. Apply classifier.
249 */ 249 */
250 if (!head->filter_list || 250 if (!head->filter_list ||
251 (result = tc_classify_comp 251 (result = tc_classify_compat(skb, head->filter_list, &res)) < 0)
252 goto fallback; 252 goto fallback;
253 253
254 if ((cl = (void*)res.class) == 254 if ((cl = (void*)res.class) == NULL) {
255 if (TC_H_MAJ(res.class 255 if (TC_H_MAJ(res.classid))
256 cl = cbq_class 256 cl = cbq_class_lookup(q, res.classid);
257 else if ((cl = defmap[ 257 else if ((cl = defmap[res.classid&TC_PRIO_MAX]) == NULL)
258 cl = defmap[TC 258 cl = defmap[TC_PRIO_BESTEFFORT];
259 259
260 if (cl == NULL || cl-> 260 if (cl == NULL || cl->level >= head->level)
261 goto fallback; 261 goto fallback;
262 } 262 }
263 263
264 #ifdef CONFIG_NET_CLS_ACT 264 #ifdef CONFIG_NET_CLS_ACT
265 switch (result) { 265 switch (result) {
266 case TC_ACT_QUEUED: 266 case TC_ACT_QUEUED:
267 case TC_ACT_STOLEN: 267 case TC_ACT_STOLEN:
268 *qerr = NET_XMIT_SUCCE 268 *qerr = NET_XMIT_SUCCESS;
269 case TC_ACT_SHOT: 269 case TC_ACT_SHOT:
270 return NULL; 270 return NULL;
271 case TC_ACT_RECLASSIFY: 271 case TC_ACT_RECLASSIFY:
272 return cbq_reclassify( 272 return cbq_reclassify(skb, cl);
273 } 273 }
274 #endif 274 #endif
275 if (cl->level == 0) 275 if (cl->level == 0)
276 return cl; 276 return cl;
277 277
278 /* 278 /*
279 * Step 3+n. If classifier sel 279 * Step 3+n. If classifier selected a link sharing class,
280 * apply agency specif 280 * apply agency specific classifier.
281 * Repeat this procdur 281 * Repeat this procdure until we hit a leaf node.
282 */ 282 */
283 head = cl; 283 head = cl;
284 } 284 }
285 285
286 fallback: 286 fallback:
287 cl = head; 287 cl = head;
288 288
289 /* 289 /*
290 * Step 4. No success... 290 * Step 4. No success...
291 */ 291 */
292 if (TC_H_MAJ(prio) == 0 && 292 if (TC_H_MAJ(prio) == 0 &&
293 !(cl = head->defaults[prio&TC_PRIO 293 !(cl = head->defaults[prio&TC_PRIO_MAX]) &&
294 !(cl = head->defaults[TC_PRIO_BEST 294 !(cl = head->defaults[TC_PRIO_BESTEFFORT]))
295 return head; 295 return head;
296 296
297 return cl; 297 return cl;
298 } 298 }
299 299
300 /* 300 /*
301 A packet has just been enqueued on the empt 301 A packet has just been enqueued on the empty class.
302 cbq_activate_class adds it to the tail of a 302 cbq_activate_class adds it to the tail of active class list
303 of its priority band. 303 of its priority band.
304 */ 304 */
305 305
306 static __inline__ void cbq_activate_class(stru 306 static __inline__ void cbq_activate_class(struct cbq_class *cl)
307 { 307 {
308 struct cbq_sched_data *q = qdisc_priv( 308 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
309 int prio = cl->cpriority; 309 int prio = cl->cpriority;
310 struct cbq_class *cl_tail; 310 struct cbq_class *cl_tail;
311 311
312 cl_tail = q->active[prio]; 312 cl_tail = q->active[prio];
313 q->active[prio] = cl; 313 q->active[prio] = cl;
314 314
315 if (cl_tail != NULL) { 315 if (cl_tail != NULL) {
316 cl->next_alive = cl_tail->next 316 cl->next_alive = cl_tail->next_alive;
317 cl_tail->next_alive = cl; 317 cl_tail->next_alive = cl;
318 } else { 318 } else {
319 cl->next_alive = cl; 319 cl->next_alive = cl;
320 q->activemask |= (1<<prio); 320 q->activemask |= (1<<prio);
321 } 321 }
322 } 322 }
323 323
324 /* 324 /*
325 Unlink class from active chain. 325 Unlink class from active chain.
326 Note that this same procedure is done direc 326 Note that this same procedure is done directly in cbq_dequeue*
327 during round-robin procedure. 327 during round-robin procedure.
328 */ 328 */
329 329
330 static void cbq_deactivate_class(struct cbq_cl 330 static void cbq_deactivate_class(struct cbq_class *this)
331 { 331 {
332 struct cbq_sched_data *q = qdisc_priv( 332 struct cbq_sched_data *q = qdisc_priv(this->qdisc);
333 int prio = this->cpriority; 333 int prio = this->cpriority;
334 struct cbq_class *cl; 334 struct cbq_class *cl;
335 struct cbq_class *cl_prev = q->active[ 335 struct cbq_class *cl_prev = q->active[prio];
336 336
337 do { 337 do {
338 cl = cl_prev->next_alive; 338 cl = cl_prev->next_alive;
339 if (cl == this) { 339 if (cl == this) {
340 cl_prev->next_alive = 340 cl_prev->next_alive = cl->next_alive;
341 cl->next_alive = NULL; 341 cl->next_alive = NULL;
342 342
343 if (cl == q->active[pr 343 if (cl == q->active[prio]) {
344 q->active[prio 344 q->active[prio] = cl_prev;
345 if (cl == q->a 345 if (cl == q->active[prio]) {
346 q->act 346 q->active[prio] = NULL;
347 q->act 347 q->activemask &= ~(1<<prio);
348 return 348 return;
349 } 349 }
350 } 350 }
351 return; 351 return;
352 } 352 }
353 } while ((cl_prev = cl) != q->active[p 353 } while ((cl_prev = cl) != q->active[prio]);
354 } 354 }
355 355
356 static void 356 static void
357 cbq_mark_toplevel(struct cbq_sched_data *q, st 357 cbq_mark_toplevel(struct cbq_sched_data *q, struct cbq_class *cl)
358 { 358 {
359 int toplevel = q->toplevel; 359 int toplevel = q->toplevel;
360 360
361 if (toplevel > cl->level && !(cl->q->f 361 if (toplevel > cl->level && !(cl->q->flags&TCQ_F_THROTTLED)) {
362 psched_time_t now; 362 psched_time_t now;
363 psched_tdiff_t incr; 363 psched_tdiff_t incr;
364 364
365 now = psched_get_time(); 365 now = psched_get_time();
366 incr = now - q->now_rt; 366 incr = now - q->now_rt;
367 now = q->now + incr; 367 now = q->now + incr;
368 368
369 do { 369 do {
370 if (cl->undertime < no 370 if (cl->undertime < now) {
371 q->toplevel = 371 q->toplevel = cl->level;
372 return; 372 return;
373 } 373 }
374 } while ((cl=cl->borrow) != NU 374 } while ((cl=cl->borrow) != NULL && toplevel > cl->level);
375 } 375 }
376 } 376 }
377 377
378 static int 378 static int
379 cbq_enqueue(struct sk_buff *skb, struct Qdisc 379 cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
380 { 380 {
381 struct cbq_sched_data *q = qdisc_priv( 381 struct cbq_sched_data *q = qdisc_priv(sch);
382 int len = skb->len; 382 int len = skb->len;
383 int uninitialized_var(ret); 383 int uninitialized_var(ret);
384 struct cbq_class *cl = cbq_classify(sk 384 struct cbq_class *cl = cbq_classify(skb, sch, &ret);
385 385
386 #ifdef CONFIG_NET_CLS_ACT 386 #ifdef CONFIG_NET_CLS_ACT
387 q->rx_class = cl; 387 q->rx_class = cl;
388 #endif 388 #endif
389 if (cl == NULL) { 389 if (cl == NULL) {
390 if (ret == NET_XMIT_BYPASS) 390 if (ret == NET_XMIT_BYPASS)
391 sch->qstats.drops++; 391 sch->qstats.drops++;
392 kfree_skb(skb); 392 kfree_skb(skb);
393 return ret; 393 return ret;
394 } 394 }
395 395
396 #ifdef CONFIG_NET_CLS_ACT 396 #ifdef CONFIG_NET_CLS_ACT
397 cl->q->__parent = sch; 397 cl->q->__parent = sch;
398 #endif 398 #endif
399 if ((ret = cl->q->enqueue(skb, cl->q)) 399 if ((ret = cl->q->enqueue(skb, cl->q)) == NET_XMIT_SUCCESS) {
400 sch->q.qlen++; 400 sch->q.qlen++;
401 sch->bstats.packets++; 401 sch->bstats.packets++;
402 sch->bstats.bytes+=len; 402 sch->bstats.bytes+=len;
403 cbq_mark_toplevel(q, cl); 403 cbq_mark_toplevel(q, cl);
404 if (!cl->next_alive) 404 if (!cl->next_alive)
405 cbq_activate_class(cl) 405 cbq_activate_class(cl);
406 return ret; 406 return ret;
407 } 407 }
408 408
409 sch->qstats.drops++; 409 sch->qstats.drops++;
410 cbq_mark_toplevel(q, cl); 410 cbq_mark_toplevel(q, cl);
411 cl->qstats.drops++; 411 cl->qstats.drops++;
412 return ret; 412 return ret;
413 } 413 }
414 414
415 static int 415 static int
416 cbq_requeue(struct sk_buff *skb, struct Qdisc 416 cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
417 { 417 {
418 struct cbq_sched_data *q = qdisc_priv( 418 struct cbq_sched_data *q = qdisc_priv(sch);
419 struct cbq_class *cl; 419 struct cbq_class *cl;
420 int ret; 420 int ret;
421 421
422 if ((cl = q->tx_class) == NULL) { 422 if ((cl = q->tx_class) == NULL) {
423 kfree_skb(skb); 423 kfree_skb(skb);
424 sch->qstats.drops++; 424 sch->qstats.drops++;
425 return NET_XMIT_CN; 425 return NET_XMIT_CN;
426 } 426 }
427 q->tx_class = NULL; 427 q->tx_class = NULL;
428 428
429 cbq_mark_toplevel(q, cl); 429 cbq_mark_toplevel(q, cl);
430 430
431 #ifdef CONFIG_NET_CLS_ACT 431 #ifdef CONFIG_NET_CLS_ACT
432 q->rx_class = cl; 432 q->rx_class = cl;
433 cl->q->__parent = sch; 433 cl->q->__parent = sch;
434 #endif 434 #endif
435 if ((ret = cl->q->ops->requeue(skb, cl 435 if ((ret = cl->q->ops->requeue(skb, cl->q)) == 0) {
436 sch->q.qlen++; 436 sch->q.qlen++;
437 sch->qstats.requeues++; 437 sch->qstats.requeues++;
438 if (!cl->next_alive) 438 if (!cl->next_alive)
439 cbq_activate_class(cl) 439 cbq_activate_class(cl);
440 return 0; 440 return 0;
441 } 441 }
442 sch->qstats.drops++; 442 sch->qstats.drops++;
443 cl->qstats.drops++; 443 cl->qstats.drops++;
444 return ret; 444 return ret;
445 } 445 }
446 446
447 /* Overlimit actions */ 447 /* Overlimit actions */
448 448
449 /* TC_CBQ_OVL_CLASSIC: (default) penalize leaf 449 /* TC_CBQ_OVL_CLASSIC: (default) penalize leaf class by adding offtime */
450 450
451 static void cbq_ovl_classic(struct cbq_class * 451 static void cbq_ovl_classic(struct cbq_class *cl)
452 { 452 {
453 struct cbq_sched_data *q = qdisc_priv( 453 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
454 psched_tdiff_t delay = cl->undertime - 454 psched_tdiff_t delay = cl->undertime - q->now;
455 455
456 if (!cl->delayed) { 456 if (!cl->delayed) {
457 delay += cl->offtime; 457 delay += cl->offtime;
458 458
459 /* 459 /*
460 Class goes to sleep, so tha 460 Class goes to sleep, so that it will have no
461 chance to work avgidle. Let 461 chance to work avgidle. Let's forgive it 8)
462 462
463 BTW cbq-2.0 has a crap in t 463 BTW cbq-2.0 has a crap in this
464 place, apparently they forg 464 place, apparently they forgot to shift it by cl->ewma_log.
465 */ 465 */
466 if (cl->avgidle < 0) 466 if (cl->avgidle < 0)
467 delay -= (-cl->avgidle 467 delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
468 if (cl->avgidle < cl->minidle) 468 if (cl->avgidle < cl->minidle)
469 cl->avgidle = cl->mini 469 cl->avgidle = cl->minidle;
470 if (delay <= 0) 470 if (delay <= 0)
471 delay = 1; 471 delay = 1;
472 cl->undertime = q->now + delay 472 cl->undertime = q->now + delay;
473 473
474 cl->xstats.overactions++; 474 cl->xstats.overactions++;
475 cl->delayed = 1; 475 cl->delayed = 1;
476 } 476 }
477 if (q->wd_expires == 0 || q->wd_expire 477 if (q->wd_expires == 0 || q->wd_expires > delay)
478 q->wd_expires = delay; 478 q->wd_expires = delay;
479 479
480 /* Dirty work! We must schedule wakeup 480 /* Dirty work! We must schedule wakeups based on
481 real available rate, rather than le 481 real available rate, rather than leaf rate,
482 which may be tiny (even zero). 482 which may be tiny (even zero).
483 */ 483 */
484 if (q->toplevel == TC_CBQ_MAXLEVEL) { 484 if (q->toplevel == TC_CBQ_MAXLEVEL) {
485 struct cbq_class *b; 485 struct cbq_class *b;
486 psched_tdiff_t base_delay = q- 486 psched_tdiff_t base_delay = q->wd_expires;
487 487
488 for (b = cl->borrow; b; b = b- 488 for (b = cl->borrow; b; b = b->borrow) {
489 delay = b->undertime - 489 delay = b->undertime - q->now;
490 if (delay < base_delay 490 if (delay < base_delay) {
491 if (delay <= 0 491 if (delay <= 0)
492 delay 492 delay = 1;
493 base_delay = d 493 base_delay = delay;
494 } 494 }
495 } 495 }
496 496
497 q->wd_expires = base_delay; 497 q->wd_expires = base_delay;
498 } 498 }
499 } 499 }
500 500
501 /* TC_CBQ_OVL_RCLASSIC: penalize by offtime cl 501 /* TC_CBQ_OVL_RCLASSIC: penalize by offtime classes in hierarchy, when
502 they go overlimit 502 they go overlimit
503 */ 503 */
504 504
505 static void cbq_ovl_rclassic(struct cbq_class 505 static void cbq_ovl_rclassic(struct cbq_class *cl)
506 { 506 {
507 struct cbq_sched_data *q = qdisc_priv( 507 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
508 struct cbq_class *this = cl; 508 struct cbq_class *this = cl;
509 509
510 do { 510 do {
511 if (cl->level > q->toplevel) { 511 if (cl->level > q->toplevel) {
512 cl = NULL; 512 cl = NULL;
513 break; 513 break;
514 } 514 }
515 } while ((cl = cl->borrow) != NULL); 515 } while ((cl = cl->borrow) != NULL);
516 516
517 if (cl == NULL) 517 if (cl == NULL)
518 cl = this; 518 cl = this;
519 cbq_ovl_classic(cl); 519 cbq_ovl_classic(cl);
520 } 520 }
521 521
522 /* TC_CBQ_OVL_DELAY: delay until it will go to 522 /* TC_CBQ_OVL_DELAY: delay until it will go to underlimit */
523 523
524 static void cbq_ovl_delay(struct cbq_class *cl 524 static void cbq_ovl_delay(struct cbq_class *cl)
525 { 525 {
526 struct cbq_sched_data *q = qdisc_priv( 526 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
527 psched_tdiff_t delay = cl->undertime - 527 psched_tdiff_t delay = cl->undertime - q->now;
528 528
529 if (!cl->delayed) { 529 if (!cl->delayed) {
530 psched_time_t sched = q->now; 530 psched_time_t sched = q->now;
531 ktime_t expires; 531 ktime_t expires;
532 532
533 delay += cl->offtime; 533 delay += cl->offtime;
534 if (cl->avgidle < 0) 534 if (cl->avgidle < 0)
535 delay -= (-cl->avgidle 535 delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
536 if (cl->avgidle < cl->minidle) 536 if (cl->avgidle < cl->minidle)
537 cl->avgidle = cl->mini 537 cl->avgidle = cl->minidle;
538 cl->undertime = q->now + delay 538 cl->undertime = q->now + delay;
539 539
540 if (delay > 0) { 540 if (delay > 0) {
541 sched += delay + cl->p 541 sched += delay + cl->penalty;
542 cl->penalized = sched; 542 cl->penalized = sched;
543 cl->cpriority = TC_CBQ 543 cl->cpriority = TC_CBQ_MAXPRIO;
544 q->pmask |= (1<<TC_CBQ 544 q->pmask |= (1<<TC_CBQ_MAXPRIO);
545 545
546 expires = ktime_set(0, 546 expires = ktime_set(0, 0);
547 expires = ktime_add_ns 547 expires = ktime_add_ns(expires, PSCHED_US2NS(sched));
548 if (hrtimer_try_to_can 548 if (hrtimer_try_to_cancel(&q->delay_timer) &&
549 ktime_to_ns(ktime_ 549 ktime_to_ns(ktime_sub(q->delay_timer.expires,
550 550 expires)) > 0)
551 q->delay_timer 551 q->delay_timer.expires = expires;
552 hrtimer_restart(&q->de 552 hrtimer_restart(&q->delay_timer);
553 cl->delayed = 1; 553 cl->delayed = 1;
554 cl->xstats.overactions 554 cl->xstats.overactions++;
555 return; 555 return;
556 } 556 }
557 delay = 1; 557 delay = 1;
558 } 558 }
559 if (q->wd_expires == 0 || q->wd_expire 559 if (q->wd_expires == 0 || q->wd_expires > delay)
560 q->wd_expires = delay; 560 q->wd_expires = delay;
561 } 561 }
562 562
563 /* TC_CBQ_OVL_LOWPRIO: penalize class by lower 563 /* TC_CBQ_OVL_LOWPRIO: penalize class by lowering its priority band */
564 564
565 static void cbq_ovl_lowprio(struct cbq_class * 565 static void cbq_ovl_lowprio(struct cbq_class *cl)
566 { 566 {
567 struct cbq_sched_data *q = qdisc_priv( 567 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
568 568
569 cl->penalized = q->now + cl->penalty; 569 cl->penalized = q->now + cl->penalty;
570 570
571 if (cl->cpriority != cl->priority2) { 571 if (cl->cpriority != cl->priority2) {
572 cl->cpriority = cl->priority2; 572 cl->cpriority = cl->priority2;
573 q->pmask |= (1<<cl->cpriority) 573 q->pmask |= (1<<cl->cpriority);
574 cl->xstats.overactions++; 574 cl->xstats.overactions++;
575 } 575 }
576 cbq_ovl_classic(cl); 576 cbq_ovl_classic(cl);
577 } 577 }
578 578
579 /* TC_CBQ_OVL_DROP: penalize class by dropping 579 /* TC_CBQ_OVL_DROP: penalize class by dropping */
580 580
581 static void cbq_ovl_drop(struct cbq_class *cl) 581 static void cbq_ovl_drop(struct cbq_class *cl)
582 { 582 {
583 if (cl->q->ops->drop) 583 if (cl->q->ops->drop)
584 if (cl->q->ops->drop(cl->q)) 584 if (cl->q->ops->drop(cl->q))
585 cl->qdisc->q.qlen--; 585 cl->qdisc->q.qlen--;
586 cl->xstats.overactions++; 586 cl->xstats.overactions++;
587 cbq_ovl_classic(cl); 587 cbq_ovl_classic(cl);
588 } 588 }
589 589
590 static psched_tdiff_t cbq_undelay_prio(struct 590 static psched_tdiff_t cbq_undelay_prio(struct cbq_sched_data *q, int prio,
591 psched_ 591 psched_time_t now)
592 { 592 {
593 struct cbq_class *cl; 593 struct cbq_class *cl;
594 struct cbq_class *cl_prev = q->active[ 594 struct cbq_class *cl_prev = q->active[prio];
595 psched_time_t sched = now; 595 psched_time_t sched = now;
596 596
597 if (cl_prev == NULL) 597 if (cl_prev == NULL)
598 return 0; 598 return 0;
599 599
600 do { 600 do {
601 cl = cl_prev->next_alive; 601 cl = cl_prev->next_alive;
602 if (now - cl->penalized > 0) { 602 if (now - cl->penalized > 0) {
603 cl_prev->next_alive = 603 cl_prev->next_alive = cl->next_alive;
604 cl->next_alive = NULL; 604 cl->next_alive = NULL;
605 cl->cpriority = cl->pr 605 cl->cpriority = cl->priority;
606 cl->delayed = 0; 606 cl->delayed = 0;
607 cbq_activate_class(cl) 607 cbq_activate_class(cl);
608 608
609 if (cl == q->active[pr 609 if (cl == q->active[prio]) {
610 q->active[prio 610 q->active[prio] = cl_prev;
611 if (cl == q->a 611 if (cl == q->active[prio]) {
612 q->act 612 q->active[prio] = NULL;
613 return 613 return 0;
614 } 614 }
615 } 615 }
616 616
617 cl = cl_prev->next_ali 617 cl = cl_prev->next_alive;
618 } else if (sched - cl->penaliz 618 } else if (sched - cl->penalized > 0)
619 sched = cl->penalized; 619 sched = cl->penalized;
620 } while ((cl_prev = cl) != q->active[p 620 } while ((cl_prev = cl) != q->active[prio]);
621 621
622 return sched - now; 622 return sched - now;
623 } 623 }
624 624
625 static enum hrtimer_restart cbq_undelay(struct 625 static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
626 { 626 {
627 struct cbq_sched_data *q = container_o 627 struct cbq_sched_data *q = container_of(timer, struct cbq_sched_data,
628 628 delay_timer);
629 struct Qdisc *sch = q->watchdog.qdisc; 629 struct Qdisc *sch = q->watchdog.qdisc;
630 psched_time_t now; 630 psched_time_t now;
631 psched_tdiff_t delay = 0; 631 psched_tdiff_t delay = 0;
632 unsigned pmask; 632 unsigned pmask;
633 633
634 now = psched_get_time(); 634 now = psched_get_time();
635 635
636 pmask = q->pmask; 636 pmask = q->pmask;
637 q->pmask = 0; 637 q->pmask = 0;
638 638
639 while (pmask) { 639 while (pmask) {
640 int prio = ffz(~pmask); 640 int prio = ffz(~pmask);
641 psched_tdiff_t tmp; 641 psched_tdiff_t tmp;
642 642
643 pmask &= ~(1<<prio); 643 pmask &= ~(1<<prio);
644 644
645 tmp = cbq_undelay_prio(q, prio 645 tmp = cbq_undelay_prio(q, prio, now);
646 if (tmp > 0) { 646 if (tmp > 0) {
647 q->pmask |= 1<<prio; 647 q->pmask |= 1<<prio;
648 if (tmp < delay || del 648 if (tmp < delay || delay == 0)
649 delay = tmp; 649 delay = tmp;
650 } 650 }
651 } 651 }
652 652
653 if (delay) { 653 if (delay) {
654 ktime_t time; 654 ktime_t time;
655 655
656 time = ktime_set(0, 0); 656 time = ktime_set(0, 0);
657 time = ktime_add_ns(time, PSCH 657 time = ktime_add_ns(time, PSCHED_US2NS(now + delay));
658 hrtimer_start(&q->delay_timer, 658 hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
659 } 659 }
660 660
661 sch->flags &= ~TCQ_F_THROTTLED; 661 sch->flags &= ~TCQ_F_THROTTLED;
662 netif_schedule(sch->dev); 662 netif_schedule(sch->dev);
663 return HRTIMER_NORESTART; 663 return HRTIMER_NORESTART;
664 } 664 }
665 665
666 #ifdef CONFIG_NET_CLS_ACT 666 #ifdef CONFIG_NET_CLS_ACT
667 static int cbq_reshape_fail(struct sk_buff *sk 667 static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
668 { 668 {
669 int len = skb->len; 669 int len = skb->len;
670 struct Qdisc *sch = child->__parent; 670 struct Qdisc *sch = child->__parent;
671 struct cbq_sched_data *q = qdisc_priv( 671 struct cbq_sched_data *q = qdisc_priv(sch);
672 struct cbq_class *cl = q->rx_class; 672 struct cbq_class *cl = q->rx_class;
673 673
674 q->rx_class = NULL; 674 q->rx_class = NULL;
675 675
676 if (cl && (cl = cbq_reclassify(skb, cl 676 if (cl && (cl = cbq_reclassify(skb, cl)) != NULL) {
677 677
678 cbq_mark_toplevel(q, cl); 678 cbq_mark_toplevel(q, cl);
679 679
680 q->rx_class = cl; 680 q->rx_class = cl;
681 cl->q->__parent = sch; 681 cl->q->__parent = sch;
682 682
683 if (cl->q->enqueue(skb, cl->q) 683 if (cl->q->enqueue(skb, cl->q) == 0) {
684 sch->q.qlen++; 684 sch->q.qlen++;
685 sch->bstats.packets++; 685 sch->bstats.packets++;
686 sch->bstats.bytes+=len 686 sch->bstats.bytes+=len;
687 if (!cl->next_alive) 687 if (!cl->next_alive)
688 cbq_activate_c 688 cbq_activate_class(cl);
689 return 0; 689 return 0;
690 } 690 }
691 sch->qstats.drops++; 691 sch->qstats.drops++;
692 return 0; 692 return 0;
693 } 693 }
694 694
695 sch->qstats.drops++; 695 sch->qstats.drops++;
696 return -1; 696 return -1;
697 } 697 }
698 #endif 698 #endif
699 699
700 /* 700 /*
701 It is mission critical procedure. 701 It is mission critical procedure.
702 702
703 We "regenerate" toplevel cutoff, if transmi 703 We "regenerate" toplevel cutoff, if transmitting class
704 has backlog and it is not regulated. It is 704 has backlog and it is not regulated. It is not part of
705 original CBQ description, but looks more re 705 original CBQ description, but looks more reasonable.
706 Probably, it is wrong. This question needs 706 Probably, it is wrong. This question needs further investigation.
707 */ 707 */
708 708
709 static __inline__ void 709 static __inline__ void
710 cbq_update_toplevel(struct cbq_sched_data *q, 710 cbq_update_toplevel(struct cbq_sched_data *q, struct cbq_class *cl,
711 struct cbq_class *borrowed 711 struct cbq_class *borrowed)
712 { 712 {
713 if (cl && q->toplevel >= borrowed->lev 713 if (cl && q->toplevel >= borrowed->level) {
714 if (cl->q->q.qlen > 1) { 714 if (cl->q->q.qlen > 1) {
715 do { 715 do {
716 if (borrowed-> 716 if (borrowed->undertime == PSCHED_PASTPERFECT) {
717 q->top 717 q->toplevel = borrowed->level;
718 return 718 return;
719 } 719 }
720 } while ((borrowed=bor 720 } while ((borrowed=borrowed->borrow) != NULL);
721 } 721 }
722 #if 0 722 #if 0
723 /* It is not necessary now. Uncommenti 723 /* It is not necessary now. Uncommenting it
724 will save CPU cycles, but decrease 724 will save CPU cycles, but decrease fairness.
725 */ 725 */
726 q->toplevel = TC_CBQ_MAXLEVEL; 726 q->toplevel = TC_CBQ_MAXLEVEL;
727 #endif 727 #endif
728 } 728 }
729 } 729 }
730 730
731 static void 731 static void
732 cbq_update(struct cbq_sched_data *q) 732 cbq_update(struct cbq_sched_data *q)
733 { 733 {
734 struct cbq_class *this = q->tx_class; 734 struct cbq_class *this = q->tx_class;
735 struct cbq_class *cl = this; 735 struct cbq_class *cl = this;
736 int len = q->tx_len; 736 int len = q->tx_len;
737 737
738 q->tx_class = NULL; 738 q->tx_class = NULL;
739 739
740 for ( ; cl; cl = cl->share) { 740 for ( ; cl; cl = cl->share) {
741 long avgidle = cl->avgidle; 741 long avgidle = cl->avgidle;
742 long idle; 742 long idle;
743 743
744 cl->bstats.packets++; 744 cl->bstats.packets++;
745 cl->bstats.bytes += len; 745 cl->bstats.bytes += len;
746 746
747 /* 747 /*
748 (now - last) is total time 748 (now - last) is total time between packet right edges.
749 (last_pktlen/rate) is "virt 749 (last_pktlen/rate) is "virtual" busy time, so that
750 750
751 idle = (now - last) - 751 idle = (now - last) - last_pktlen/rate
752 */ 752 */
753 753
754 idle = q->now - cl->last; 754 idle = q->now - cl->last;
755 if ((unsigned long)idle > 128* 755 if ((unsigned long)idle > 128*1024*1024) {
756 avgidle = cl->maxidle; 756 avgidle = cl->maxidle;
757 } else { 757 } else {
758 idle -= L2T(cl, len); 758 idle -= L2T(cl, len);
759 759
760 /* true_avgidle := (1-W)*true_ 760 /* true_avgidle := (1-W)*true_avgidle + W*idle,
761 where W=2^{-ewma_log}. But 761 where W=2^{-ewma_log}. But cl->avgidle is scaled:
762 cl->avgidle == true_avgidle 762 cl->avgidle == true_avgidle/W,
763 hence: 763 hence:
764 */ 764 */
765 avgidle += idle - (avg 765 avgidle += idle - (avgidle>>cl->ewma_log);
766 } 766 }
767 767
768 if (avgidle <= 0) { 768 if (avgidle <= 0) {
769 /* Overlimit or at-lim 769 /* Overlimit or at-limit */
770 770
771 if (avgidle < cl->mini 771 if (avgidle < cl->minidle)
772 avgidle = cl-> 772 avgidle = cl->minidle;
773 773
774 cl->avgidle = avgidle; 774 cl->avgidle = avgidle;
775 775
776 /* Calculate expected 776 /* Calculate expected time, when this class
777 will be allowed to 777 will be allowed to send.
778 It will occur, when 778 It will occur, when:
779 (1-W)*true_avgidle 779 (1-W)*true_avgidle + W*delay = 0, i.e.
780 idle = (1/W - 1)*(- 780 idle = (1/W - 1)*(-true_avgidle)
781 or 781 or
782 idle = (1 - W)*(-cl 782 idle = (1 - W)*(-cl->avgidle);
783 */ 783 */
784 idle = (-avgidle) - (( 784 idle = (-avgidle) - ((-avgidle) >> cl->ewma_log);
785 785
786 /* 786 /*
787 That is not all. 787 That is not all.
788 To maintain the rat 788 To maintain the rate allocated to the class,
789 we add to undertime 789 we add to undertime virtual clock,
790 necessary to comple 790 necessary to complete transmitted packet.
791 (len/phys_bandwidth 791 (len/phys_bandwidth has been already passed
792 to the moment of cb 792 to the moment of cbq_update)
793 */ 793 */
794 794
795 idle -= L2T(&q->link, 795 idle -= L2T(&q->link, len);
796 idle += L2T(cl, len); 796 idle += L2T(cl, len);
797 797
798 cl->undertime = q->now 798 cl->undertime = q->now + idle;
799 } else { 799 } else {
800 /* Underlimit */ 800 /* Underlimit */
801 801
802 cl->undertime = PSCHED 802 cl->undertime = PSCHED_PASTPERFECT;
803 if (avgidle > cl->maxi 803 if (avgidle > cl->maxidle)
804 cl->avgidle = 804 cl->avgidle = cl->maxidle;
805 else 805 else
806 cl->avgidle = 806 cl->avgidle = avgidle;
807 } 807 }
808 cl->last = q->now; 808 cl->last = q->now;
809 } 809 }
810 810
811 cbq_update_toplevel(q, this, q->tx_bor 811 cbq_update_toplevel(q, this, q->tx_borrowed);
812 } 812 }
813 813
814 static __inline__ struct cbq_class * 814 static __inline__ struct cbq_class *
815 cbq_under_limit(struct cbq_class *cl) 815 cbq_under_limit(struct cbq_class *cl)
816 { 816 {
817 struct cbq_sched_data *q = qdisc_priv( 817 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
818 struct cbq_class *this_cl = cl; 818 struct cbq_class *this_cl = cl;
819 819
820 if (cl->tparent == NULL) 820 if (cl->tparent == NULL)
821 return cl; 821 return cl;
822 822
823 if (cl->undertime == PSCHED_PASTPERFEC 823 if (cl->undertime == PSCHED_PASTPERFECT || q->now >= cl->undertime) {
824 cl->delayed = 0; 824 cl->delayed = 0;
825 return cl; 825 return cl;
826 } 826 }
827 827
828 do { 828 do {
829 /* It is very suspicious place 829 /* It is very suspicious place. Now overlimit
830 action is generated for not 830 action is generated for not bounded classes
831 only if link is completely 831 only if link is completely congested.
832 Though it is in agree with 832 Though it is in agree with ancestor-only paradigm,
833 it looks very stupid. Parti 833 it looks very stupid. Particularly,
834 it means that this chunk of 834 it means that this chunk of code will either
835 never be called or result i 835 never be called or result in strong amplification
836 of burstiness. Dangerous, s 836 of burstiness. Dangerous, silly, and, however,
837 no another solution exists. 837 no another solution exists.
838 */ 838 */
839 if ((cl = cl->borrow) == NULL) 839 if ((cl = cl->borrow) == NULL) {
840 this_cl->qstats.overli 840 this_cl->qstats.overlimits++;
841 this_cl->overlimit(thi 841 this_cl->overlimit(this_cl);
842 return NULL; 842 return NULL;
843 } 843 }
844 if (cl->level > q->toplevel) 844 if (cl->level > q->toplevel)
845 return NULL; 845 return NULL;
846 } while (cl->undertime != PSCHED_PASTP 846 } while (cl->undertime != PSCHED_PASTPERFECT && q->now < cl->undertime);
847 847
848 cl->delayed = 0; 848 cl->delayed = 0;
849 return cl; 849 return cl;
850 } 850 }
851 851
852 static __inline__ struct sk_buff * 852 static __inline__ struct sk_buff *
853 cbq_dequeue_prio(struct Qdisc *sch, int prio) 853 cbq_dequeue_prio(struct Qdisc *sch, int prio)
854 { 854 {
855 struct cbq_sched_data *q = qdisc_priv( 855 struct cbq_sched_data *q = qdisc_priv(sch);
856 struct cbq_class *cl_tail, *cl_prev, * 856 struct cbq_class *cl_tail, *cl_prev, *cl;
857 struct sk_buff *skb; 857 struct sk_buff *skb;
858 int deficit; 858 int deficit;
859 859
860 cl_tail = cl_prev = q->active[prio]; 860 cl_tail = cl_prev = q->active[prio];
861 cl = cl_prev->next_alive; 861 cl = cl_prev->next_alive;
862 862
863 do { 863 do {
864 deficit = 0; 864 deficit = 0;
865 865
866 /* Start round */ 866 /* Start round */
867 do { 867 do {
868 struct cbq_class *borr 868 struct cbq_class *borrow = cl;
869 869
870 if (cl->q->q.qlen && 870 if (cl->q->q.qlen &&
871 (borrow = cbq_unde 871 (borrow = cbq_under_limit(cl)) == NULL)
872 goto skip_clas 872 goto skip_class;
873 873
874 if (cl->deficit <= 0) 874 if (cl->deficit <= 0) {
875 /* Class exhau 875 /* Class exhausted its allotment per
876 this round. 876 this round. Switch to the next one.
877 */ 877 */
878 deficit = 1; 878 deficit = 1;
879 cl->deficit += 879 cl->deficit += cl->quantum;
880 goto next_clas 880 goto next_class;
881 } 881 }
882 882
883 skb = cl->q->dequeue(c 883 skb = cl->q->dequeue(cl->q);
884 884
885 /* Class did not give 885 /* Class did not give us any skb :-(
886 It could occur even 886 It could occur even if cl->q->q.qlen != 0
887 f.e. if cl->q == "t 887 f.e. if cl->q == "tbf"
888 */ 888 */
889 if (skb == NULL) 889 if (skb == NULL)
890 goto skip_clas 890 goto skip_class;
891 891
892 cl->deficit -= skb->le 892 cl->deficit -= skb->len;
893 q->tx_class = cl; 893 q->tx_class = cl;
894 q->tx_borrowed = borro 894 q->tx_borrowed = borrow;
895 if (borrow != cl) { 895 if (borrow != cl) {
896 #ifndef CBQ_XSTATS_BORROWS_BYTES 896 #ifndef CBQ_XSTATS_BORROWS_BYTES
897 borrow->xstats 897 borrow->xstats.borrows++;
898 cl->xstats.bor 898 cl->xstats.borrows++;
899 #else 899 #else
900 borrow->xstats 900 borrow->xstats.borrows += skb->len;
901 cl->xstats.bor 901 cl->xstats.borrows += skb->len;
902 #endif 902 #endif
903 } 903 }
904 q->tx_len = skb->len; 904 q->tx_len = skb->len;
905 905
906 if (cl->deficit <= 0) 906 if (cl->deficit <= 0) {
907 q->active[prio 907 q->active[prio] = cl;
908 cl = cl->next_ 908 cl = cl->next_alive;
909 cl->deficit += 909 cl->deficit += cl->quantum;
910 } 910 }
911 return skb; 911 return skb;
912 912
913 skip_class: 913 skip_class:
914 if (cl->q->q.qlen == 0 914 if (cl->q->q.qlen == 0 || prio != cl->cpriority) {
915 /* Class is em 915 /* Class is empty or penalized.
916 Unlink it f 916 Unlink it from active chain.
917 */ 917 */
918 cl_prev->next_ 918 cl_prev->next_alive = cl->next_alive;
919 cl->next_alive 919 cl->next_alive = NULL;
920 920
921 /* Did cl_tail 921 /* Did cl_tail point to it? */
922 if (cl == cl_t 922 if (cl == cl_tail) {
923 /* Rep 923 /* Repair it! */
924 cl_tai 924 cl_tail = cl_prev;
925 925
926 /* Was 926 /* Was it the last class in this band? */
927 if (cl 927 if (cl == cl_tail) {
928 928 /* Kill the band! */
929 929 q->active[prio] = NULL;
930 930 q->activemask &= ~(1<<prio);
931 931 if (cl->q->q.qlen)
932 932 cbq_activate_class(cl);
933 933 return NULL;
934 } 934 }
935 935
936 q->act 936 q->active[prio] = cl_tail;
937 } 937 }
938 if (cl->q->q.q 938 if (cl->q->q.qlen)
939 cbq_ac 939 cbq_activate_class(cl);
940 940
941 cl = cl_prev; 941 cl = cl_prev;
942 } 942 }
943 943
944 next_class: 944 next_class:
945 cl_prev = cl; 945 cl_prev = cl;
946 cl = cl->next_alive; 946 cl = cl->next_alive;
947 } while (cl_prev != cl_tail); 947 } while (cl_prev != cl_tail);
948 } while (deficit); 948 } while (deficit);
949 949
950 q->active[prio] = cl_prev; 950 q->active[prio] = cl_prev;
951 951
952 return NULL; 952 return NULL;
953 } 953 }
954 954
955 static __inline__ struct sk_buff * 955 static __inline__ struct sk_buff *
956 cbq_dequeue_1(struct Qdisc *sch) 956 cbq_dequeue_1(struct Qdisc *sch)
957 { 957 {
958 struct cbq_sched_data *q = qdisc_priv( 958 struct cbq_sched_data *q = qdisc_priv(sch);
959 struct sk_buff *skb; 959 struct sk_buff *skb;
960 unsigned activemask; 960 unsigned activemask;
961 961
962 activemask = q->activemask&0xFF; 962 activemask = q->activemask&0xFF;
963 while (activemask) { 963 while (activemask) {
964 int prio = ffz(~activemask); 964 int prio = ffz(~activemask);
965 activemask &= ~(1<<prio); 965 activemask &= ~(1<<prio);
966 skb = cbq_dequeue_prio(sch, pr 966 skb = cbq_dequeue_prio(sch, prio);
967 if (skb) 967 if (skb)
968 return skb; 968 return skb;
969 } 969 }
970 return NULL; 970 return NULL;
971 } 971 }
972 972
973 static struct sk_buff * 973 static struct sk_buff *
974 cbq_dequeue(struct Qdisc *sch) 974 cbq_dequeue(struct Qdisc *sch)
975 { 975 {
976 struct sk_buff *skb; 976 struct sk_buff *skb;
977 struct cbq_sched_data *q = qdisc_priv( 977 struct cbq_sched_data *q = qdisc_priv(sch);
978 psched_time_t now; 978 psched_time_t now;
979 psched_tdiff_t incr; 979 psched_tdiff_t incr;
980 980
981 now = psched_get_time(); 981 now = psched_get_time();
982 incr = now - q->now_rt; 982 incr = now - q->now_rt;
983 983
984 if (q->tx_class) { 984 if (q->tx_class) {
985 psched_tdiff_t incr2; 985 psched_tdiff_t incr2;
986 /* Time integrator. We calcula 986 /* Time integrator. We calculate EOS time
987 by adding expected packet t 987 by adding expected packet transmission time.
988 If real time is greater, we 988 If real time is greater, we warp artificial clock,
989 so that: 989 so that:
990 990
991 cbq_time = max(real_time, w 991 cbq_time = max(real_time, work);
992 */ 992 */
993 incr2 = L2T(&q->link, q->tx_le 993 incr2 = L2T(&q->link, q->tx_len);
994 q->now += incr2; 994 q->now += incr2;
995 cbq_update(q); 995 cbq_update(q);
996 if ((incr -= incr2) < 0) 996 if ((incr -= incr2) < 0)
997 incr = 0; 997 incr = 0;
998 } 998 }
999 q->now += incr; 999 q->now += incr;
1000 q->now_rt = now; 1000 q->now_rt = now;
1001 1001
1002 for (;;) { 1002 for (;;) {
1003 q->wd_expires = 0; 1003 q->wd_expires = 0;
1004 1004
1005 skb = cbq_dequeue_1(sch); 1005 skb = cbq_dequeue_1(sch);
1006 if (skb) { 1006 if (skb) {
1007 sch->q.qlen--; 1007 sch->q.qlen--;
1008 sch->flags &= ~TCQ_F_ 1008 sch->flags &= ~TCQ_F_THROTTLED;
1009 return skb; 1009 return skb;
1010 } 1010 }
1011 1011
1012 /* All the classes are overli 1012 /* All the classes are overlimit.
1013 1013
1014 It is possible, if: 1014 It is possible, if:
1015 1015
1016 1. Scheduler is empty. 1016 1. Scheduler is empty.
1017 2. Toplevel cutoff inhibit 1017 2. Toplevel cutoff inhibited borrowing.
1018 3. Root class is overlimit 1018 3. Root class is overlimit.
1019 1019
1020 Reset 2d and 3d conditions 1020 Reset 2d and 3d conditions and retry.
1021 1021
1022 Note, that NS and cbq-2.0 1022 Note, that NS and cbq-2.0 are buggy, peeking
1023 an arbitrary class is appr 1023 an arbitrary class is appropriate for ancestor-only
1024 sharing, but not for tople 1024 sharing, but not for toplevel algorithm.
1025 1025
1026 Our version is better, but 1026 Our version is better, but slower, because it requires
1027 two passes, but it is unav 1027 two passes, but it is unavoidable with top-level sharing.
1028 */ 1028 */
1029 1029
1030 if (q->toplevel == TC_CBQ_MAX 1030 if (q->toplevel == TC_CBQ_MAXLEVEL &&
1031 q->link.undertime == PSCH 1031 q->link.undertime == PSCHED_PASTPERFECT)
1032 break; 1032 break;
1033 1033
1034 q->toplevel = TC_CBQ_MAXLEVEL 1034 q->toplevel = TC_CBQ_MAXLEVEL;
1035 q->link.undertime = PSCHED_PA 1035 q->link.undertime = PSCHED_PASTPERFECT;
1036 } 1036 }
1037 1037
1038 /* No packets in scheduler or nobody 1038 /* No packets in scheduler or nobody wants to give them to us :-(
1039 Sigh... start watchdog timer in th 1039 Sigh... start watchdog timer in the last case. */
1040 1040
1041 if (sch->q.qlen) { 1041 if (sch->q.qlen) {
1042 sch->qstats.overlimits++; 1042 sch->qstats.overlimits++;
1043 if (q->wd_expires) 1043 if (q->wd_expires)
1044 qdisc_watchdog_schedu 1044 qdisc_watchdog_schedule(&q->watchdog,
1045 1045 now + q->wd_expires);
1046 } 1046 }
1047 return NULL; 1047 return NULL;
1048 } 1048 }
1049 1049
1050 /* CBQ class maintanance routines */ 1050 /* CBQ class maintanance routines */
1051 1051
1052 static void cbq_adjust_levels(struct cbq_clas 1052 static void cbq_adjust_levels(struct cbq_class *this)
1053 { 1053 {
1054 if (this == NULL) 1054 if (this == NULL)
1055 return; 1055 return;
1056 1056
1057 do { 1057 do {
1058 int level = 0; 1058 int level = 0;
1059 struct cbq_class *cl; 1059 struct cbq_class *cl;
1060 1060
1061 if ((cl = this->children) != 1061 if ((cl = this->children) != NULL) {
1062 do { 1062 do {
1063 if (cl->level 1063 if (cl->level > level)
1064 level 1064 level = cl->level;
1065 } while ((cl = cl->si 1065 } while ((cl = cl->sibling) != this->children);
1066 } 1066 }
1067 this->level = level+1; 1067 this->level = level+1;
1068 } while ((this = this->tparent) != NU 1068 } while ((this = this->tparent) != NULL);
1069 } 1069 }
1070 1070
1071 static void cbq_normalize_quanta(struct cbq_s 1071 static void cbq_normalize_quanta(struct cbq_sched_data *q, int prio)
1072 { 1072 {
1073 struct cbq_class *cl; 1073 struct cbq_class *cl;
1074 unsigned h; 1074 unsigned h;
1075 1075
1076 if (q->quanta[prio] == 0) 1076 if (q->quanta[prio] == 0)
1077 return; 1077 return;
1078 1078
1079 for (h=0; h<16; h++) { 1079 for (h=0; h<16; h++) {
1080 for (cl = q->classes[h]; cl; 1080 for (cl = q->classes[h]; cl; cl = cl->next) {
1081 /* BUGGGG... Beware! 1081 /* BUGGGG... Beware! This expression suffer of
1082 arithmetic overflo 1082 arithmetic overflows!
1083 */ 1083 */
1084 if (cl->priority == p 1084 if (cl->priority == prio) {
1085 cl->quantum = 1085 cl->quantum = (cl->weight*cl->allot*q->nclasses[prio])/
1086 q->qu 1086 q->quanta[prio];
1087 } 1087 }
1088 if (cl->quantum <= 0 1088 if (cl->quantum <= 0 || cl->quantum>32*cl->qdisc->dev->mtu) {
1089 printk(KERN_W 1089 printk(KERN_WARNING "CBQ: class %08x has bad quantum==%ld, repaired.\n", cl->classid, cl->quantum);
1090 cl->quantum = 1090 cl->quantum = cl->qdisc->dev->mtu/2 + 1;
1091 } 1091 }
1092 } 1092 }
1093 } 1093 }
1094 } 1094 }
1095 1095
1096 static void cbq_sync_defmap(struct cbq_class 1096 static void cbq_sync_defmap(struct cbq_class *cl)
1097 { 1097 {
1098 struct cbq_sched_data *q = qdisc_priv 1098 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
1099 struct cbq_class *split = cl->split; 1099 struct cbq_class *split = cl->split;
1100 unsigned h; 1100 unsigned h;
1101 int i; 1101 int i;
1102 1102
1103 if (split == NULL) 1103 if (split == NULL)
1104 return; 1104 return;
1105 1105
1106 for (i=0; i<=TC_PRIO_MAX; i++) { 1106 for (i=0; i<=TC_PRIO_MAX; i++) {
1107 if (split->defaults[i] == cl 1107 if (split->defaults[i] == cl && !(cl->defmap&(1<<i)))
1108 split->defaults[i] = 1108 split->defaults[i] = NULL;
1109 } 1109 }
1110 1110
1111 for (i=0; i<=TC_PRIO_MAX; i++) { 1111 for (i=0; i<=TC_PRIO_MAX; i++) {
1112 int level = split->level; 1112 int level = split->level;
1113 1113
1114 if (split->defaults[i]) 1114 if (split->defaults[i])
1115 continue; 1115 continue;
1116 1116
1117 for (h=0; h<16; h++) { 1117 for (h=0; h<16; h++) {
1118 struct cbq_class *c; 1118 struct cbq_class *c;
1119 1119
1120 for (c = q->classes[h 1120 for (c = q->classes[h]; c; c = c->next) {
1121 if (c->split 1121 if (c->split == split && c->level < level &&
1122 c->defmap 1122 c->defmap&(1<<i)) {
1123 split 1123 split->defaults[i] = c;
1124 level 1124 level = c->level;
1125 } 1125 }
1126 } 1126 }
1127 } 1127 }
1128 } 1128 }
1129 } 1129 }
1130 1130
1131 static void cbq_change_defmap(struct cbq_clas 1131 static void cbq_change_defmap(struct cbq_class *cl, u32 splitid, u32 def, u32 mask)
1132 { 1132 {
1133 struct cbq_class *split = NULL; 1133 struct cbq_class *split = NULL;
1134 1134
1135 if (splitid == 0) { 1135 if (splitid == 0) {
1136 if ((split = cl->split) == NU 1136 if ((split = cl->split) == NULL)
1137 return; 1137 return;
1138 splitid = split->classid; 1138 splitid = split->classid;
1139 } 1139 }
1140 1140
1141 if (split == NULL || split->classid ! 1141 if (split == NULL || split->classid != splitid) {
1142 for (split = cl->tparent; spl 1142 for (split = cl->tparent; split; split = split->tparent)
1143 if (split->classid == 1143 if (split->classid == splitid)
1144 break; 1144 break;
1145 } 1145 }
1146 1146
1147 if (split == NULL) 1147 if (split == NULL)
1148 return; 1148 return;
1149 1149
1150 if (cl->split != split) { 1150 if (cl->split != split) {
1151 cl->defmap = 0; 1151 cl->defmap = 0;
1152 cbq_sync_defmap(cl); 1152 cbq_sync_defmap(cl);
1153 cl->split = split; 1153 cl->split = split;
1154 cl->defmap = def&mask; 1154 cl->defmap = def&mask;
1155 } else 1155 } else
1156 cl->defmap = (cl->defmap&~mas 1156 cl->defmap = (cl->defmap&~mask)|(def&mask);
1157 1157
1158 cbq_sync_defmap(cl); 1158 cbq_sync_defmap(cl);
1159 } 1159 }
1160 1160
1161 static void cbq_unlink_class(struct cbq_class 1161 static void cbq_unlink_class(struct cbq_class *this)
1162 { 1162 {
1163 struct cbq_class *cl, **clp; 1163 struct cbq_class *cl, **clp;
1164 struct cbq_sched_data *q = qdisc_priv 1164 struct cbq_sched_data *q = qdisc_priv(this->qdisc);
1165 1165
1166 for (clp = &q->classes[cbq_hash(this- 1166 for (clp = &q->classes[cbq_hash(this->classid)]; (cl = *clp) != NULL; clp = &cl->next) {
1167 if (cl == this) { 1167 if (cl == this) {
1168 *clp = cl->next; 1168 *clp = cl->next;
1169 cl->next = NULL; 1169 cl->next = NULL;
1170 break; 1170 break;
1171 } 1171 }
1172 } 1172 }
1173 1173
1174 if (this->tparent) { 1174 if (this->tparent) {
1175 clp=&this->sibling; 1175 clp=&this->sibling;
1176 cl = *clp; 1176 cl = *clp;
1177 do { 1177 do {
1178 if (cl == this) { 1178 if (cl == this) {
1179 *clp = cl->si 1179 *clp = cl->sibling;
1180 break; 1180 break;
1181 } 1181 }
1182 clp = &cl->sibling; 1182 clp = &cl->sibling;
1183 } while ((cl = *clp) != this- 1183 } while ((cl = *clp) != this->sibling);
1184 1184
1185 if (this->tparent->children = 1185 if (this->tparent->children == this) {
1186 this->tparent->childr 1186 this->tparent->children = this->sibling;
1187 if (this->sibling == 1187 if (this->sibling == this)
1188 this->tparent 1188 this->tparent->children = NULL;
1189 } 1189 }
1190 } else { 1190 } else {
1191 BUG_TRAP(this->sibling == thi 1191 BUG_TRAP(this->sibling == this);
1192 } 1192 }
1193 } 1193 }
1194 1194
1195 static void cbq_link_class(struct cbq_class * 1195 static void cbq_link_class(struct cbq_class *this)
1196 { 1196 {
1197 struct cbq_sched_data *q = qdisc_priv 1197 struct cbq_sched_data *q = qdisc_priv(this->qdisc);
1198 unsigned h = cbq_hash(this->classid); 1198 unsigned h = cbq_hash(this->classid);
1199 struct cbq_class *parent = this->tpar 1199 struct cbq_class *parent = this->tparent;
1200 1200
1201 this->sibling = this; 1201 this->sibling = this;
1202 this->next = q->classes[h]; 1202 this->next = q->classes[h];
1203 q->classes[h] = this; 1203 q->classes[h] = this;
1204 1204
1205 if (parent == NULL) 1205 if (parent == NULL)
1206 return; 1206 return;
1207 1207
1208 if (parent->children == NULL) { 1208 if (parent->children == NULL) {
1209 parent->children = this; 1209 parent->children = this;
1210 } else { 1210 } else {
1211 this->sibling = parent->child 1211 this->sibling = parent->children->sibling;
1212 parent->children->sibling = t 1212 parent->children->sibling = this;
1213 } 1213 }
1214 } 1214 }
1215 1215
1216 static unsigned int cbq_drop(struct Qdisc* sc 1216 static unsigned int cbq_drop(struct Qdisc* sch)
1217 { 1217 {
1218 struct cbq_sched_data *q = qdisc_priv 1218 struct cbq_sched_data *q = qdisc_priv(sch);
1219 struct cbq_class *cl, *cl_head; 1219 struct cbq_class *cl, *cl_head;
1220 int prio; 1220 int prio;
1221 unsigned int len; 1221 unsigned int len;
1222 1222
1223 for (prio = TC_CBQ_MAXPRIO; prio >= 0 1223 for (prio = TC_CBQ_MAXPRIO; prio >= 0; prio--) {
1224 if ((cl_head = q->active[prio 1224 if ((cl_head = q->active[prio]) == NULL)
1225 continue; 1225 continue;
1226 1226
1227 cl = cl_head; 1227 cl = cl_head;
1228 do { 1228 do {
1229 if (cl->q->ops->drop 1229 if (cl->q->ops->drop && (len = cl->q->ops->drop(cl->q))) {
1230 sch->q.qlen-- 1230 sch->q.qlen--;
1231 if (!cl->q->q 1231 if (!cl->q->q.qlen)
1232 cbq_d 1232 cbq_deactivate_class(cl);
1233 return len; 1233 return len;
1234 } 1234 }
1235 } while ((cl = cl->next_alive 1235 } while ((cl = cl->next_alive) != cl_head);
1236 } 1236 }
1237 return 0; 1237 return 0;
1238 } 1238 }
1239 1239
1240 static void 1240 static void
1241 cbq_reset(struct Qdisc* sch) 1241 cbq_reset(struct Qdisc* sch)
1242 { 1242 {
1243 struct cbq_sched_data *q = qdisc_priv 1243 struct cbq_sched_data *q = qdisc_priv(sch);
1244 struct cbq_class *cl; 1244 struct cbq_class *cl;
1245 int prio; 1245 int prio;
1246 unsigned h; 1246 unsigned h;
1247 1247
1248 q->activemask = 0; 1248 q->activemask = 0;
1249 q->pmask = 0; 1249 q->pmask = 0;
1250 q->tx_class = NULL; 1250 q->tx_class = NULL;
1251 q->tx_borrowed = NULL; 1251 q->tx_borrowed = NULL;
1252 qdisc_watchdog_cancel(&q->watchdog); 1252 qdisc_watchdog_cancel(&q->watchdog);
1253 hrtimer_cancel(&q->delay_timer); 1253 hrtimer_cancel(&q->delay_timer);
1254 q->toplevel = TC_CBQ_MAXLEVEL; 1254 q->toplevel = TC_CBQ_MAXLEVEL;
1255 q->now = psched_get_time(); 1255 q->now = psched_get_time();
1256 q->now_rt = q->now; 1256 q->now_rt = q->now;
1257 1257
1258 for (prio = 0; prio <= TC_CBQ_MAXPRIO 1258 for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++)
1259 q->active[prio] = NULL; 1259 q->active[prio] = NULL;
1260 1260
1261 for (h = 0; h < 16; h++) { 1261 for (h = 0; h < 16; h++) {
1262 for (cl = q->classes[h]; cl; 1262 for (cl = q->classes[h]; cl; cl = cl->next) {
1263 qdisc_reset(cl->q); 1263 qdisc_reset(cl->q);
1264 1264
1265 cl->next_alive = NULL 1265 cl->next_alive = NULL;
1266 cl->undertime = PSCHE 1266 cl->undertime = PSCHED_PASTPERFECT;
1267 cl->avgidle = cl->max 1267 cl->avgidle = cl->maxidle;
1268 cl->deficit = cl->qua 1268 cl->deficit = cl->quantum;
1269 cl->cpriority = cl->p 1269 cl->cpriority = cl->priority;
1270 } 1270 }
1271 } 1271 }
1272 sch->q.qlen = 0; 1272 sch->q.qlen = 0;
1273 } 1273 }
1274 1274
1275 1275
1276 static int cbq_set_lss(struct cbq_class *cl, 1276 static int cbq_set_lss(struct cbq_class *cl, struct tc_cbq_lssopt *lss)
1277 { 1277 {
1278 if (lss->change&TCF_CBQ_LSS_FLAGS) { 1278 if (lss->change&TCF_CBQ_LSS_FLAGS) {
1279 cl->share = (lss->flags&TCF_C 1279 cl->share = (lss->flags&TCF_CBQ_LSS_ISOLATED) ? NULL : cl->tparent;
1280 cl->borrow = (lss->flags&TCF_ 1280 cl->borrow = (lss->flags&TCF_CBQ_LSS_BOUNDED) ? NULL : cl->tparent;
1281 } 1281 }
1282 if (lss->change&TCF_CBQ_LSS_EWMA) 1282 if (lss->change&TCF_CBQ_LSS_EWMA)
1283 cl->ewma_log = lss->ewma_log; 1283 cl->ewma_log = lss->ewma_log;
1284 if (lss->change&TCF_CBQ_LSS_AVPKT) 1284 if (lss->change&TCF_CBQ_LSS_AVPKT)
1285 cl->avpkt = lss->avpkt; 1285 cl->avpkt = lss->avpkt;
1286 if (lss->change&TCF_CBQ_LSS_MINIDLE) 1286 if (lss->change&TCF_CBQ_LSS_MINIDLE)
1287 cl->minidle = -(long)lss->min 1287 cl->minidle = -(long)lss->minidle;
1288 if (lss->change&TCF_CBQ_LSS_MAXIDLE) 1288 if (lss->change&TCF_CBQ_LSS_MAXIDLE) {
1289 cl->maxidle = lss->maxidle; 1289 cl->maxidle = lss->maxidle;
1290 cl->avgidle = lss->maxidle; 1290 cl->avgidle = lss->maxidle;
1291 } 1291 }
1292 if (lss->change&TCF_CBQ_LSS_OFFTIME) 1292 if (lss->change&TCF_CBQ_LSS_OFFTIME)
1293 cl->offtime = lss->offtime; 1293 cl->offtime = lss->offtime;
1294 return 0; 1294 return 0;
1295 } 1295 }
1296 1296
1297 static void cbq_rmprio(struct cbq_sched_data 1297 static void cbq_rmprio(struct cbq_sched_data *q, struct cbq_class *cl)
1298 { 1298 {
1299 q->nclasses[cl->priority]--; 1299 q->nclasses[cl->priority]--;
1300 q->quanta[cl->priority] -= cl->weight 1300 q->quanta[cl->priority] -= cl->weight;
1301 cbq_normalize_quanta(q, cl->priority) 1301 cbq_normalize_quanta(q, cl->priority);
1302 } 1302 }
1303 1303
1304 static void cbq_addprio(struct cbq_sched_data 1304 static void cbq_addprio(struct cbq_sched_data *q, struct cbq_class *cl)
1305 { 1305 {
1306 q->nclasses[cl->priority]++; 1306 q->nclasses[cl->priority]++;
1307 q->quanta[cl->priority] += cl->weight 1307 q->quanta[cl->priority] += cl->weight;
1308 cbq_normalize_quanta(q, cl->priority) 1308 cbq_normalize_quanta(q, cl->priority);
1309 } 1309 }
1310 1310
1311 static int cbq_set_wrr(struct cbq_class *cl, 1311 static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr)
1312 { 1312 {
1313 struct cbq_sched_data *q = qdisc_priv 1313 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
1314 1314
1315 if (wrr->allot) 1315 if (wrr->allot)
1316 cl->allot = wrr->allot; 1316 cl->allot = wrr->allot;
1317 if (wrr->weight) 1317 if (wrr->weight)
1318 cl->weight = wrr->weight; 1318 cl->weight = wrr->weight;
1319 if (wrr->priority) { 1319 if (wrr->priority) {
1320 cl->priority = wrr->priority- 1320 cl->priority = wrr->priority-1;
1321 cl->cpriority = cl->priority; 1321 cl->cpriority = cl->priority;
1322 if (cl->priority >= cl->prior 1322 if (cl->priority >= cl->priority2)
1323 cl->priority2 = TC_CB 1323 cl->priority2 = TC_CBQ_MAXPRIO-1;
1324 } 1324 }
1325 1325
1326 cbq_addprio(q, cl); 1326 cbq_addprio(q, cl);
1327 return 0; 1327 return 0;
1328 } 1328 }
1329 1329
1330 static int cbq_set_overlimit(struct cbq_class 1330 static int cbq_set_overlimit(struct cbq_class *cl, struct tc_cbq_ovl *ovl)
1331 { 1331 {
1332 switch (ovl->strategy) { 1332 switch (ovl->strategy) {
1333 case TC_CBQ_OVL_CLASSIC: 1333 case TC_CBQ_OVL_CLASSIC:
1334 cl->overlimit = cbq_ovl_class 1334 cl->overlimit = cbq_ovl_classic;
1335 break; 1335 break;
1336 case TC_CBQ_OVL_DELAY: 1336 case TC_CBQ_OVL_DELAY:
1337 cl->overlimit = cbq_ovl_delay 1337 cl->overlimit = cbq_ovl_delay;
1338 break; 1338 break;
1339 case TC_CBQ_OVL_LOWPRIO: 1339 case TC_CBQ_OVL_LOWPRIO:
1340 if (ovl->priority2-1 >= TC_CB 1340 if (ovl->priority2-1 >= TC_CBQ_MAXPRIO ||
1341 ovl->priority2-1 <= cl->p 1341 ovl->priority2-1 <= cl->priority)
1342 return -EINVAL; 1342 return -EINVAL;
1343 cl->priority2 = ovl->priority 1343 cl->priority2 = ovl->priority2-1;
1344 cl->overlimit = cbq_ovl_lowpr 1344 cl->overlimit = cbq_ovl_lowprio;
1345 break; 1345 break;
1346 case TC_CBQ_OVL_DROP: 1346 case TC_CBQ_OVL_DROP:
1347 cl->overlimit = cbq_ovl_drop; 1347 cl->overlimit = cbq_ovl_drop;
1348 break; 1348 break;
1349 case TC_CBQ_OVL_RCLASSIC: 1349 case TC_CBQ_OVL_RCLASSIC:
1350 cl->overlimit = cbq_ovl_rclas 1350 cl->overlimit = cbq_ovl_rclassic;
1351 break; 1351 break;
1352 default: 1352 default:
1353 return -EINVAL; 1353 return -EINVAL;
1354 } 1354 }
1355 cl->penalty = ovl->penalty; 1355 cl->penalty = ovl->penalty;
1356 return 0; 1356 return 0;
1357 } 1357 }
1358 1358
1359 #ifdef CONFIG_NET_CLS_ACT 1359 #ifdef CONFIG_NET_CLS_ACT
1360 static int cbq_set_police(struct cbq_class *c 1360 static int cbq_set_police(struct cbq_class *cl, struct tc_cbq_police *p)
1361 { 1361 {
1362 cl->police = p->police; 1362 cl->police = p->police;
1363 1363
1364 if (cl->q->handle) { 1364 if (cl->q->handle) {
1365 if (p->police == TC_POLICE_RE 1365 if (p->police == TC_POLICE_RECLASSIFY)
1366 cl->q->reshape_fail = 1366 cl->q->reshape_fail = cbq_reshape_fail;
1367 else 1367 else
1368 cl->q->reshape_fail = 1368 cl->q->reshape_fail = NULL;
1369 } 1369 }
1370 return 0; 1370 return 0;
1371 } 1371 }
1372 #endif 1372 #endif
1373 1373
1374 static int cbq_set_fopt(struct cbq_class *cl, 1374 static int cbq_set_fopt(struct cbq_class *cl, struct tc_cbq_fopt *fopt)
1375 { 1375 {
1376 cbq_change_defmap(cl, fopt->split, fo 1376 cbq_change_defmap(cl, fopt->split, fopt->defmap, fopt->defchange);
1377 return 0; 1377 return 0;
1378 } 1378 }
1379 1379
1380 static const struct nla_policy cbq_policy[TCA 1380 static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
1381 [TCA_CBQ_LSSOPT] = { .len = si 1381 [TCA_CBQ_LSSOPT] = { .len = sizeof(struct tc_cbq_lssopt) },
1382 [TCA_CBQ_WRROPT] = { .len = si 1382 [TCA_CBQ_WRROPT] = { .len = sizeof(struct tc_cbq_wrropt) },
1383 [TCA_CBQ_FOPT] = { .len = si 1383 [TCA_CBQ_FOPT] = { .len = sizeof(struct tc_cbq_fopt) },
1384 [TCA_CBQ_OVL_STRATEGY] = { .len = si 1384 [TCA_CBQ_OVL_STRATEGY] = { .len = sizeof(struct tc_cbq_ovl) },
1385 [TCA_CBQ_RATE] = { .len = si 1385 [TCA_CBQ_RATE] = { .len = sizeof(struct tc_ratespec) },
1386 [TCA_CBQ_RTAB] = { .type = N 1386 [TCA_CBQ_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
1387 [TCA_CBQ_POLICE] = { .len = si 1387 [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) },
1388 }; 1388 };
1389 1389
1390 static int cbq_init(struct Qdisc *sch, struct 1390 static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
1391 { 1391 {
1392 struct cbq_sched_data *q = qdisc_priv 1392 struct cbq_sched_data *q = qdisc_priv(sch);
1393 struct nlattr *tb[TCA_CBQ_MAX + 1]; 1393 struct nlattr *tb[TCA_CBQ_MAX + 1];
1394 struct tc_ratespec *r; 1394 struct tc_ratespec *r;
1395 int err; 1395 int err;
1396 1396
1397 err = nla_parse_nested(tb, TCA_CBQ_MA 1397 err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
1398 if (err < 0) 1398 if (err < 0)
1399 return err; 1399 return err;
1400 1400
1401 if (tb[TCA_CBQ_RTAB] == NULL || tb[TC 1401 if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL)
1402 return -EINVAL; 1402 return -EINVAL;
1403 1403
1404 r = nla_data(tb[TCA_CBQ_RATE]); 1404 r = nla_data(tb[TCA_CBQ_RATE]);
1405 1405
1406 if ((q->link.R_tab = qdisc_get_rtab(r 1406 if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB])) == NULL)
1407 return -EINVAL; 1407 return -EINVAL;
1408 1408
1409 q->link.refcnt = 1; 1409 q->link.refcnt = 1;
1410 q->link.sibling = &q->link; 1410 q->link.sibling = &q->link;
1411 q->link.classid = sch->handle; 1411 q->link.classid = sch->handle;
1412 q->link.qdisc = sch; 1412 q->link.qdisc = sch;
1413 if (!(q->link.q = qdisc_create_dflt(s 1413 if (!(q->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1414 s 1414 sch->handle)))
1415 q->link.q = &noop_qdisc; 1415 q->link.q = &noop_qdisc;
1416 1416
1417 q->link.priority = TC_CBQ_MAXPRIO-1; 1417 q->link.priority = TC_CBQ_MAXPRIO-1;
1418 q->link.priority2 = TC_CBQ_MAXPRIO-1; 1418 q->link.priority2 = TC_CBQ_MAXPRIO-1;
1419 q->link.cpriority = TC_CBQ_MAXPRIO-1; 1419 q->link.cpriority = TC_CBQ_MAXPRIO-1;
1420 q->link.ovl_strategy = TC_CBQ_OVL_CLA 1420 q->link.ovl_strategy = TC_CBQ_OVL_CLASSIC;
1421 q->link.overlimit = cbq_ovl_classic; 1421 q->link.overlimit = cbq_ovl_classic;
1422 q->link.allot = psched_mtu(sch->dev); 1422 q->link.allot = psched_mtu(sch->dev);
1423 q->link.quantum = q->link.allot; 1423 q->link.quantum = q->link.allot;
1424 q->link.weight = q->link.R_tab->rate. 1424 q->link.weight = q->link.R_tab->rate.rate;
1425 1425
1426 q->link.ewma_log = TC_CBQ_DEF_EWMA; 1426 q->link.ewma_log = TC_CBQ_DEF_EWMA;
1427 q->link.avpkt = q->link.allot/2; 1427 q->link.avpkt = q->link.allot/2;
1428 q->link.minidle = -0x7FFFFFFF; 1428 q->link.minidle = -0x7FFFFFFF;
1429 1429
1430 qdisc_watchdog_init(&q->watchdog, sch 1430 qdisc_watchdog_init(&q->watchdog, sch);
1431 hrtimer_init(&q->delay_timer, CLOCK_M 1431 hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1432 q->delay_timer.function = cbq_undelay 1432 q->delay_timer.function = cbq_undelay;
1433 q->toplevel = TC_CBQ_MAXLEVEL; 1433 q->toplevel = TC_CBQ_MAXLEVEL;
1434 q->now = psched_get_time(); 1434 q->now = psched_get_time();
1435 q->now_rt = q->now; 1435 q->now_rt = q->now;
1436 1436
1437 cbq_link_class(&q->link); 1437 cbq_link_class(&q->link);
1438 1438
1439 if (tb[TCA_CBQ_LSSOPT]) 1439 if (tb[TCA_CBQ_LSSOPT])
1440 cbq_set_lss(&q->link, nla_dat 1440 cbq_set_lss(&q->link, nla_data(tb[TCA_CBQ_LSSOPT]));
1441 1441
1442 cbq_addprio(q, &q->link); 1442 cbq_addprio(q, &q->link);
1443 return 0; 1443 return 0;
1444 } 1444 }
1445 1445
1446 static __inline__ int cbq_dump_rate(struct sk 1446 static __inline__ int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl)
1447 { 1447 {
1448 unsigned char *b = skb_tail_pointer(s 1448 unsigned char *b = skb_tail_pointer(skb);
1449 1449
1450 NLA_PUT(skb, TCA_CBQ_RATE, sizeof(cl- 1450 NLA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
1451 return skb->len; 1451 return skb->len;
1452 1452
1453 nla_put_failure: 1453 nla_put_failure:
1454 nlmsg_trim(skb, b); 1454 nlmsg_trim(skb, b);
1455 return -1; 1455 return -1;
1456 } 1456 }
1457 1457
1458 static __inline__ int cbq_dump_lss(struct sk_ 1458 static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
1459 { 1459 {
1460 unsigned char *b = skb_tail_pointer(s 1460 unsigned char *b = skb_tail_pointer(skb);
1461 struct tc_cbq_lssopt opt; 1461 struct tc_cbq_lssopt opt;
1462 1462
1463 opt.flags = 0; 1463 opt.flags = 0;
1464 if (cl->borrow == NULL) 1464 if (cl->borrow == NULL)
1465 opt.flags |= TCF_CBQ_LSS_BOUN 1465 opt.flags |= TCF_CBQ_LSS_BOUNDED;
1466 if (cl->share == NULL) 1466 if (cl->share == NULL)
1467 opt.flags |= TCF_CBQ_LSS_ISOL 1467 opt.flags |= TCF_CBQ_LSS_ISOLATED;
1468 opt.ewma_log = cl->ewma_log; 1468 opt.ewma_log = cl->ewma_log;
1469 opt.level = cl->level; 1469 opt.level = cl->level;
1470 opt.avpkt = cl->avpkt; 1470 opt.avpkt = cl->avpkt;
1471 opt.maxidle = cl->maxidle; 1471 opt.maxidle = cl->maxidle;
1472 opt.minidle = (u32)(-cl->minidle); 1472 opt.minidle = (u32)(-cl->minidle);
1473 opt.offtime = cl->offtime; 1473 opt.offtime = cl->offtime;
1474 opt.change = ~0; 1474 opt.change = ~0;
1475 NLA_PUT(skb, TCA_CBQ_LSSOPT, sizeof(o 1475 NLA_PUT(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt);
1476 return skb->len; 1476 return skb->len;
1477 1477
1478 nla_put_failure: 1478 nla_put_failure:
1479 nlmsg_trim(skb, b); 1479 nlmsg_trim(skb, b);
1480 return -1; 1480 return -1;
1481 } 1481 }
1482 1482
1483 static __inline__ int cbq_dump_wrr(struct sk_ 1483 static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
1484 { 1484 {
1485 unsigned char *b = skb_tail_pointer(s 1485 unsigned char *b = skb_tail_pointer(skb);
1486 struct tc_cbq_wrropt opt; 1486 struct tc_cbq_wrropt opt;
1487 1487
1488 opt.flags = 0; 1488 opt.flags = 0;
1489 opt.allot = cl->allot; 1489 opt.allot = cl->allot;
1490 opt.priority = cl->priority+1; 1490 opt.priority = cl->priority+1;
1491 opt.cpriority = cl->cpriority+1; 1491 opt.cpriority = cl->cpriority+1;
1492 opt.weight = cl->weight; 1492 opt.weight = cl->weight;
1493 NLA_PUT(skb, TCA_CBQ_WRROPT, sizeof(o 1493 NLA_PUT(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt);
1494 return skb->len; 1494 return skb->len;
1495 1495
1496 nla_put_failure: 1496 nla_put_failure:
1497 nlmsg_trim(skb, b); 1497 nlmsg_trim(skb, b);
1498 return -1; 1498 return -1;
1499 } 1499 }
1500 1500
1501 static __inline__ int cbq_dump_ovl(struct sk_ 1501 static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
1502 { 1502 {
1503 unsigned char *b = skb_tail_pointer(s 1503 unsigned char *b = skb_tail_pointer(skb);
1504 struct tc_cbq_ovl opt; 1504 struct tc_cbq_ovl opt;
1505 1505
1506 opt.strategy = cl->ovl_strategy; 1506 opt.strategy = cl->ovl_strategy;
1507 opt.priority2 = cl->priority2+1; 1507 opt.priority2 = cl->priority2+1;
1508 opt.pad = 0; 1508 opt.pad = 0;
1509 opt.penalty = cl->penalty; 1509 opt.penalty = cl->penalty;
1510 NLA_PUT(skb, TCA_CBQ_OVL_STRATEGY, si 1510 NLA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
1511 return skb->len; 1511 return skb->len;
1512 1512
1513 nla_put_failure: 1513 nla_put_failure:
1514 nlmsg_trim(skb, b); 1514 nlmsg_trim(skb, b);
1515 return -1; 1515 return -1;
1516 } 1516 }
1517 1517
1518 static __inline__ int cbq_dump_fopt(struct sk 1518 static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
1519 { 1519 {
1520 unsigned char *b = skb_tail_pointer(s 1520 unsigned char *b = skb_tail_pointer(skb);
1521 struct tc_cbq_fopt opt; 1521 struct tc_cbq_fopt opt;
1522 1522
1523 if (cl->split || cl->defmap) { 1523 if (cl->split || cl->defmap) {
1524 opt.split = cl->split ? cl->s 1524 opt.split = cl->split ? cl->split->classid : 0;
1525 opt.defmap = cl->defmap; 1525 opt.defmap = cl->defmap;
1526 opt.defchange = ~0; 1526 opt.defchange = ~0;
1527 NLA_PUT(skb, TCA_CBQ_FOPT, si 1527 NLA_PUT(skb, TCA_CBQ_FOPT, sizeof(opt), &opt);
1528 } 1528 }
1529 return skb->len; 1529 return skb->len;
1530 1530
1531 nla_put_failure: 1531 nla_put_failure:
1532 nlmsg_trim(skb, b); 1532 nlmsg_trim(skb, b);
1533 return -1; 1533 return -1;
1534 } 1534 }
1535 1535
1536 #ifdef CONFIG_NET_CLS_ACT 1536 #ifdef CONFIG_NET_CLS_ACT
1537 static __inline__ int cbq_dump_police(struct 1537 static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
1538 { 1538 {
1539 unsigned char *b = skb_tail_pointer(s 1539 unsigned char *b = skb_tail_pointer(skb);
1540 struct tc_cbq_police opt; 1540 struct tc_cbq_police opt;
1541 1541
1542 if (cl->police) { 1542 if (cl->police) {
1543 opt.police = cl->police; 1543 opt.police = cl->police;
1544 opt.__res1 = 0; 1544 opt.__res1 = 0;
1545 opt.__res2 = 0; 1545 opt.__res2 = 0;
1546 NLA_PUT(skb, TCA_CBQ_POLICE, 1546 NLA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
1547 } 1547 }
1548 return skb->len; 1548 return skb->len;
1549 1549
1550 nla_put_failure: 1550 nla_put_failure:
1551 nlmsg_trim(skb, b); 1551 nlmsg_trim(skb, b);
1552 return -1; 1552 return -1;
1553 } 1553 }
1554 #endif 1554 #endif
1555 1555
1556 static int cbq_dump_attr(struct sk_buff *skb, 1556 static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
1557 { 1557 {
1558 if (cbq_dump_lss(skb, cl) < 0 || 1558 if (cbq_dump_lss(skb, cl) < 0 ||
1559 cbq_dump_rate(skb, cl) < 0 || 1559 cbq_dump_rate(skb, cl) < 0 ||
1560 cbq_dump_wrr(skb, cl) < 0 || 1560 cbq_dump_wrr(skb, cl) < 0 ||
1561 cbq_dump_ovl(skb, cl) < 0 || 1561 cbq_dump_ovl(skb, cl) < 0 ||
1562 #ifdef CONFIG_NET_CLS_ACT 1562 #ifdef CONFIG_NET_CLS_ACT
1563 cbq_dump_police(skb, cl) < 0 || 1563 cbq_dump_police(skb, cl) < 0 ||
1564 #endif 1564 #endif
1565 cbq_dump_fopt(skb, cl) < 0) 1565 cbq_dump_fopt(skb, cl) < 0)
1566 return -1; 1566 return -1;
1567 return 0; 1567 return 0;
1568 } 1568 }
1569 1569
1570 static int cbq_dump(struct Qdisc *sch, struct 1570 static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
1571 { 1571 {
1572 struct cbq_sched_data *q = qdisc_priv 1572 struct cbq_sched_data *q = qdisc_priv(sch);
1573 struct nlattr *nest; 1573 struct nlattr *nest;
1574 1574
1575 nest = nla_nest_start(skb, TCA_OPTION 1575 nest = nla_nest_start(skb, TCA_OPTIONS);
1576 if (nest == NULL) 1576 if (nest == NULL)
1577 goto nla_put_failure; 1577 goto nla_put_failure;
1578 if (cbq_dump_attr(skb, &q->link) < 0) 1578 if (cbq_dump_attr(skb, &q->link) < 0)
1579 goto nla_put_failure; 1579 goto nla_put_failure;
1580 nla_nest_end(skb, nest); 1580 nla_nest_end(skb, nest);
1581 return skb->len; 1581 return skb->len;
1582 1582
1583 nla_put_failure: 1583 nla_put_failure:
1584 nla_nest_cancel(skb, nest); 1584 nla_nest_cancel(skb, nest);
1585 return -1; 1585 return -1;
1586 } 1586 }
1587 1587
1588 static int 1588 static int
1589 cbq_dump_stats(struct Qdisc *sch, struct gnet 1589 cbq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
1590 { 1590 {
1591 struct cbq_sched_data *q = qdisc_priv 1591 struct cbq_sched_data *q = qdisc_priv(sch);
1592 1592
1593 q->link.xstats.avgidle = q->link.avgi 1593 q->link.xstats.avgidle = q->link.avgidle;
1594 return gnet_stats_copy_app(d, &q->lin 1594 return gnet_stats_copy_app(d, &q->link.xstats, sizeof(q->link.xstats));
1595 } 1595 }
1596 1596
1597 static int 1597 static int
1598 cbq_dump_class(struct Qdisc *sch, unsigned lo 1598 cbq_dump_class(struct Qdisc *sch, unsigned long arg,
1599 struct sk_buff *skb, struct tc 1599 struct sk_buff *skb, struct tcmsg *tcm)
1600 { 1600 {
1601 struct cbq_class *cl = (struct cbq_cl 1601 struct cbq_class *cl = (struct cbq_class*)arg;
1602 struct nlattr *nest; 1602 struct nlattr *nest;
1603 1603
1604 if (cl->tparent) 1604 if (cl->tparent)
1605 tcm->tcm_parent = cl->tparent 1605 tcm->tcm_parent = cl->tparent->classid;
1606 else 1606 else
1607 tcm->tcm_parent = TC_H_ROOT; 1607 tcm->tcm_parent = TC_H_ROOT;
1608 tcm->tcm_handle = cl->classid; 1608 tcm->tcm_handle = cl->classid;
1609 tcm->tcm_info = cl->q->handle; 1609 tcm->tcm_info = cl->q->handle;
1610 1610
1611 nest = nla_nest_start(skb, TCA_OPTION 1611 nest = nla_nest_start(skb, TCA_OPTIONS);
1612 if (nest == NULL) 1612 if (nest == NULL)
1613 goto nla_put_failure; 1613 goto nla_put_failure;
1614 if (cbq_dump_attr(skb, cl) < 0) 1614 if (cbq_dump_attr(skb, cl) < 0)
1615 goto nla_put_failure; 1615 goto nla_put_failure;
1616 nla_nest_end(skb, nest); 1616 nla_nest_end(skb, nest);
1617 return skb->len; 1617 return skb->len;
1618 1618
1619 nla_put_failure: 1619 nla_put_failure:
1620 nla_nest_cancel(skb, nest); 1620 nla_nest_cancel(skb, nest);
1621 return -1; 1621 return -1;
1622 } 1622 }
1623 1623
1624 static int 1624 static int
1625 cbq_dump_class_stats(struct Qdisc *sch, unsig 1625 cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
1626 struct gnet_dump *d) 1626 struct gnet_dump *d)
1627 { 1627 {
1628 struct cbq_sched_data *q = qdisc_priv 1628 struct cbq_sched_data *q = qdisc_priv(sch);
1629 struct cbq_class *cl = (struct cbq_cl 1629 struct cbq_class *cl = (struct cbq_class*)arg;
1630 1630
1631 cl->qstats.qlen = cl->q->q.qlen; 1631 cl->qstats.qlen = cl->q->q.qlen;
1632 cl->xstats.avgidle = cl->avgidle; 1632 cl->xstats.avgidle = cl->avgidle;
1633 cl->xstats.undertime = 0; 1633 cl->xstats.undertime = 0;
1634 1634
1635 if (cl->undertime != PSCHED_PASTPERFE 1635 if (cl->undertime != PSCHED_PASTPERFECT)
1636 cl->xstats.undertime = cl->un 1636 cl->xstats.undertime = cl->undertime - q->now;
1637 1637
1638 if (gnet_stats_copy_basic(d, &cl->bst 1638 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
1639 gnet_stats_copy_rate_est(d, &cl-> 1639 gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
1640 gnet_stats_copy_queue(d, &cl->qst 1640 gnet_stats_copy_queue(d, &cl->qstats) < 0)
1641 return -1; 1641 return -1;
1642 1642
1643 return gnet_stats_copy_app(d, &cl->xs 1643 return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
1644 } 1644 }
1645 1645
1646 static int cbq_graft(struct Qdisc *sch, unsig 1646 static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1647 struct Qdisc **old) 1647 struct Qdisc **old)
1648 { 1648 {
1649 struct cbq_class *cl = (struct cbq_cl 1649 struct cbq_class *cl = (struct cbq_class*)arg;
1650 1650
1651 if (cl) { 1651 if (cl) {
1652 if (new == NULL) { 1652 if (new == NULL) {
1653 if ((new = qdisc_crea 1653 if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1654 1654 cl->classid)) == NULL)
1655 return -ENOBU 1655 return -ENOBUFS;
1656 } else { 1656 } else {
1657 #ifdef CONFIG_NET_CLS_ACT 1657 #ifdef CONFIG_NET_CLS_ACT
1658 if (cl->police == TC_ 1658 if (cl->police == TC_POLICE_RECLASSIFY)
1659 new->reshape_ 1659 new->reshape_fail = cbq_reshape_fail;
1660 #endif 1660 #endif
1661 } 1661 }
1662 sch_tree_lock(sch); 1662 sch_tree_lock(sch);
1663 *old = xchg(&cl->q, new); 1663 *old = xchg(&cl->q, new);
1664 qdisc_tree_decrease_qlen(*old 1664 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1665 qdisc_reset(*old); 1665 qdisc_reset(*old);
1666 sch_tree_unlock(sch); 1666 sch_tree_unlock(sch);
1667 1667
1668 return 0; 1668 return 0;
1669 } 1669 }
1670 return -ENOENT; 1670 return -ENOENT;
1671 } 1671 }
1672 1672
1673 static struct Qdisc * 1673 static struct Qdisc *
1674 cbq_leaf(struct Qdisc *sch, unsigned long arg 1674 cbq_leaf(struct Qdisc *sch, unsigned long arg)
1675 { 1675 {
1676 struct cbq_class *cl = (struct cbq_cl 1676 struct cbq_class *cl = (struct cbq_class*)arg;
1677 1677
1678 return cl ? cl->q : NULL; 1678 return cl ? cl->q : NULL;
1679 } 1679 }
1680 1680
1681 static void cbq_qlen_notify(struct Qdisc *sch 1681 static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg)
1682 { 1682 {
1683 struct cbq_class *cl = (struct cbq_cl 1683 struct cbq_class *cl = (struct cbq_class *)arg;
1684 1684
1685 if (cl->q->q.qlen == 0) 1685 if (cl->q->q.qlen == 0)
1686 cbq_deactivate_class(cl); 1686 cbq_deactivate_class(cl);
1687 } 1687 }
1688 1688
1689 static unsigned long cbq_get(struct Qdisc *sc 1689 static unsigned long cbq_get(struct Qdisc *sch, u32 classid)
1690 { 1690 {
1691 struct cbq_sched_data *q = qdisc_priv 1691 struct cbq_sched_data *q = qdisc_priv(sch);
1692 struct cbq_class *cl = cbq_class_look 1692 struct cbq_class *cl = cbq_class_lookup(q, classid);
1693 1693
1694 if (cl) { 1694 if (cl) {
1695 cl->refcnt++; 1695 cl->refcnt++;
1696 return (unsigned long)cl; 1696 return (unsigned long)cl;
1697 } 1697 }
1698 return 0; 1698 return 0;
1699 } 1699 }
1700 1700
1701 static void cbq_destroy_class(struct Qdisc *s 1701 static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
1702 { 1702 {
1703 struct cbq_sched_data *q = qdisc_priv 1703 struct cbq_sched_data *q = qdisc_priv(sch);
1704 1704
1705 BUG_TRAP(!cl->filters); 1705 BUG_TRAP(!cl->filters);
1706 1706
1707 tcf_destroy_chain(cl->filter_list); 1707 tcf_destroy_chain(cl->filter_list);
1708 qdisc_destroy(cl->q); 1708 qdisc_destroy(cl->q);
1709 qdisc_put_rtab(cl->R_tab); 1709 qdisc_put_rtab(cl->R_tab);
1710 gen_kill_estimator(&cl->bstats, &cl-> 1710 gen_kill_estimator(&cl->bstats, &cl->rate_est);
1711 if (cl != &q->link) 1711 if (cl != &q->link)
1712 kfree(cl); 1712 kfree(cl);
1713 } 1713 }
1714 1714
1715 static void 1715 static void
1716 cbq_destroy(struct Qdisc* sch) 1716 cbq_destroy(struct Qdisc* sch)
1717 { 1717 {
1718 struct cbq_sched_data *q = qdisc_priv 1718 struct cbq_sched_data *q = qdisc_priv(sch);
1719 struct cbq_class *cl; 1719 struct cbq_class *cl;
1720 unsigned h; 1720 unsigned h;
1721 1721
1722 #ifdef CONFIG_NET_CLS_ACT 1722 #ifdef CONFIG_NET_CLS_ACT
1723 q->rx_class = NULL; 1723 q->rx_class = NULL;
1724 #endif 1724 #endif
1725 /* 1725 /*
1726 * Filters must be destroyed first be 1726 * Filters must be destroyed first because we don't destroy the
1727 * classes from root to leafs which m 1727 * classes from root to leafs which means that filters can still
1728 * be bound to classes which have bee 1728 * be bound to classes which have been destroyed already. --TGR '04
1729 */ 1729 */
1730 for (h = 0; h < 16; h++) { 1730 for (h = 0; h < 16; h++) {
1731 for (cl = q->classes[h]; cl; 1731 for (cl = q->classes[h]; cl; cl = cl->next) {
1732 tcf_destroy_chain(cl- 1732 tcf_destroy_chain(cl->filter_list);
1733 cl->filter_list = NUL 1733 cl->filter_list = NULL;
1734 } 1734 }
1735 } 1735 }
1736 for (h = 0; h < 16; h++) { 1736 for (h = 0; h < 16; h++) {
1737 struct cbq_class *next; 1737 struct cbq_class *next;
1738 1738
1739 for (cl = q->classes[h]; cl; 1739 for (cl = q->classes[h]; cl; cl = next) {
1740 next = cl->next; 1740 next = cl->next;
1741 cbq_destroy_class(sch 1741 cbq_destroy_class(sch, cl);
1742 } 1742 }
1743 } 1743 }
1744 } 1744 }
1745 1745
1746 static void cbq_put(struct Qdisc *sch, unsign 1746 static void cbq_put(struct Qdisc *sch, unsigned long arg)
1747 { 1747 {
1748 struct cbq_class *cl = (struct cbq_cl 1748 struct cbq_class *cl = (struct cbq_class*)arg;
1749 1749
1750 if (--cl->refcnt == 0) { 1750 if (--cl->refcnt == 0) {
1751 #ifdef CONFIG_NET_CLS_ACT 1751 #ifdef CONFIG_NET_CLS_ACT
1752 struct cbq_sched_data *q = qd 1752 struct cbq_sched_data *q = qdisc_priv(sch);
1753 1753
1754 spin_lock_bh(&sch->dev->queue 1754 spin_lock_bh(&sch->dev->queue_lock);
1755 if (q->rx_class == cl) 1755 if (q->rx_class == cl)
1756 q->rx_class = NULL; 1756 q->rx_class = NULL;
1757 spin_unlock_bh(&sch->dev->que 1757 spin_unlock_bh(&sch->dev->queue_lock);
1758 #endif 1758 #endif
1759 1759
1760 cbq_destroy_class(sch, cl); 1760 cbq_destroy_class(sch, cl);
1761 } 1761 }
1762 } 1762 }
1763 1763
1764 static int 1764 static int
1765 cbq_change_class(struct Qdisc *sch, u32 class 1765 cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca,
1766 unsigned long *arg) 1766 unsigned long *arg)
1767 { 1767 {
1768 int err; 1768 int err;
1769 struct cbq_sched_data *q = qdisc_priv 1769 struct cbq_sched_data *q = qdisc_priv(sch);
1770 struct cbq_class *cl = (struct cbq_cl 1770 struct cbq_class *cl = (struct cbq_class*)*arg;
1771 struct nlattr *opt = tca[TCA_OPTIONS] 1771 struct nlattr *opt = tca[TCA_OPTIONS];
1772 struct nlattr *tb[TCA_CBQ_MAX + 1]; 1772 struct nlattr *tb[TCA_CBQ_MAX + 1];
1773 struct cbq_class *parent; 1773 struct cbq_class *parent;
1774 struct qdisc_rate_table *rtab = NULL; 1774 struct qdisc_rate_table *rtab = NULL;
1775 1775
1776 if (opt == NULL) 1776 if (opt == NULL)
1777 return -EINVAL; 1777 return -EINVAL;
1778 1778
1779 err = nla_parse_nested(tb, TCA_CBQ_MA 1779 err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
1780 if (err < 0) 1780 if (err < 0)
1781 return err; 1781 return err;
1782 1782
1783 if (cl) { 1783 if (cl) {
1784 /* Check parent */ 1784 /* Check parent */
1785 if (parentid) { 1785 if (parentid) {
1786 if (cl->tparent && cl 1786 if (cl->tparent && cl->tparent->classid != parentid)
1787 return -EINVA 1787 return -EINVAL;
1788 if (!cl->tparent && p 1788 if (!cl->tparent && parentid != TC_H_ROOT)
1789 return -EINVA 1789 return -EINVAL;
1790 } 1790 }
1791 1791
1792 if (tb[TCA_CBQ_RATE]) { 1792 if (tb[TCA_CBQ_RATE]) {
1793 rtab = qdisc_get_rtab 1793 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
1794 if (rtab == NULL) 1794 if (rtab == NULL)
1795 return -EINVA 1795 return -EINVAL;
1796 } 1796 }
1797 1797
1798 /* Change class parameters */ 1798 /* Change class parameters */
1799 sch_tree_lock(sch); 1799 sch_tree_lock(sch);
1800 1800
1801 if (cl->next_alive != NULL) 1801 if (cl->next_alive != NULL)
1802 cbq_deactivate_class( 1802 cbq_deactivate_class(cl);
1803 1803
1804 if (rtab) { 1804 if (rtab) {
1805 rtab = xchg(&cl->R_ta 1805 rtab = xchg(&cl->R_tab, rtab);
1806 qdisc_put_rtab(rtab); 1806 qdisc_put_rtab(rtab);
1807 } 1807 }
1808 1808
1809 if (tb[TCA_CBQ_LSSOPT]) 1809 if (tb[TCA_CBQ_LSSOPT])
1810 cbq_set_lss(cl, nla_d 1810 cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
1811 1811
1812 if (tb[TCA_CBQ_WRROPT]) { 1812 if (tb[TCA_CBQ_WRROPT]) {
1813 cbq_rmprio(q, cl); 1813 cbq_rmprio(q, cl);
1814 cbq_set_wrr(cl, nla_d 1814 cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
1815 } 1815 }
1816 1816
1817 if (tb[TCA_CBQ_OVL_STRATEGY]) 1817 if (tb[TCA_CBQ_OVL_STRATEGY])
1818 cbq_set_overlimit(cl, 1818 cbq_set_overlimit(cl, nla_data(tb[TCA_CBQ_OVL_STRATEGY]));
1819 1819
1820 #ifdef CONFIG_NET_CLS_ACT 1820 #ifdef CONFIG_NET_CLS_ACT
1821 if (tb[TCA_CBQ_POLICE]) 1821 if (tb[TCA_CBQ_POLICE])
1822 cbq_set_police(cl, nl 1822 cbq_set_police(cl, nla_data(tb[TCA_CBQ_POLICE]));
1823 #endif 1823 #endif
1824 1824
1825 if (tb[TCA_CBQ_FOPT]) 1825 if (tb[TCA_CBQ_FOPT])
1826 cbq_set_fopt(cl, nla_ 1826 cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
1827 1827
1828 if (cl->q->q.qlen) 1828 if (cl->q->q.qlen)
1829 cbq_activate_class(cl 1829 cbq_activate_class(cl);
1830 1830
1831 sch_tree_unlock(sch); 1831 sch_tree_unlock(sch);
1832 1832
1833 if (tca[TCA_RATE]) 1833 if (tca[TCA_RATE])
1834 gen_replace_estimator 1834 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1835 1835 &sch->dev->queue_lock,
1836 1836 tca[TCA_RATE]);
1837 return 0; 1837 return 0;
1838 } 1838 }
1839 1839
1840 if (parentid == TC_H_ROOT) 1840 if (parentid == TC_H_ROOT)
1841 return -EINVAL; 1841 return -EINVAL;
1842 1842
1843 if (tb[TCA_CBQ_WRROPT] == NULL || tb[ 1843 if (tb[TCA_CBQ_WRROPT] == NULL || tb[TCA_CBQ_RATE] == NULL ||
1844 tb[TCA_CBQ_LSSOPT] == NULL) 1844 tb[TCA_CBQ_LSSOPT] == NULL)
1845 return -EINVAL; 1845 return -EINVAL;
1846 1846
1847 rtab = qdisc_get_rtab(nla_data(tb[TCA 1847 rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
1848 if (rtab == NULL) 1848 if (rtab == NULL)
1849 return -EINVAL; 1849 return -EINVAL;
1850 1850
1851 if (classid) { 1851 if (classid) {
1852 err = -EINVAL; 1852 err = -EINVAL;
1853 if (TC_H_MAJ(classid^sch->han 1853 if (TC_H_MAJ(classid^sch->handle) || cbq_class_lookup(q, classid))
1854 goto failure; 1854 goto failure;
1855 } else { 1855 } else {
1856 int i; 1856 int i;
1857 classid = TC_H_MAKE(sch->hand 1857 classid = TC_H_MAKE(sch->handle,0x8000);
1858 1858
1859 for (i=0; i<0x8000; i++) { 1859 for (i=0; i<0x8000; i++) {
1860 if (++q->hgenerator > 1860 if (++q->hgenerator >= 0x8000)
1861 q->hgenerator 1861 q->hgenerator = 1;
1862 if (cbq_class_lookup( 1862 if (cbq_class_lookup(q, classid|q->hgenerator) == NULL)
1863 break; 1863 break;
1864 } 1864 }
1865 err = -ENOSR; 1865 err = -ENOSR;
1866 if (i >= 0x8000) 1866 if (i >= 0x8000)
1867 goto failure; 1867 goto failure;
1868 classid = classid|q->hgenerat 1868 classid = classid|q->hgenerator;
1869 } 1869 }
1870 1870
1871 parent = &q->link; 1871 parent = &q->link;
1872 if (parentid) { 1872 if (parentid) {
1873 parent = cbq_class_lookup(q, 1873 parent = cbq_class_lookup(q, parentid);
1874 err = -EINVAL; 1874 err = -EINVAL;
1875 if (parent == NULL) 1875 if (parent == NULL)
1876 goto failure; 1876 goto failure;
1877 } 1877 }
1878 1878
1879 err = -ENOBUFS; 1879 err = -ENOBUFS;
1880 cl = kzalloc(sizeof(*cl), GFP_KERNEL) 1880 cl = kzalloc(sizeof(*cl), GFP_KERNEL);
1881 if (cl == NULL) 1881 if (cl == NULL)
1882 goto failure; 1882 goto failure;
1883 cl->R_tab = rtab; 1883 cl->R_tab = rtab;
1884 rtab = NULL; 1884 rtab = NULL;
1885 cl->refcnt = 1; 1885 cl->refcnt = 1;
1886 if (!(cl->q = qdisc_create_dflt(sch-> 1886 if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid)))
1887 cl->q = &noop_qdisc; 1887 cl->q = &noop_qdisc;
1888 cl->classid = classid; 1888 cl->classid = classid;
1889 cl->tparent = parent; 1889 cl->tparent = parent;
1890 cl->qdisc = sch; 1890 cl->qdisc = sch;
1891 cl->allot = parent->allot; 1891 cl->allot = parent->allot;
1892 cl->quantum = cl->allot; 1892 cl->quantum = cl->allot;
1893 cl->weight = cl->R_tab->rate.rate; 1893 cl->weight = cl->R_tab->rate.rate;
1894 1894
1895 sch_tree_lock(sch); 1895 sch_tree_lock(sch);
1896 cbq_link_class(cl); 1896 cbq_link_class(cl);
1897 cl->borrow = cl->tparent; 1897 cl->borrow = cl->tparent;
1898 if (cl->tparent != &q->link) 1898 if (cl->tparent != &q->link)
1899 cl->share = cl->tparent; 1899 cl->share = cl->tparent;
1900 cbq_adjust_levels(parent); 1900 cbq_adjust_levels(parent);
1901 cl->minidle = -0x7FFFFFFF; 1901 cl->minidle = -0x7FFFFFFF;
1902 cbq_set_lss(cl, nla_data(tb[TCA_CBQ_L 1902 cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
1903 cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_W 1903 cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
1904 if (cl->ewma_log==0) 1904 if (cl->ewma_log==0)
1905 cl->ewma_log = q->link.ewma_l 1905 cl->ewma_log = q->link.ewma_log;
1906 if (cl->maxidle==0) 1906 if (cl->maxidle==0)
1907 cl->maxidle = q->link.maxidle 1907 cl->maxidle = q->link.maxidle;
1908 if (cl->avpkt==0) 1908 if (cl->avpkt==0)
1909 cl->avpkt = q->link.avpkt; 1909 cl->avpkt = q->link.avpkt;
1910 cl->overlimit = cbq_ovl_classic; 1910 cl->overlimit = cbq_ovl_classic;
1911 if (tb[TCA_CBQ_OVL_STRATEGY]) 1911 if (tb[TCA_CBQ_OVL_STRATEGY])
1912 cbq_set_overlimit(cl, nla_dat 1912 cbq_set_overlimit(cl, nla_data(tb[TCA_CBQ_OVL_STRATEGY]));
1913 #ifdef CONFIG_NET_CLS_ACT 1913 #ifdef CONFIG_NET_CLS_ACT
1914 if (tb[TCA_CBQ_POLICE]) 1914 if (tb[TCA_CBQ_POLICE])
1915 cbq_set_police(cl, nla_data(t 1915 cbq_set_police(cl, nla_data(tb[TCA_CBQ_POLICE]));
1916 #endif 1916 #endif
1917 if (tb[TCA_CBQ_FOPT]) 1917 if (tb[TCA_CBQ_FOPT])
1918 cbq_set_fopt(cl, nla_data(tb[ 1918 cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
1919 sch_tree_unlock(sch); 1919 sch_tree_unlock(sch);
1920 1920
1921 if (tca[TCA_RATE]) 1921 if (tca[TCA_RATE])
1922 gen_new_estimator(&cl->bstats 1922 gen_new_estimator(&cl->bstats, &cl->rate_est,
1923 &sch->dev-> 1923 &sch->dev->queue_lock, tca[TCA_RATE]);
1924 1924
1925 *arg = (unsigned long)cl; 1925 *arg = (unsigned long)cl;
1926 return 0; 1926 return 0;
1927 1927
1928 failure: 1928 failure:
1929 qdisc_put_rtab(rtab); 1929 qdisc_put_rtab(rtab);
1930 return err; 1930 return err;
1931 } 1931 }
1932 1932
1933 static int cbq_delete(struct Qdisc *sch, unsi 1933 static int cbq_delete(struct Qdisc *sch, unsigned long arg)
1934 { 1934 {
1935 struct cbq_sched_data *q = qdisc_priv 1935 struct cbq_sched_data *q = qdisc_priv(sch);
1936 struct cbq_class *cl = (struct cbq_cl 1936 struct cbq_class *cl = (struct cbq_class*)arg;
1937 unsigned int qlen; 1937 unsigned int qlen;
1938 1938
1939 if (cl->filters || cl->children || cl 1939 if (cl->filters || cl->children || cl == &q->link)
1940 return -EBUSY; 1940 return -EBUSY;
1941 1941
1942 sch_tree_lock(sch); 1942 sch_tree_lock(sch);
1943 1943
1944 qlen = cl->q->q.qlen; 1944 qlen = cl->q->q.qlen;
1945 qdisc_reset(cl->q); 1945 qdisc_reset(cl->q);
1946 qdisc_tree_decrease_qlen(cl->q, qlen) 1946 qdisc_tree_decrease_qlen(cl->q, qlen);
1947 1947
1948 if (cl->next_alive) 1948 if (cl->next_alive)
1949 cbq_deactivate_class(cl); 1949 cbq_deactivate_class(cl);
1950 1950
1951 if (q->tx_borrowed == cl) 1951 if (q->tx_borrowed == cl)
1952 q->tx_borrowed = q->tx_class; 1952 q->tx_borrowed = q->tx_class;
1953 if (q->tx_class == cl) { 1953 if (q->tx_class == cl) {
1954 q->tx_class = NULL; 1954 q->tx_class = NULL;
1955 q->tx_borrowed = NULL; 1955 q->tx_borrowed = NULL;
1956 } 1956 }
1957 #ifdef CONFIG_NET_CLS_ACT 1957 #ifdef CONFIG_NET_CLS_ACT
1958 if (q->rx_class == cl) 1958 if (q->rx_class == cl)
1959 q->rx_class = NULL; 1959 q->rx_class = NULL;
1960 #endif 1960 #endif
1961 1961
1962 cbq_unlink_class(cl); 1962 cbq_unlink_class(cl);
1963 cbq_adjust_levels(cl->tparent); 1963 cbq_adjust_levels(cl->tparent);
1964 cl->defmap = 0; 1964 cl->defmap = 0;
1965 cbq_sync_defmap(cl); 1965 cbq_sync_defmap(cl);
1966 1966
1967 cbq_rmprio(q, cl); 1967 cbq_rmprio(q, cl);
1968 sch_tree_unlock(sch); 1968 sch_tree_unlock(sch);
1969 1969
1970 if (--cl->refcnt == 0) 1970 if (--cl->refcnt == 0)
1971 cbq_destroy_class(sch, cl); 1971 cbq_destroy_class(sch, cl);
1972 1972
1973 return 0; 1973 return 0;
1974 } 1974 }
1975 1975
1976 static struct tcf_proto **cbq_find_tcf(struct 1976 static struct tcf_proto **cbq_find_tcf(struct Qdisc *sch, unsigned long arg)
1977 { 1977 {
1978 struct cbq_sched_data *q = qdisc_priv 1978 struct cbq_sched_data *q = qdisc_priv(sch);
1979 struct cbq_class *cl = (struct cbq_cl 1979 struct cbq_class *cl = (struct cbq_class *)arg;
1980 1980
1981 if (cl == NULL) 1981 if (cl == NULL)
1982 cl = &q->link; 1982 cl = &q->link;
1983 1983
1984 return &cl->filter_list; 1984 return &cl->filter_list;
1985 } 1985 }
1986 1986
1987 static unsigned long cbq_bind_filter(struct Q 1987 static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent,
1988 u32 clas 1988 u32 classid)
1989 { 1989 {
1990 struct cbq_sched_data *q = qdisc_priv 1990 struct cbq_sched_data *q = qdisc_priv(sch);
1991 struct cbq_class *p = (struct cbq_cla 1991 struct cbq_class *p = (struct cbq_class*)parent;
1992 struct cbq_class *cl = cbq_class_look 1992 struct cbq_class *cl = cbq_class_lookup(q, classid);
1993 1993
1994 if (cl) { 1994 if (cl) {
1995 if (p && p->level <= cl->leve 1995 if (p && p->level <= cl->level)
1996 return 0; 1996 return 0;
1997 cl->filters++; 1997 cl->filters++;
1998 return (unsigned long)cl; 1998 return (unsigned long)cl;
1999 } 1999 }
2000 return 0; 2000 return 0;
2001 } 2001 }
2002 2002
2003 static void cbq_unbind_filter(struct Qdisc *s 2003 static void cbq_unbind_filter(struct Qdisc *sch, unsigned long arg)
2004 { 2004 {
2005 struct cbq_class *cl = (struct cbq_cl 2005 struct cbq_class *cl = (struct cbq_class*)arg;
2006 2006
2007 cl->filters--; 2007 cl->filters--;
2008 } 2008 }
2009 2009
2010 static void cbq_walk(struct Qdisc *sch, struc 2010 static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
2011 { 2011 {
2012 struct cbq_sched_data *q = qdisc_priv 2012 struct cbq_sched_data *q = qdisc_priv(sch);
2013 unsigned h; 2013 unsigned h;
2014 2014
2015 if (arg->stop) 2015 if (arg->stop)
2016 return; 2016 return;
2017 2017
2018 for (h = 0; h < 16; h++) { 2018 for (h = 0; h < 16; h++) {
2019 struct cbq_class *cl; 2019 struct cbq_class *cl;
2020 2020
2021 for (cl = q->classes[h]; cl; 2021 for (cl = q->classes[h]; cl; cl = cl->next) {
2022 if (arg->count < arg- 2022 if (arg->count < arg->skip) {
2023 arg->count++; 2023 arg->count++;
2024 continue; 2024 continue;
2025 } 2025 }
2026 if (arg->fn(sch, (uns 2026 if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
2027 arg->stop = 1 2027 arg->stop = 1;
2028 return; 2028 return;
2029 } 2029 }
2030 arg->count++; 2030 arg->count++;
2031 } 2031 }
2032 } 2032 }
2033 } 2033 }
2034 2034
2035 static const struct Qdisc_class_ops cbq_class 2035 static const struct Qdisc_class_ops cbq_class_ops = {
2036 .graft = cbq_graft, 2036 .graft = cbq_graft,
2037 .leaf = cbq_leaf, 2037 .leaf = cbq_leaf,
2038 .qlen_notify = cbq_qlen_noti 2038 .qlen_notify = cbq_qlen_notify,
2039 .get = cbq_get, 2039 .get = cbq_get,
2040 .put = cbq_put, 2040 .put = cbq_put,
2041 .change = cbq_change_cl 2041 .change = cbq_change_class,
2042 .delete = cbq_delete, 2042 .delete = cbq_delete,
2043 .walk = cbq_walk, 2043 .walk = cbq_walk,
2044 .tcf_chain = cbq_find_tcf, 2044 .tcf_chain = cbq_find_tcf,
2045 .bind_tcf = cbq_bind_filt 2045 .bind_tcf = cbq_bind_filter,
2046 .unbind_tcf = cbq_unbind_fi 2046 .unbind_tcf = cbq_unbind_filter,
2047 .dump = cbq_dump_clas 2047 .dump = cbq_dump_class,
2048 .dump_stats = cbq_dump_clas 2048 .dump_stats = cbq_dump_class_stats,
2049 }; 2049 };
2050 2050
2051 static struct Qdisc_ops cbq_qdisc_ops __read_ 2051 static struct Qdisc_ops cbq_qdisc_ops __read_mostly = {
2052 .next = NULL, 2052 .next = NULL,
2053 .cl_ops = &cbq_class_op 2053 .cl_ops = &cbq_class_ops,
2054 .id = "cbq", 2054 .id = "cbq",
2055 .priv_size = sizeof(struct 2055 .priv_size = sizeof(struct cbq_sched_data),
2056 .enqueue = cbq_enqueue, 2056 .enqueue = cbq_enqueue,
2057 .dequeue = cbq_dequeue, 2057 .dequeue = cbq_dequeue,
2058 .requeue = cbq_requeue, 2058 .requeue = cbq_requeue,
2059 .drop = cbq_drop, 2059 .drop = cbq_drop,
2060 .init = cbq_init, 2060 .init = cbq_init,
2061 .reset = cbq_reset, 2061 .reset = cbq_reset,
2062 .destroy = cbq_destroy, 2062 .destroy = cbq_destroy,
2063 .change = NULL, 2063 .change = NULL,
2064 .dump = cbq_dump, 2064 .dump = cbq_dump,
2065 .dump_stats = cbq_dump_stat 2065 .dump_stats = cbq_dump_stats,
2066 .owner = THIS_MODULE, 2066 .owner = THIS_MODULE,
2067 }; 2067 };
2068 2068
2069 static int __init cbq_module_init(void) 2069 static int __init cbq_module_init(void)
2070 { 2070 {
2071 return register_qdisc(&cbq_qdisc_ops) 2071 return register_qdisc(&cbq_qdisc_ops);
2072 } 2072 }
2073 static void __exit cbq_module_exit(void) 2073 static void __exit cbq_module_exit(void)
2074 { 2074 {
2075 unregister_qdisc(&cbq_qdisc_ops); 2075 unregister_qdisc(&cbq_qdisc_ops);
2076 } 2076 }
2077 module_init(cbq_module_init) 2077 module_init(cbq_module_init)
2078 module_exit(cbq_module_exit) 2078 module_exit(cbq_module_exit)
2079 MODULE_LICENSE("GPL"); 2079 MODULE_LICENSE("GPL");
2080 2080
|
This page was automatically generated by the
LXR engine.
|