]> git.pld-linux.org Git - packages/kernel.git/blob - ds9-htb3-2.2.21-2.diff
- added description of djurban's branch
[packages/kernel.git] / ds9-htb3-2.2.21-2.diff
1 diff -urN ../v2.2.21-ds9/linux/Documentation/Configure.help linux/Documentation/Configure.help
2 --- ../v2.2.21-ds9/linux/Documentation/Configure.help   Tue May 21 23:26:01 2002
3 +++ linux/Documentation/Configure.help  Sat Aug 10 10:48:07 2002
4 @@ -6118,6 +6118,20 @@
5    whenever you want). If you want to compile it as a module, say M
6    here and read Documentation/modules.txt.
7  
8 +CONFIG_NET_SCH_HTB
9 +  Say Y here if you want to use the Hierarchical Token Buckets (HTB)
10 +  packet scheduling algorithm for some of your network devices. See
11 +  URL http://luxik.cdi.cz/~devik/qos/htb/ for complete manual and
12 +  in-depth articles.
13 +
14 +  HTB is very similar to the CBQ regarding its goals however is has 
15 +  different properties and different algorithm.
16 +
17 +  This code is also available as a module called sch_htb.o ( = code
18 +  which can be inserted in and removed from the running kernel
19 +  whenever you want).  If you want to compile it as a module, say M
20 +  here and read Documentation/modules.txt.
21 +
22  CSZ packet scheduler
23  CONFIG_NET_SCH_CSZ
24    Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet
25 diff -urN ../v2.2.21-ds9/linux/include/linux/pkt_sched.h linux/include/linux/pkt_sched.h
26 --- ../v2.2.21-ds9/linux/include/linux/pkt_sched.h      Sun Aug  4 14:54:40 2002
27 +++ linux/include/linux/pkt_sched.h     Sat Aug 10 10:31:11 2002
28 @@ -246,6 +246,48 @@
29  };
30  
31  
32 +/* HTB section */
33 +#define TC_HTB_NUMPRIO         8
34 +#define TC_HTB_MAXDEPTH                8
35 +#define TC_HTB_PROTOVER                3 /* the same as HTB and TC's major */
36 +
37 +struct tc_htb_opt
38 +{
39 +       struct tc_ratespec      rate;
40 +       struct tc_ratespec      ceil;
41 +       __u32   buffer;
42 +       __u32   cbuffer;
43 +       __u32   quantum;
44 +       __u32   level;          /* out only */
45 +       __u32   prio;
46 +};
47 +struct tc_htb_glob
48 +{
49 +       __u32 version;          /* to match HTB/TC */
50 +       __u32 rate2quantum;     /* bps->quantum divisor */
51 +       __u32 defcls;           /* default class number */
52 +       __u32 debug;            /* debug flags */
53 +
54 +       /* stats */
55 +       __u32 direct_pkts; /* count of non shapped packets */
56 +};
57 +enum
58 +{
59 +       TCA_HTB_UNSPEC,
60 +       TCA_HTB_PARMS,
61 +       TCA_HTB_INIT,
62 +       TCA_HTB_CTAB,
63 +       TCA_HTB_RTAB,
64 +};
65 +struct tc_htb_xstats
66 +{
67 +       __u32 lends;
68 +       __u32 borrows;
69 +       __u32 giants;   /* too big packets (rate will not be accurate) */
70 +       __u32 tokens;
71 +       __u32 ctokens;
72 +};
73 +
74  /* CBQ section */
75  
76  #define TC_CBQ_MAXPRIO         8
77 diff -urN ../v2.2.21-ds9/linux/net/sched/Config.in linux/net/sched/Config.in
78 --- ../v2.2.21-ds9/linux/net/sched/Config.in    Wed Jul 31 00:00:59 2002
79 +++ linux/net/sched/Config.in   Sat Aug 10 10:31:11 2002
80 @@ -4,6 +4,7 @@
81  define_bool CONFIG_NETLINK y
82  define_bool CONFIG_RTNETLINK y 
83  tristate 'CBQ packet scheduler' CONFIG_NET_SCH_CBQ
84 +tristate 'HTB packet scheduler' CONFIG_NET_SCH_HTB
85  tristate 'CSZ packet scheduler' CONFIG_NET_SCH_CSZ
86  #tristate 'H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ
87  #tristate 'H-FSC packet scheduler' CONFIG_NET_SCH_HFCS
88 diff -urN ../v2.2.21-ds9/linux/net/sched/Makefile linux/net/sched/Makefile
89 --- ../v2.2.21-ds9/linux/net/sched/Makefile     Wed Jul 31 00:00:59 2002
90 +++ linux/net/sched/Makefile    Sat Aug 10 10:31:11 2002
91 @@ -68,6 +68,14 @@
92    endif
93  endif
94  
95 +ifeq ($(CONFIG_NET_SCH_HTB), y)
96 +O_OBJS += sch_htb.o
97 +else
98 +  ifeq ($(CONFIG_NET_SCH_HTB), m)
99 +       M_OBJS += sch_htb.o
100 +  endif
101 +endif
102 +
103  
104  ifeq ($(CONFIG_NET_SCH_SFQ), y)
105  O_OBJS += sch_sfq.o
106 diff -urN ../v2.2.21-ds9/linux/net/sched/sch_htb.c linux/net/sched/sch_htb.c
107 --- ../v2.2.21-ds9/linux/net/sched/sch_htb.c    Thu Jan  1 00:00:00 1970
108 +++ linux/net/sched/sch_htb.c   Thu Oct 24 00:45:35 2002
109 @@ -1,5 +1,5 @@
110 -/* vim: ts=8 sw=4
111 - * net/sched/sch_htb.c Hierarchical token bucket
112 +/* vim: ts=8 sw=8
113 + * net/sched/sch_htb.c Hierarchical token bucket, feed tree version
114   *
115   *             This program is free software; you can redistribute it and/or
116   *             modify it under the terms of the GNU General Public License
117 @@ -8,18 +8,19 @@
118   *
119   * Authors:    Martin Devera, <devik@cdi.cz>
120   *
121 - * Credits (in time order):    
122 + * Credits (in time order) for older HTB versions:
123   *             Ondrej Kraus, <krauso@barr.cz> 
124   *                     found missing INIT_QDISC(htb)
125   *             Vladimir Smelhaus, Aamer Akhter, Bert Hubert
126   *                     helped a lot to locate nasty class stall bug
127   *             Andi Kleen, Jamal Hadi, Bert Hubert
128   *                     code review and helpful comments on shaping
129 + *             Tomasz Wrona, <tw@eter.tym.pl>
130 + *                     created test case so that I was able to fix nasty bug
131   *             and many others. thanks.
132   *
133 - * $Id$
134 + * $Id$
135   */
136 -
137  #include <linux/config.h>
138  #include <linux/module.h>
139  #include <asm/uaccess.h>
140 @@ -44,15 +45,17 @@
141  #include <net/ip.h>
142  #include <net/route.h>
143  #include <linux/skbuff.h>
144 +#include <linux/list.h>
145  #include <net/sock.h>
146  #include <net/pkt_sched.h>
147 +#include <linux/rbtree.h>
148  
149  /* HTB algorithm.
150      Author: devik@cdi.cz
151 -    =======================================
152 +    ========================================================================
153      HTB is like TBF with multiple classes. It is also similar to CBQ because
154      it allows to assign priority to each class in hierarchy. 
155 -    In fact it is another implementation os Floyd's formal sharing.
156 +    In fact it is another implementation of Floyd's formal sharing.
157  
158      Levels:
159      Each class is assigned level. Leaf has ALWAYS level 0 and root 
160 @@ -63,37 +66,19 @@
161  #define HTB_HSIZE 16   /* classid hash size */
162  #define HTB_EWMAC 2    /* rate average over HTB_EWMAC*HTB_HSIZE sec */
163  #define HTB_DEBUG 1    /* compile debugging support (activated by tc tool) */
164 -#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
165 -#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
166 -
167 -/* ======== Begin of part to be deleted for 2.4 merged one ========= */
168 -#if LINUX_VERSION_CODE < 0x20300
169 -#define MODULE_LICENSE(X)
170 -
171 -#define NET_XMIT_SUCCESS 1
172 -#define NET_XMIT_DROP 0
173 -
174 -static inline void __skb_queue_purge(struct sk_buff_head *list)
175 -{
176 -        struct sk_buff *skb;
177 -       while ((skb=__skb_dequeue(list))!=NULL)
178 -           kfree_skb(skb);
179 -}
180 -#define del_timer_sync(t) del_timer(t)
181 +#define HTB_RATECM 1    /* whether to use rate computer */
182 +#define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
183 +#define HTB_QLOCK(S) sch_dev_queue_lock((S)->dev)
184 +#define HTB_QUNLOCK(S) sch_dev_queue_unlock((S)->dev)
185 +#define HTB_VER 0x30007        /* major must be matched with number suplied by TC as version */
186  
187 -#define netif_schedule qdisc_wakeup
188 -#define netif_queue_stopped(D) (D->tbusy)
189 -#define sch_tree_lock(S) start_bh_atomic()
190 -#define sch_tree_unlock(S) end_bh_atomic()
191 -#undef HTB_QLOCK
192 -#undef HTB_QUNLOCK
193 -#define HTB_QLOCK(S) 
194 -#define HTB_QUNLOCK(S) 
195 -#ifndef BUG_TRAP
196 -#define BUG_TRAP(x) if (!(x)) { printk("Assertion (" #x ") failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); }
197 +#if HTB_VER >> 16 != TC_HTB_PROTOVER
198 +#error "Mismatched sch_htb.c and pkt_sch.h"
199  #endif
200 -#endif
201 -/* ======== End of part to be deleted for 2.4 merged one =========== */
202 +
203 +/* temporary debug defines to be removed after beta stage */
204 +#define DEVIK_MEND(N)
205 +#define DEVIK_MSTART(N)
206  
207  /* debugging support; S is subsystem, these are defined:
208    0 - netlink messages
209 @@ -102,7 +87,9 @@
210    3 - dequeue main
211    4 - dequeue one prio DRR part
212    5 - dequeue class accounting
213 -  6 - dequeue rcache (ready level computation)
214 +  6 - class overlimit status computation
215 +  7 - hint tree
216 +  8 - event queue
217   10 - rate estimator
218   11 - classifier 
219   12 - fast dequeue cache
220 @@ -111,80 +98,88 @@
221   q->debug uint32 contains 16 2-bit fields one for subsystem starting
222   from LSB
223   */
224 -#if HTB_DEBUG
225 +#ifdef HTB_DEBUG
226  #define HTB_DBG(S,L,FMT,ARG...) if (((q->debug>>(2*S))&3) >= L) \
227         printk(KERN_DEBUG FMT,##ARG)
228 +#define HTB_CHCL(cl) BUG_TRAP((cl)->magic == HTB_CMAGIC)
229 +#define HTB_PASSQ q,
230 +#define HTB_ARGQ struct htb_sched *q,
231 +#define static
232 +#define __inline__
233 +#define inline
234 +#define HTB_CMAGIC 0xFEFAFEF1
235 +#define htb_safe_rb_erase(N,R) do { BUG_TRAP((N)->rb_color != -1); \
236 +               if ((N)->rb_color == -1) break; \
237 +               rb_erase(N,R); \
238 +               (N)->rb_color = -1; } while (0)
239  #else
240  #define HTB_DBG(S,L,FMT,ARG...)
241 +#define HTB_PASSQ
242 +#define HTB_ARGQ
243 +#define HTB_CHCL(cl)
244 +#define htb_safe_rb_erase(N,R) rb_erase(N,R)
245  #endif
246  
247  
248 -/* used internaly to pass status of single class */
249 +/* used internaly to keep status of single class */
250  enum htb_cmode {
251      HTB_CANT_SEND,             /* class can't send and can't borrow */
252      HTB_MAY_BORROW,            /* class can't send but may borrow */
253      HTB_CAN_SEND               /* class can send */
254  };
255 -#define HTB_F_INJ 0x10000      /* to mark dequeue level as injected one */
256 -
257 -/* often used circular list of classes; I didn't use generic linux 
258 -   double linked list to avoid casts and before I rely on some behaviour
259 -   of insert and delete functions; item not bound to list is guaranted
260 -   to have prev member NULL (we don't mangle next pointer as we often
261 -   need it */
262 -struct htb_litem {
263 -    struct htb_class *prev, *next;
264 -};
265 -/* circular list insert and delete macros; these also maintain
266 -   correct value of pointer to the list; insert adds 'new' class 
267 -   before 'cl' class using prev/next member 'list' */
268 -#define HTB_INSERTB(list,cl,new) \
269 -do { if (!cl) new->list.prev = cl = new; \
270 -    new->list.next = cl; new->list.prev = cl->list.prev; \
271 -    cl->list.prev->list.next = cl->list.prev = new; } while(0)
272 -    
273 -/* remove 'cl' class from 'list' repairing 'ptr' if not null */
274 -#define HTB_DELETE(list,cl,ptr) do { \
275 -    if (cl->list.prev) { cl->list.prev->list.next = cl->list.next; \
276 -    cl->list.next->list.prev = cl->list.prev; \
277 -    if (ptr == cl) ptr = cl->list.next; \
278 -    if (ptr == cl) ptr = NULL; cl->list.prev = NULL; } \
279 -    else printk(KERN_ERR "htb: DELETE BUG [" #list "," #cl "," #ptr "]\n"); \
280 -    } while (0)
281  
282  /* interior & leaf nodes; props specific to leaves are marked L: */
283  struct htb_class
284  {
285 +#ifdef HTB_DEBUG
286 +       unsigned magic;
287 +#endif
288      /* general class parameters */
289      u32 classid;
290      struct tc_stats    stats;  /* generic stats */
291      struct tc_htb_xstats xstats;/* our special stats */
292      int refcnt;                        /* usage count of this class */
293 -    struct Qdisc *q;           /* L: elem. qdisc */
294  
295 +#ifdef HTB_RATECM
296      /* rate measurement counters */
297      unsigned long rate_bytes,sum_bytes;
298      unsigned long rate_packets,sum_packets;
299 +#endif
300  
301 -    /* DRR scheduler parameters */
302 -    int quantum;       /* L: round quantum computed from rate */
303 -    int deficit[TC_HTB_MAXDEPTH]; /* L: deficit for class at level */
304 -    char prio;         /* L: priority of the class; 0 is the highest */
305 -    char aprio;                /* L: prio at which we were last adding to active list
306 -                          it is used to change priority at runtime */
307      /* topology */
308 -    char level;                        /* our level (see above) */
309 -    char injectd;              /* distance from injected parent */
310 +    int level;                 /* our level (see above) */
311      struct htb_class *parent;  /* parent class */
312 -    struct htb_class *children;        /* pointer to children list */
313 -    struct htb_litem hlist;    /* classid hash list */
314 -    struct htb_litem active;   /* L: prio level active DRR list */
315 -    struct htb_litem sibling;  /* sibling list */
316 +    struct list_head hlist;    /* classid hash list item */
317 +    struct list_head sibling;  /* sibling list item */
318 +    struct list_head children; /* children list */
319 +
320 +    union {
321 +           struct htb_class_leaf {
322 +                   struct Qdisc *q;
323 +                   int prio;
324 +                   int aprio;  
325 +                   int quantum;
326 +                   int deficit[TC_HTB_MAXDEPTH];
327 +                   struct list_head drop_list;
328 +           } leaf;
329 +           struct htb_class_inner {
330 +                   rb_root_t feed[TC_HTB_NUMPRIO];     /* feed trees */
331 +                   rb_node_t *ptr[TC_HTB_NUMPRIO];     /* current class ptr */
332 +           } inner;
333 +    } un;
334 +    rb_node_t node[TC_HTB_NUMPRIO];    /* node for self or feed tree */
335 +    rb_node_t pq_node;                 /* node for event queue */
336 +    unsigned long pq_key;      /* the same type as jiffies global */
337      
338 +    int prio_activity;         /* for which prios are we active */
339 +    enum htb_cmode cmode;      /* current mode of the class */
340 +
341      /* class attached filters */
342      struct tcf_proto *filter_list;
343      int filter_cnt;
344  
345 +    int warned;                /* only one warning about non work conserving .. */
346 +
347      /* token bucket parameters */
348      struct qdisc_rate_table *rate;     /* rate table of the class itself */
349      struct qdisc_rate_table *ceil;     /* ceiling rate (limits borrows too) */
350 @@ -192,10 +187,6 @@
351      long mbuffer;                      /* max wait time */
352      long tokens,ctokens;               /* current number of tokens */
353      psched_time_t t_c;                 /* checkpoint time */
354 -
355 -    /* walk result cache for leaves */
356 -    unsigned long rcache_sn;           /* SN of cache validity */
357 -    unsigned rc_level;                 /* victim's level */
358  };
359  
360  /* TODO: maybe compute rate when size is too large .. or drop ? */
361 @@ -212,19 +203,23 @@
362  
363  struct htb_sched
364  {
365 -    struct htb_class *root;            /* root classes circular list */
366 -    struct htb_class *hash[HTB_HSIZE]; /* hashed by classid */
367 +    struct list_head root;                     /* root classes list */
368 +    struct list_head hash[HTB_HSIZE];          /* hashed by classid */
369 +    struct list_head drops[TC_HTB_NUMPRIO];    /* active leaves (for drops) */
370      
371 -    /* active classes table; this needs explanation. This table contains
372 -       one set of pointers per priority, it is obvious. The set contains
373 -       one pointer per class level in the same way as cl->deficit is
374 -       independent for each level. This allows us to maintain correct
375 -       DRR position independent of borrowing level.
376 -       If we used single active/deficit items then DRR fairness'd suffer
377 -       from frequent class level changes.
378 -       Note that htb_[de]activate must be used to update this item
379 -       because it needs to keep all pointers in set coherent. */
380 -    struct htb_class *active[TC_HTB_NUMPRIO][TC_HTB_MAXDEPTH];
381 +    /* self list - roots of self generating tree */
382 +    rb_root_t row[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
383 +    int row_mask[TC_HTB_MAXDEPTH];
384 +    rb_node_t *ptr[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
385 +
386 +    /* self wait list - roots of wait PQs per row */
387 +    rb_root_t wait_pq[TC_HTB_MAXDEPTH];
388 +
389 +    /* time of nearest event per level (row) */
390 +    unsigned long near_ev_cache[TC_HTB_MAXDEPTH];
391 +
392 +    /* whether we hit non-work conserving class during this dequeue; we use */
393 +    int nwc_hit;       /* this to disable mindelay complaint in dequeue */
394  
395      int defcls;                /* class where unclassified flows go to */
396      u32 debug;         /* subsystem debug levels */
397 @@ -233,27 +228,18 @@
398      struct tcf_proto *filter_list;
399      int filter_cnt;
400  
401 -    unsigned long sn;          /* result cache serial number */
402      int rate2quantum;          /* quant = rate / rate2quantum */
403      psched_time_t now;         /* cached dequeue time */
404 -    long delay;                        /* how long to deactivate for */
405      struct timer_list timer;   /* send delay timer */
406 +#ifdef HTB_RATECM
407      struct timer_list rttim;   /* rate computer timer */
408      int recmp_bucket;          /* which hash bucket to recompute next */
409 -
410 -    /* cache of last dequeued class */
411 -    struct htb_class *last_tx;
412 -    int use_dcache;
413 -
414 -    /* non shapped skbs; let them go directly thru */
415 +#endif
416 +    
417 +    /* non shaped skbs; let them go directly thru */
418      struct sk_buff_head direct_queue;
419      int direct_qlen;  /* max qlen of above */
420  
421 -    /* statistics (see tc_htb_glob for explanation) */
422 -    long deq_rate,deq_rate_c;
423 -    long utilz,utilz_c;
424 -    long trials,trials_c;
425 -    long dcache_hits;
426      long direct_pkts;
427  };
428  
429 @@ -271,117 +257,477 @@
430  /* find class in global hash table using given handle */
431  static __inline__ struct htb_class *htb_find(u32 handle, struct Qdisc *sch)
432  {
433 -    struct htb_sched *q = (struct htb_sched *)sch->data;
434 -    int h = htb_hash(handle);
435 -    struct htb_class *cl;
436 -    if (TC_H_MAJ(handle) != sch->handle) return NULL;
437 -    cl = q->hash[h];
438 -    if (cl) do {
439 -       if (cl->classid == handle) return cl;
440 -
441 -    } while ((cl = cl->hlist.next) != q->hash[h]);
442 -    return NULL;
443 +       struct htb_sched *q = (struct htb_sched *)sch->data;
444 +       struct list_head *p;
445 +       if (TC_H_MAJ(handle) != sch->handle) 
446 +               return NULL;
447 +       
448 +       list_for_each (p,q->hash+htb_hash(handle)) {
449 +               struct htb_class *cl = list_entry(p,struct htb_class,hlist);
450 +               if (cl->classid == handle)
451 +                       return cl;
452 +       }
453 +       return NULL;
454  }
455  
456 -/* classify packet into class TODO: use inner filters & marks here */
457 -static struct htb_class *htb_clasify(struct sk_buff *skb, struct Qdisc *sch)
458 +/**
459 + * htb_classify - classify a packet into class
460 + *
461 + * It returns NULL if the packet should be dropped or -1 if the packet
462 + * should be passed directly thru. In all other cases leaf class is returned.
463 + * We allow direct class selection by classid in priority. The we examine
464 + * filters in qdisc and in inner nodes (if higher filter points to the inner
465 + * node). If we end up with classid MAJOR:0 we enqueue the skb into special
466 + * internal fifo (direct). These packets then go directly thru. If we still 
467 + * have no valid leaf we try to use MAJOR:default leaf. It still unsuccessfull
468 + * then finish and return direct queue.
469 + */
470 +#define HTB_DIRECT (struct htb_class*)-1
471 +static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch)
472  {
473 -    struct htb_sched *q = (struct htb_sched *)sch->data;
474 -    struct htb_class *cl;
475 -    struct tcf_result res;
476 -    struct tcf_proto *tcf;
477 -
478 -    /* allow to select class by setting skb->priority to valid classid;
479 -       note that nfmark can be used too by attaching filter fw with no
480 -       rules in it */
481 -    if (skb->priority == sch->handle)
482 -       return NULL;  /* X:0 (direct flow) selected */
483 -    if ((cl = htb_find(skb->priority,sch)) != NULL) 
484 +       struct htb_sched *q = (struct htb_sched *)sch->data;
485 +       struct htb_class *cl;
486 +       struct tcf_result res;
487 +       struct tcf_proto *tcf;
488 +       int result;
489 +
490 +       /* allow to select class by setting skb->priority to valid classid;
491 +          note that nfmark can be used too by attaching filter fw with no
492 +          rules in it */
493 +       if (skb->priority == sch->handle)
494 +               return HTB_DIRECT;  /* X:0 (direct flow) selected */
495 +       if ((cl = htb_find(skb->priority,sch)) != NULL) 
496 +               return cl;
497 +
498 +       tcf = q->filter_list;
499 +       while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
500 +#ifdef CONFIG_NET_CLS_POLICE
501 +               if (result == TC_POLICE_SHOT)
502 +                       return NULL;
503 +#endif
504 +               if ((cl = (void*)res.class) == NULL) {
505 +                       if (res.classid == sch->handle)
506 +                               return HTB_DIRECT;  /* X:0 (direct flow) */
507 +                       if ((cl = htb_find(res.classid,sch)) == NULL)
508 +                               break; /* filter selected invalid classid */
509 +               }
510 +               if (!cl->level)
511 +                       return cl; /* we hit leaf; return it */
512 +
513 +               /* we have got inner class; apply inner filter chain */
514 +               tcf = cl->filter_list;
515 +       }
516 +       /* classification failed; try to use default class */
517 +       cl = htb_find(TC_H_MAKE(TC_H_MAJ(sch->handle),q->defcls),sch);
518 +       if (!cl || cl->level)
519 +               return HTB_DIRECT; /* bad default .. this is safe bet */
520         return cl;
521 +}
522 +
523 +#ifdef HTB_DEBUG
524 +static void htb_next_rb_node(rb_node_t **n);
525 +#define HTB_DUMTREE(root,memb) if(root) { \
526 +       rb_node_t *n = (root)->rb_node; \
527 +       while (n->rb_left) n = n->rb_left; \
528 +       while (n) { \
529 +               struct htb_class *cl = rb_entry(n, struct htb_class, memb); \
530 +               printk(" %x",cl->classid); htb_next_rb_node (&n); \
531 +       } }
532 +
533 +static void htb_debug_dump (struct htb_sched *q)
534 +{
535 +       int i,p;
536 +       printk(KERN_DEBUG "htb*g j=%lu\n",jiffies);
537 +       /* rows */
538 +       for (i=TC_HTB_MAXDEPTH-1;i>=0;i--) {
539 +               printk(KERN_DEBUG "htb*r%d m=%x",i,q->row_mask[i]);
540 +               for (p=0;p<TC_HTB_NUMPRIO;p++) {
541 +                       if (!q->row[i][p].rb_node) continue;
542 +                       printk(" p%d:",p);
543 +                       HTB_DUMTREE(q->row[i]+p,node[p]);
544 +               }
545 +               printk("\n");
546 +       }
547 +       /* classes */
548 +       for (i = 0; i < HTB_HSIZE; i++) {
549 +               struct list_head *l;
550 +               list_for_each (l,q->hash+i) {
551 +                       struct htb_class *cl = list_entry(l,struct htb_class,hlist);
552 +                       long diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
553 +                       printk(KERN_DEBUG "htb*c%x m=%d t=%ld c=%ld pq=%lu df=%ld ql=%d "
554 +                                       "pa=%x f:",
555 +                               cl->classid,cl->cmode,cl->tokens,cl->ctokens,
556 +                               cl->pq_node.rb_color==-1?0:cl->pq_key,diff,
557 +                               cl->level?0:cl->un.leaf.q->q.qlen,cl->prio_activity);
558 +                       if (cl->level)
559 +                       for (p=0;p<TC_HTB_NUMPRIO;p++) {
560 +                               if (!cl->un.inner.feed[p].rb_node) continue;
561 +                               printk(" p%d a=%x:",p,cl->un.inner.ptr[p]?rb_entry(cl->un.inner.ptr[p], struct htb_class,node[p])->classid:0);
562 +                               HTB_DUMTREE(cl->un.inner.feed+p,node[p]);
563 +                       }
564 +                       printk("\n");
565 +               }
566 +       }
567 +}
568 +#endif
569 +/**
570 + * htb_add_to_id_tree - adds class to the round robin list
571 + *
572 + * Routine adds class to the list (actually tree) sorted by classid.
573 + * Make sure that class is not already on such list for given prio.
574 + */
575 +static void htb_add_to_id_tree (HTB_ARGQ rb_root_t *root,
576 +               struct htb_class *cl,int prio)
577 +{
578 +       rb_node_t **p = &root->rb_node, *parent = NULL;
579 +       HTB_DBG(7,3,"htb_add_id_tree cl=%X prio=%d\n",cl->classid,prio);
580 +#ifdef HTB_DEBUG
581 +       if (cl->node[prio].rb_color != -1) { BUG_TRAP(0); return; }
582 +       HTB_CHCL(cl);
583 +       if (*p) {
584 +               struct htb_class *x = rb_entry(*p,struct htb_class,node[prio]);
585 +               HTB_CHCL(x);
586 +       }
587 +#endif
588 +       while (*p) {
589 +               struct htb_class *c; parent = *p;
590 +               c = rb_entry(parent, struct htb_class, node[prio]);
591 +               HTB_CHCL(c);
592 +               if (cl->classid > c->classid)
593 +                       p = &parent->rb_right;
594 +               else 
595 +                       p = &parent->rb_left;
596 +       }
597 +       rb_link_node(&cl->node[prio], parent, p);
598 +       rb_insert_color(&cl->node[prio], root);
599 +}
600 +
601 +/**
602 + * htb_add_to_wait_tree - adds class to the event queue with delay
603 + *
604 + * The class is added to priority event queue to indicate that class will
605 + * change its mode in cl->pq_key microseconds. Make sure that class is not
606 + * already in the queue.
607 + */
608 +static void htb_add_to_wait_tree (struct htb_sched *q,
609 +               struct htb_class *cl,long delay,int debug_hint)
610 +{
611 +       rb_node_t **p = &q->wait_pq[cl->level].rb_node, *parent = NULL;
612 +       HTB_DBG(7,3,"htb_add_wt cl=%X key=%lu\n",cl->classid,cl->pq_key);
613 +#ifdef HTB_DEBUG
614 +       if (cl->pq_node.rb_color != -1) { BUG_TRAP(0); return; }
615 +       HTB_CHCL(cl);
616 +       if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit())
617 +               printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint);
618 +#endif
619 +       DEVIK_MSTART(9);
620 +       cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay);
621 +       if (cl->pq_key == jiffies)
622 +               cl->pq_key++;
623 +
624 +       /* update the nearest event cache */
625 +       if (q->near_ev_cache[cl->level] - cl->pq_key < 0x80000000)
626 +               q->near_ev_cache[cl->level] = cl->pq_key;
627 +       
628 +       while (*p) {
629 +               struct htb_class *c; parent = *p;
630 +               c = rb_entry(parent, struct htb_class, pq_node);
631 +               if (cl->pq_key - c->pq_key < 0x80000000)
632 +                       p = &parent->rb_right;
633 +               else 
634 +                       p = &parent->rb_left;
635 +       }
636 +       rb_link_node(&cl->pq_node, parent, p);
637 +       rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]);
638 +       DEVIK_MEND(9);
639 +}
640  
641 -    tcf = q->filter_list;
642 -    while (tcf && !tc_classify(skb, tcf, &res)) {
643 -       if (res.classid == sch->handle)
644 -           return NULL;  /* X:0 (direct flow) selected */
645 -       if ((cl = htb_find(res.classid,sch)) == NULL)
646 -           break; /* filter selected invalid classid */
647 -       if (!cl->level)
648 -           return cl; /* we hit leaf; return it */ 
649 +/**
650 + * htb_next_rb_node - finds next node in binary tree
651 + *
652 + * When we are past last key we return NULL.
653 + * Average complexity is 2 steps per call.
654 + */
655 +static void htb_next_rb_node(rb_node_t **n)
656 +{
657 +       rb_node_t *p;
658 +       if ((*n)->rb_right) {
659 +               *n = (*n)->rb_right;
660 +               while ((*n)->rb_left) 
661 +                       *n = (*n)->rb_left;
662 +               return;
663 +       }
664 +       while ((p = (*n)->rb_parent) != NULL) {
665 +               if (p->rb_left == *n) break;
666 +               *n = p;
667 +       }
668 +       *n = p;
669 +}
670  
671 -       /* we have got inner class; apply inner filter chain */
672 -       tcf = cl->filter_list;
673 +/**
674 + * htb_add_class_to_row - add class to its row
675 + *
676 + * The class is added to row at priorities marked in mask.
677 + * It does nothing if mask == 0.
678 + */
679 +static inline void htb_add_class_to_row(struct htb_sched *q, 
680 +               struct htb_class *cl,int mask)
681 +{
682 +       HTB_DBG(7,2,"htb_addrow cl=%X mask=%X rmask=%X\n",
683 +                       cl->classid,mask,q->row_mask[cl->level]);
684 +       HTB_CHCL(cl);
685 +       q->row_mask[cl->level] |= mask;
686 +       while (mask) {
687 +               int prio = ffz(~mask);
688 +               mask &= ~(1 << prio);
689 +               htb_add_to_id_tree(HTB_PASSQ q->row[cl->level]+prio,cl,prio);
690 +       }
691 +}
692 +
693 +/**
694 + * htb_remove_class_from_row - removes class from its row
695 + *
696 + * The class is removed from row at priorities marked in mask.
697 + * It does nothing if mask == 0.
698 + */
699 +static __inline__ void htb_remove_class_from_row(struct htb_sched *q,
700 +               struct htb_class *cl,int mask)
701 +{
702 +       int m = 0;
703 +       HTB_CHCL(cl);
704 +       while (mask) {
705 +               int prio = ffz(~mask);
706 +               mask &= ~(1 << prio);
707 +               if (q->ptr[cl->level][prio] == cl->node+prio)
708 +                       htb_next_rb_node(q->ptr[cl->level]+prio);
709 +               htb_safe_rb_erase(cl->node + prio,q->row[cl->level]+prio);
710 +               if (!q->row[cl->level][prio].rb_node) 
711 +                       m |= 1 << prio;
712 +       }
713 +       HTB_DBG(7,2,"htb_delrow cl=%X mask=%X rmask=%X maskdel=%X\n",
714 +                       cl->classid,mask,q->row_mask[cl->level],m);
715 +       q->row_mask[cl->level] &= ~m;
716 +}
717 +
718 +/**
719 + * htb_activate_prios - creates active classe's feed chain
720 + *
721 + * The class is connected to ancestors and/or appropriate rows
722 + * for priorities it is participating on. cl->cmode must be new 
723 + * (activated) mode. It does nothing if cl->prio_activity == 0.
724 + */
725 +static void htb_activate_prios(struct htb_sched *q,struct htb_class *cl)
726 +{
727 +       struct htb_class *p = cl->parent;
728 +       long m,mask = cl->prio_activity;
729 +       HTB_DBG(7,2,"htb_act_prios cl=%X mask=%lX cmode=%d\n",cl->classid,mask,cl->cmode);
730 +       HTB_CHCL(cl);
731 +
732 +       while (cl->cmode == HTB_MAY_BORROW && p && mask) {
733 +               HTB_CHCL(p);
734 +               m = mask; while (m) {
735 +                       int prio = ffz(~m);
736 +                       m &= ~(1 << prio);
737 +                       
738 +                       if (p->un.inner.feed[prio].rb_node)
739 +                               /* parent already has its feed in use so that
740 +                                  reset bit in mask as parent is already ok */
741 +                               mask &= ~(1 << prio);
742 +                       
743 +                       htb_add_to_id_tree(HTB_PASSQ p->un.inner.feed+prio,cl,prio);
744 +               }
745 +               HTB_DBG(7,3,"htb_act_pr_aft p=%X pact=%X mask=%lX pmode=%d\n",
746 +                               p->classid,p->prio_activity,mask,p->cmode);
747 +               p->prio_activity |= mask;
748 +               cl = p; p = cl->parent;
749 +               HTB_CHCL(cl);
750 +       }
751 +       if (cl->cmode == HTB_CAN_SEND && mask)
752 +               htb_add_class_to_row(q,cl,mask);
753 +}
754 +
755 +/**
756 + * htb_deactivate_prios - remove class from feed chain
757 + *
758 + * cl->cmode must represent old mode (before deactivation). It does 
759 + * nothing if cl->prio_activity == 0. Class is removed from all feed
760 + * chains and rows.
761 + */
762 +static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl)
763 +{
764 +       struct htb_class *p = cl->parent;
765 +       long m,mask = cl->prio_activity;
766 +       HTB_DBG(7,2,"htb_deact_prios cl=%X mask=%lX cmode=%d\n",cl->classid,mask,cl->cmode);
767 +       HTB_CHCL(cl);
768 +
769 +       while (cl->cmode == HTB_MAY_BORROW && p && mask) {
770 +               m = mask; mask = 0; 
771 +               while (m) {
772 +                       int prio = ffz(~m);
773 +                       m &= ~(1 << prio);
774 +                       
775 +                       if (p->un.inner.ptr[prio] == cl->node+prio)
776 +                               htb_next_rb_node(p->un.inner.ptr + prio);
777 +                       
778 +                       htb_safe_rb_erase(cl->node + prio,p->un.inner.feed + prio);
779 +                       
780 +                       if (!p->un.inner.feed[prio].rb_node) 
781 +                               mask |= 1 << prio;
782 +               }
783 +               HTB_DBG(7,3,"htb_deact_pr_aft p=%X pact=%X mask=%lX pmode=%d\n",
784 +                               p->classid,p->prio_activity,mask,p->cmode);
785 +               p->prio_activity &= ~mask;
786 +               cl = p; p = cl->parent;
787 +               HTB_CHCL(cl);
788 +       }
789 +       if (cl->cmode == HTB_CAN_SEND && mask) 
790 +               htb_remove_class_from_row(q,cl,mask);
791 +}
792 +
793 +/**
794 + * htb_class_mode - computes and returns current class mode
795 + *
796 + * It computes cl's mode at time cl->t_c+diff and returns it. If mode
797 + * is not HTB_CAN_SEND then cl->pq_key is updated to time difference
798 + * from now to time when cl will change its state. 
799 + * Also it is worth to note that class mode doesn't change simply
800 + * at cl->{c,}tokens == 0 but there can rather be hysteresis of 
801 + * 0 .. -cl->{c,}buffer range. It is meant to limit number of
802 + * mode transitions per time unit. The speed gain is about 1/6.
803 + */
804 +static __inline__ enum htb_cmode 
805 +htb_class_mode(struct htb_class *cl,long *diff)
806 +{
807 +    long toks;
808 +
809 +    if ((toks = (cl->ctokens + *diff)) < (
810 +#ifdef HTB_HYSTERESIS
811 +           cl->cmode != HTB_CANT_SEND ? -cl->cbuffer :
812 +#endif
813 +                   0)) {
814 +           *diff = -toks;
815 +           return HTB_CANT_SEND;
816      }
817 -    /* classification failed; try to use default class */
818 -    return htb_find(TC_H_MAKE(TC_H_MAJ(sch->handle),q->defcls),sch);
819 +    if ((toks = (cl->tokens + *diff)) >= (
820 +#ifdef HTB_HYSTERESIS
821 +           cl->cmode == HTB_CAN_SEND ? -cl->buffer :
822 +#endif
823 +           0))
824 +           return HTB_CAN_SEND;
825 +
826 +    *diff = -toks;
827 +    return HTB_MAY_BORROW;
828  }
829  
830 -/* inserts cl into appropriate active lists (for all levels) */
831 +/**
832 + * htb_change_class_mode - changes classe's mode
833 + *
834 + * This should be the only way how to change classe's mode under normal
835 + * cirsumstances. Routine will update feed lists linkage, change mode
836 + * and add class to the wait event queue if appropriate. New mode should
837 + * be different from old one and cl->pq_key has to be valid if changing
838 + * to mode other than HTB_CAN_SEND (see htb_add_to_wait_tree).
839 + */
840 +static void 
841 +htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, long *diff)
842 +{ 
843 +       enum htb_cmode new_mode = htb_class_mode(cl,diff);
844 +       
845 +       HTB_CHCL(cl);
846 +       HTB_DBG(7,1,"htb_chging_clmode %d->%d cl=%X\n",cl->cmode,new_mode,cl->classid);
847 +
848 +       if (new_mode == cl->cmode)
849 +               return; 
850 +       
851 +       if (cl->prio_activity) { /* not neccessary: speed optimization */
852 +               if (cl->cmode != HTB_CANT_SEND) 
853 +                       htb_deactivate_prios(q,cl);
854 +               cl->cmode = new_mode;
855 +               if (new_mode != HTB_CANT_SEND) 
856 +                       htb_activate_prios(q,cl);
857 +       } else 
858 +               cl->cmode = new_mode;
859 +}
860 +
861 +/**
862 + * htb_activate - inserts leaf cl into appropriate active feeds 
863 + *
864 + * Routine learns (new) priority of leaf and activates feed chain
865 + * for the prio. It can be called on already active leaf safely.
866 + * It also adds leaf into droplist.
867 + */
868  static __inline__ void htb_activate(struct htb_sched *q,struct htb_class *cl)
869  {
870 -    if (!cl->active.prev) {
871 -       struct htb_class **ap = q->active[(int)(cl->aprio=cl->prio)];
872 -       int i = !ap[0];
873 -       HTB_INSERTB(active,ap[0],cl);
874 -       if (i) /* set also all level pointers */
875 -           for (i = 1; i < TC_HTB_MAXDEPTH; i++) ap[i] = ap[0];
876 -    }
877 +       BUG_TRAP(!cl->level && cl->un.leaf.q && cl->un.leaf.q->q.qlen);
878 +       HTB_CHCL(cl);
879 +       if (!cl->prio_activity) {
880 +               cl->prio_activity = 1 << (cl->un.leaf.aprio = cl->un.leaf.prio);
881 +               htb_activate_prios(q,cl);
882 +               list_add_tail(&cl->un.leaf.drop_list,q->drops+cl->un.leaf.aprio);
883 +       }
884  }
885  
886 -/* remove cl from active lists; lev is level at which we dequeued
887 -   so that we know that active[prio][lev] points to cl */
888 +/**
889 + * htb_deactivate - remove leaf cl from active feeds 
890 + *
891 + * Make sure that leaf is active. In the other words it can't be called
892 + * with non-active leaf. It also removes class from the drop list.
893 + */
894  static __inline__ void 
895 -htb_deactivate(struct htb_sched *q,struct htb_class *cl,int lev)
896 +htb_deactivate(struct htb_sched *q,struct htb_class *cl)
897  {
898 -    int i;
899 -    struct htb_class **ap = q->active[(int)cl->aprio];
900 -    HTB_DELETE(active,cl,ap[lev]);
901 -    if (ap[lev]) {
902 -       /* repair other level pointers if they've pointed
903 -          to the deleted class */
904 -       for (i = 0; i < TC_HTB_MAXDEPTH; i++)
905 -           if (ap[i] == cl) ap[i] = ap[lev];
906 -    } else
907 -       memset(ap,0,sizeof(*ap)*TC_HTB_MAXDEPTH);
908 +       BUG_TRAP(cl->prio_activity);
909 +       HTB_CHCL(cl);
910 +       htb_deactivate_prios(q,cl);
911 +       cl->prio_activity = 0;
912 +       list_del_init(&cl->un.leaf.drop_list);
913  }
914  
915  static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
916  {
917      struct htb_sched *q = (struct htb_sched *)sch->data;
918 -    struct htb_class *cl = htb_clasify(skb,sch);
919 +    struct htb_class *cl = htb_classify(skb,sch);
920  
921 -    if (!cl || !cl->q) {
922 -       /* bad class; enqueue to helper queue */
923 -       if (q->direct_queue.qlen < q->direct_qlen) {
924 +    DEVIK_MSTART(0);
925 +    if (cl == HTB_DIRECT || !cl) {
926 +       /* enqueue to helper queue */
927 +       if (q->direct_queue.qlen < q->direct_qlen && cl) {
928             __skb_queue_tail(&q->direct_queue, skb);
929             q->direct_pkts++;
930         } else {
931             kfree_skb (skb);
932             sch->stats.drops++;
933 +           DEVIK_MEND(0);
934             return NET_XMIT_DROP;
935         }
936 -    } else if (cl->q->enqueue(skb, cl->q) != NET_XMIT_SUCCESS) {
937 +    } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
938         sch->stats.drops++;
939         cl->stats.drops++;
940 +       DEVIK_MEND(0);
941         return NET_XMIT_DROP;
942      } else {
943         cl->stats.packets++; cl->stats.bytes += skb->len;
944 +       DEVIK_MSTART(1);
945         htb_activate (q,cl);
946 +       DEVIK_MEND(1);
947      }
948  
949      sch->q.qlen++;
950      sch->stats.packets++; sch->stats.bytes += skb->len;
951      HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
952 +    DEVIK_MEND(0);
953      return NET_XMIT_SUCCESS;
954  }
955  
956 +/* TODO: requeuing packet charges it to policers again !! */
957  static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
958  {
959      struct htb_sched *q = (struct htb_sched *)sch->data;
960 -    struct htb_class *cl = htb_clasify(skb,sch);
961 +    struct htb_class *cl = htb_classify(skb,sch);
962  
963 -    if (!cl || !cl->q) {
964 -       /* bad class; enqueue to helper queue */
965 -       if (q->direct_queue.qlen < q->direct_qlen) {
966 +    if (cl == HTB_DIRECT || !cl) {
967 +       /* enqueue to helper queue */
968 +       if (q->direct_queue.qlen < q->direct_qlen && cl) {
969             __skb_queue_tail(&q->direct_queue, skb);
970             q->direct_pkts++;
971         } else {
972 @@ -389,12 +735,12 @@
973             sch->stats.drops++;
974             return NET_XMIT_DROP;
975         }
976 -    } else if (cl->q->ops->requeue(skb, cl->q) != NET_XMIT_SUCCESS) {
977 +    } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
978         sch->stats.drops++;
979         cl->stats.drops++;
980         return NET_XMIT_DROP;
981      } else 
982 -       htb_activate (q,cl);
983 +           htb_activate (q,cl);
984  
985      sch->q.qlen++;
986      HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
987 @@ -409,315 +755,251 @@
988      netif_schedule(sch->dev);
989  }
990  
991 +#ifdef HTB_RATECM
992  #define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0
993  static void htb_rate_timer(unsigned long arg)
994  {
995 -    struct Qdisc *sch = (struct Qdisc*)arg;
996 -    struct htb_sched *q = (struct htb_sched *)sch->data;
997 -    struct htb_class *cl;
998 -
999 -    /* lock queue so that we can muck with it */
1000 -    HTB_QLOCK(sch);
1001 -    HTB_DBG(10,1,"htb_rttmr j=%ld\n",jiffies);
1002 -
1003 -    q->rttim.expires = jiffies + HZ;
1004 -    add_timer(&q->rttim);
1005 -
1006 -    /* scan and recompute one bucket at time */
1007 -    if (++q->recmp_bucket >= HTB_HSIZE) q->recmp_bucket = 0;
1008 -    if ((cl = q->hash[q->recmp_bucket]) != NULL) do {
1009 -       HTB_DBG(10,2,"htb_rttmr_cl cl=%X sbyte=%lu spkt=%lu\n",cl->classid,cl->sum_bytes,cl->sum_packets);
1010 -       RT_GEN (cl->sum_bytes,cl->rate_bytes);
1011 -       RT_GEN (cl->sum_packets,cl->rate_packets);
1012 -    } while ((cl = cl->hlist.next) != q->hash[q->recmp_bucket]);
1013 -    
1014 -    /* global stats */
1015 -    RT_GEN (q->trials_c,q->trials);
1016 -    RT_GEN (q->utilz_c,q->utilz);
1017 -    RT_GEN (q->deq_rate_c,q->deq_rate);
1018 -
1019 -    HTB_QUNLOCK(sch);
1020 -}
1021 -
1022 -/* test whether class can send or borrow packet */
1023 -static enum htb_cmode
1024 -htb_class_mode(struct htb_sched *q, struct htb_class *cl)
1025 -{
1026 -    long toks,diff;
1027 -    diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
1028 -    HTB_DBG(6,3,"htb_cm diff=%ld\n",diff);
1029 -
1030 -    /* check whether we are over ceil */
1031 -    if ((toks = (cl->ctokens + diff)) < 0) { 
1032 -       if (q->delay > -toks || !q->delay) q->delay = -toks;
1033 -       return HTB_CANT_SEND;
1034 -    }
1035 -
1036 -    /* our regular rate */
1037 -    if ((toks = (cl->tokens + diff)) >= 0) 
1038 -       return HTB_CAN_SEND;
1039 -
1040 -    /* record time when we can transmit */
1041 -    if (q->delay > -toks || !q->delay) q->delay = -toks;
1042 -
1043 -    return HTB_MAY_BORROW;
1044 -}
1045 -
1046 -/* computes (possibly ancestor) class ready to send; cl is leaf; 
1047 -   cl's rc_level is then filled with level we are borrowing at; 
1048 -   it is set to TC_HTB_MAXDEPTH if we can't borrow at all and can be
1049 -   ORed with HTB_F_INJ if bw was injected. */
1050 -static void htb_ready_level(struct htb_sched *q,struct htb_class *cl)
1051 -{
1052 -    struct htb_class *stack[TC_HTB_MAXDEPTH],**sp = stack;
1053 -    int level = TC_HTB_MAXDEPTH, injdist = cl->injectd;
1054 -    enum htb_cmode mode;
1055 -    HTB_DBG(6,1,"htb_rl cl=%X tok=%ld ctok=%ld buf=%ld cbuf=%ld\n",cl->classid,cl->tokens,cl->ctokens,cl->buffer,cl->cbuffer);
1056 -
1057 -    /* traverse tree upward looking for ready class */
1058 -    for (;;) {
1059 -       *sp++ = cl; /* push at stack */
1060 -
1061 -       /* test mode */
1062 -       mode = htb_class_mode(q,cl);
1063 -       HTB_DBG(6,2,"htb_clmod cl=%X m=%d tok=%ld ctok=%ld buf=%ld cbuf=%ld\n",cl->classid,mode,cl->tokens,cl->ctokens,cl->buffer,cl->cbuffer);
1064 -       if (mode != HTB_MAY_BORROW) {
1065 -           if (mode == HTB_CAN_SEND) level = cl->level;
1066 -           break;
1067 -       }
1068 -       /* update injdist from current node */
1069 -       if (injdist > cl->injectd) injdist = cl->injectd;
1070 -
1071 -       /* if this is leaf's injector then resolve borrow positively */
1072 -       if (!injdist--) {
1073 -           /* don't cache this result in interior nodes */
1074 -           stack[0]->rc_level = cl->level|HTB_F_INJ;
1075 -           stack[0]->rcache_sn = q->sn;
1076 -           return;
1077 -       }
1078 -       if ((cl = cl->parent) == NULL) break;
1079 -       if (q->sn == cl->rcache_sn) {
1080 -           /* the node has already computed result; use it */
1081 -           level = cl->rc_level; break;
1082 +       struct Qdisc *sch = (struct Qdisc*)arg;
1083 +       struct htb_sched *q = (struct htb_sched *)sch->data;
1084 +       struct list_head *p;
1085 +
1086 +       /* lock queue so that we can muck with it */
1087 +       HTB_QLOCK(sch);
1088 +       HTB_DBG(10,1,"htb_rttmr j=%ld\n",jiffies);
1089 +
1090 +       q->rttim.expires = jiffies + HZ;
1091 +       add_timer(&q->rttim);
1092 +
1093 +       /* scan and recompute one bucket at time */
1094 +       if (++q->recmp_bucket >= HTB_HSIZE) 
1095 +               q->recmp_bucket = 0;
1096 +       list_for_each (p,q->hash+q->recmp_bucket) {
1097 +               struct htb_class *cl = list_entry(p,struct htb_class,hlist);
1098 +               HTB_DBG(10,2,"htb_rttmr_cl cl=%X sbyte=%lu spkt=%lu\n",
1099 +                               cl->classid,cl->sum_bytes,cl->sum_packets);
1100 +               RT_GEN (cl->sum_bytes,cl->rate_bytes);
1101 +               RT_GEN (cl->sum_packets,cl->rate_packets);
1102         }
1103 -    }
1104 -    while (--sp >= stack) { /* update mode cache */
1105 -       (*sp)->rcache_sn = q->sn;
1106 -       (*sp)->rc_level = level;
1107 -    }  
1108 +       HTB_QUNLOCK(sch);
1109  }
1110 +#endif
1111  
1112 -/* pull packet from class and charge to ancestors */
1113 -static struct sk_buff *
1114 -htb_dequeue_class(struct Qdisc *sch, struct htb_class *cl)
1115 +/**
1116 + * htb_charge_class - charges ammount "bytes" to leaf and ancestors
1117 + *
1118 + * Routine assumes that packet "bytes" long was dequeued from leaf cl
1119 + * borrowing from "level". It accounts bytes to ceil leaky bucket for
1120 + * leaf and all ancestors and to rate bucket for ancestors at levels
1121 + * "level" and higher. It also handles possible change of mode resulting
1122 + * from the update. Note that mode can also increase here (MAY_BORROW to
1123 + * CAN_SEND) because we can use more precise clock that event queue here.
1124 + * In such case we remove class from event queue first.
1125 + */
1126 +static void htb_charge_class(struct htb_sched *q,struct htb_class *cl,
1127 +               int level,int bytes)
1128  {      
1129 -    struct htb_sched *q = (struct htb_sched *)sch->data;
1130 -    long toks,diff;
1131 -    int injecting = cl->rc_level & HTB_F_INJ, injdist = cl->injectd;
1132 -    int level = cl->rc_level & 0xff;
1133 -    struct sk_buff *skb = cl->q->dequeue(cl->q);
1134 -    HTB_DBG(5,1,"htb_deq_cl cl=%X skb=%p lev=%d inj=%d\n",cl->classid,skb,level,injecting);
1135 -    if (!skb) return NULL;
1136 -
1137 -    /* we have got skb, account it to victim and its parents
1138 -       and also to all ceil estimators under victim */
1139 -    while (cl) {
1140 -       diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
1141 +       long toks,diff;
1142 +       enum htb_cmode old_mode;
1143 +       HTB_DBG(5,1,"htb_chrg_cl cl=%X lev=%d len=%d\n",cl->classid,level,bytes);
1144  
1145  #define HTB_ACCNT(T,B,R) toks = diff + cl->T; \
1146         if (toks > cl->B) toks = cl->B; \
1147 -           toks -= L2T(cl, cl->R, skb->len); \
1148 +       toks -= L2T(cl, cl->R, bytes); \
1149         if (toks <= -cl->mbuffer) toks = 1-cl->mbuffer; \
1150 -           cl->T = toks
1151 -
1152 -       HTB_ACCNT (ctokens,cbuffer,ceil);
1153 -       if (cl->level >= level) {
1154 -           if (cl->level == level) cl->xstats.lends++;
1155 -           HTB_ACCNT (tokens,buffer,rate);
1156 -       } else {
1157 -           cl->xstats.borrows++;
1158 -           cl->tokens += diff; /* we moved t_c; update tokens */
1159 -       }
1160 -       cl->t_c = q->now;
1161 -       HTB_DBG(5,2,"htb_deq_clp cl=%X clev=%d diff=%ld\n",cl->classid,cl->level,diff);
1162 +       cl->T = toks
1163  
1164 -       /* update rate counters */
1165 -       cl->sum_bytes += skb->len; cl->sum_packets++;
1166 +       while (cl) {
1167 +               HTB_CHCL(cl);
1168 +               diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
1169 +#ifdef HTB_DEBUG
1170 +               if (diff > cl->mbuffer || diff < 0 || PSCHED_TLESS(q->now, cl->t_c)) {
1171 +                       if (net_ratelimit())
1172 +                               printk(KERN_ERR "HTB: bad diff in charge, cl=%X diff=%lX now=%Lu then=%Lu j=%lu\n",
1173 +                                      cl->classid, diff,
1174 +                                      (unsigned long long) q->now,
1175 +                                      (unsigned long long) cl->t_c,
1176 +                                      jiffies);
1177 +                       diff = 1000;
1178 +               }
1179 +#endif
1180 +               if (cl->level >= level) {
1181 +                       if (cl->level == level) cl->xstats.lends++;
1182 +                       HTB_ACCNT (tokens,buffer,rate);
1183 +               } else {
1184 +                       cl->xstats.borrows++;
1185 +                       cl->tokens += diff; /* we moved t_c; update tokens */
1186 +               }
1187 +               HTB_ACCNT (ctokens,cbuffer,ceil);
1188 +               cl->t_c = q->now;
1189 +               HTB_DBG(5,2,"htb_chrg_clp cl=%X diff=%ld tok=%ld ctok=%ld\n",cl->classid,diff,cl->tokens,cl->ctokens);
1190 +
1191 +               old_mode = cl->cmode; diff = 0;
1192 +               htb_change_class_mode(q,cl,&diff);
1193 +               if (old_mode != cl->cmode) {
1194 +                       if (old_mode != HTB_CAN_SEND)
1195 +                               htb_safe_rb_erase(&cl->pq_node,q->wait_pq+cl->level);
1196 +                       if (cl->cmode != HTB_CAN_SEND)
1197 +                               htb_add_to_wait_tree (q,cl,diff,1);
1198 +               }
1199 +               
1200 +#ifdef HTB_RATECM
1201 +               /* update rate counters */
1202 +               cl->sum_bytes += bytes; cl->sum_packets++;
1203 +#endif
1204  
1205 -       /* update byte stats except for leaves which are already updated */
1206 -       if (cl->level) {
1207 -           cl->stats.bytes += skb->len;
1208 -           cl->stats.packets++;
1209 -       }
1210 -       /* finish if we hit stop-class and we are injecting */
1211 -       if (injecting) {
1212 -           if (injdist > cl->injectd) injdist = cl->injectd;
1213 -           if (!injdist--) {
1214 -               cl->xstats.injects++; break;
1215 -           }
1216 +               /* update byte stats except for leaves which are already updated */
1217 +               if (cl->level) {
1218 +                       cl->stats.bytes += bytes;
1219 +                       cl->stats.packets++;
1220 +               }
1221 +               cl = cl->parent;
1222         }
1223 -       cl = cl->parent;
1224 -    }
1225 -    return skb;
1226  }
1227  
1228 -/* dequeues packet at given priority borrowing from given level;
1229 -   if unsuccessfull then it returns level at which someone can
1230 -   dequeue. If it sets level to TC_HTB_MAXDEPTH then no one can. */
1231 -static struct sk_buff *htb_dequeue_prio(struct Qdisc *sch,int prio,int *level)
1232 +/**
1233 + * htb_do_events - make mode changes to classes at the level
1234 + *
1235 + * Scans event queue for pending events and applies them. Returns jiffies to
1236 + * next pending event (0 for no event in pq).
1237 + */
1238 +static long htb_do_events(struct htb_sched *q,int level)
1239  {
1240 -    struct sk_buff *skb = NULL;
1241 -    struct htb_sched *q = (struct htb_sched *)sch->data;
1242 -    struct htb_class **ap = q->active[prio], *cl = ap[*level];
1243 -    int done,top = TC_HTB_MAXDEPTH,rclev;
1244 -
1245 -    HTB_DBG(4,1,"htb_deq_pr pr=%d lev=%d cl=%X\n",prio,*level,cl->classid);
1246 -    /* this is DRR algorithm */
1247 -    do {
1248 -       done = 1;
1249 -       do {
1250 -           /* catch empty classes here; note that we don't remove them
1251 -              immediately after dequeue but rather delay remove to next
1252 -              DRR round because if packet arrive for just emptied class
1253 -              then we don't need to remove and again add it */
1254 -           if (!cl->q->q.qlen) {
1255 -               ap[*level] = cl; /* needed for HTB_DELETE in deactivate */
1256 -               htb_deactivate (q,cl,*level);
1257 -
1258 -               HTB_DBG(4,2,"htb_deq_deact cl=%X ncl=%X\n",cl->classid,ap[*level]?ap[*level]->classid:0);
1259 -               if (ap[*level]) continue;
1260 -               *level = TC_HTB_MAXDEPTH; 
1261 -               return NULL; /* NO class remains active */
1262 -           }
1263 -           /* test whether class can send at all borrowing from level */
1264 -           if (cl->rcache_sn != q->sn) htb_ready_level(q,cl);
1265 -           rclev = cl->rc_level & 0xff; /* filter injecting flag out */
1266 -           
1267 -           HTB_DBG(4,2,"htb_deq_rd cl=%X rc_lev=0x%x dfct=%d qnt=%d\n",
1268 -                       cl->classid,cl->rc_level,cl->deficit[*level],cl->quantum);
1269 -
1270 -           if (rclev == TC_HTB_MAXDEPTH) {
1271 -               /* TODO: overlimit increment here is not proven correct */
1272 -               if (cl->deficit[*level] > 0) cl->stats.overlimits++;
1273 -               continue; /* can't send or borrow */
1274 -           }
1275 -           /* if we can't send at this level, remember where we can */
1276 -           if (rclev > *level) {
1277 -               if (rclev < top) /* keep lowest level */
1278 -                   top = rclev;
1279 -               
1280 -               HTB_DBG(4,2,"htb_deq_badlev top=%d\n",top);
1281 -               continue;
1282 -           }
1283 -           if (cl->deficit[*level] <= 0) {
1284 -               /* haven't allotment, increase and try again */
1285 -               done = 0; cl->deficit[*level] += cl->quantum;
1286 -               continue;
1287 -           }
1288 -           if ((skb = htb_dequeue_class(sch,cl)) == NULL) {
1289 -               /* nonempty class can't dequeue so that mark it as such;
1290 -                  note that rcache_sn is already set and thus this remarking
1291 -                  will be valid only for rest of this dequeue; this is
1292 -                  possible if child class is non work conserving */
1293 -               cl->rc_level = TC_HTB_MAXDEPTH;
1294 -
1295 -               HTB_DBG(4,2,"htb_deq_noskb cl=%X len=%d\n",cl->classid,cl->q->q.qlen);
1296 -               continue;
1297 -           }
1298 -           sch->q.qlen--;
1299 -           /* prepare next class if we can't stay valid */
1300 -           if ((cl->deficit[*level] -= skb->len) <= 0) cl = cl->active.next;
1301 -           else if (q->use_dcache) 
1302 -               q->last_tx = cl; /* cache cl if it still can transmit */
1303 -           ap[*level] = cl;
1304 -           
1305 -           HTB_DBG(4,1,"htb_deq_haspkt ncl=%X sqlen=%d\n",cl->classid,sch->q.qlen);
1306 -           return skb;
1307 -
1308 -       } while ((cl = cl->active.next) != ap[*level]);
1309 -
1310 -    } while (!done);
1311 -    *level = top; 
1312 -    HTB_DBG(4,1,"htb_deq_quit top=%d\n",top);
1313 -    return NULL;
1314 +       int i;
1315 +       HTB_DBG(8,1,"htb_do_events l=%d root=%p rmask=%X\n",
1316 +                       level,q->wait_pq[level].rb_node,q->row_mask[level]);
1317 +       for (i = 0; i < 500; i++) {
1318 +               struct htb_class *cl;
1319 +               long diff;
1320 +               rb_node_t *p = q->wait_pq[level].rb_node;
1321 +               if (!p) return 0;
1322 +               while (p->rb_left) p = p->rb_left;
1323 +
1324 +               cl = rb_entry(p, struct htb_class, pq_node);
1325 +               if (cl->pq_key - (jiffies+1) < 0x80000000) {
1326 +                       HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - jiffies);
1327 +                       return cl->pq_key - jiffies;
1328 +               }
1329 +               htb_safe_rb_erase(p,q->wait_pq+level);
1330 +               diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
1331 +#ifdef HTB_DEBUG
1332 +               if (diff > cl->mbuffer || diff < 0 || PSCHED_TLESS(q->now, cl->t_c)) {
1333 +                       if (net_ratelimit())
1334 +                               printk(KERN_ERR "HTB: bad diff in events, cl=%X diff=%lX now=%Lu then=%Lu j=%lu\n",
1335 +                                      cl->classid, diff,
1336 +                                      (unsigned long long) q->now,
1337 +                                      (unsigned long long) cl->t_c,
1338 +                                      jiffies);
1339 +                       diff = 1000;
1340 +               }
1341 +#endif
1342 +               htb_change_class_mode(q,cl,&diff);
1343 +               if (cl->cmode != HTB_CAN_SEND)
1344 +                       htb_add_to_wait_tree (q,cl,diff,2);
1345 +       }
1346 +       if (net_ratelimit())
1347 +               printk(KERN_WARNING "htb: too many events !\n");
1348 +       return HZ/10;
1349  }
1350  
1351 -static struct sk_buff *htb_dequeue(struct Qdisc *sch)
1352 +/**
1353 + * htb_lookup_leaf - returns next leaf class in DRR order
1354 + *
1355 + * Find leaf where current feed pointers points to.
1356 + */
1357 +static struct htb_class *
1358 +htb_lookup_leaf(rb_root_t *tree,int prio,rb_node_t **pptr)
1359  {
1360 -    struct sk_buff *skb = NULL;
1361 -    struct htb_sched *q = (struct htb_sched *)sch->data;
1362 -    int prio,oklev,okprio = 0 /* avoid unused warning */,lev,i;
1363 -    struct htb_class *cl;
1364 -    psched_time_t endt;
1365 -    
1366 -    HTB_DBG(3,1,"htb_deq dircnt=%d ltx=%X\n",skb_queue_len(&q->direct_queue),
1367 -           q->last_tx?q->last_tx->classid:0);
1368 -
1369 -    /* try to dequeue direct packets as high prio (!) to minimize cpu work */
1370 -    if ((skb = __skb_dequeue(&q->direct_queue)) != NULL) {
1371 -       sch->flags &= ~TCQ_F_THROTTLED;
1372 -       sch->q.qlen--;
1373 -       return skb;
1374 -    }
1375 -
1376 -    PSCHED_GET_TIME(q->now); /* htb_dequeue_class needs it too */
1377 -    q->delay = 0; q->sn++;
1378 +       int i;
1379 +       struct {
1380 +               rb_node_t *root;
1381 +               rb_node_t **pptr;
1382 +       } stk[TC_HTB_MAXDEPTH],*sp = stk;
1383 +       
1384 +       sp->root = tree->rb_node;
1385 +       sp->pptr = pptr;
1386 +
1387 +       for (i = 0; i < 65535; i++) {
1388 +               if (!*sp->pptr) { /* we are at right end; rewind & go up */
1389 +                       *sp->pptr = sp->root;
1390 +                       while ((*sp->pptr)->rb_left) 
1391 +                               *sp->pptr = (*sp->pptr)->rb_left;
1392 +                       if (sp > stk) {
1393 +                               sp--;
1394 +                               BUG_TRAP(*sp->pptr); if(!*sp->pptr) return NULL;
1395 +                               htb_next_rb_node (sp->pptr);
1396 +                       }
1397 +               } else {
1398 +                       struct htb_class *cl;
1399 +                       cl = rb_entry(*sp->pptr,struct htb_class,node[prio]);
1400 +                       HTB_CHCL(cl);
1401 +                       if (!cl->level) 
1402 +                               return cl;
1403 +                       (++sp)->root = cl->un.inner.feed[prio].rb_node;
1404 +                       sp->pptr = cl->un.inner.ptr+prio;
1405 +               }
1406 +       }
1407 +       BUG_TRAP(0);
1408 +       return NULL;
1409 +}
1410  
1411 -    /* well here I bite CBQ's speed :-) if last dequeued class is
1412 -       still active and is not deficit then we can dequeue it again */
1413 -    if ((cl = q->last_tx) != NULL && cl->q->q.qlen > 0 && 
1414 -           cl->deficit[cl->rc_level & 0xff] > 0 && 
1415 -           (skb = htb_dequeue_class(sch,cl)) != NULL) {
1416 -       sch->q.qlen--;
1417 -       cl->deficit[cl->rc_level & 0xff] -= skb->len;
1418 -       sch->flags &= ~TCQ_F_THROTTLED;
1419 -       q->dcache_hits++;
1420 -       HTB_DBG(3,1,"htb_deq_hit skb=%p\n",skb);
1421 +/* dequeues packet at given priority and level; call only if
1422 +   you are sure that there is active class at prio/level */
1423 +static struct sk_buff *
1424 +htb_dequeue_tree(struct htb_sched *q,int prio,int level)
1425 +{
1426 +       struct sk_buff *skb = NULL;
1427 +       //struct htb_sched *q = (struct htb_sched *)sch->data;
1428 +       struct htb_class *cl,*start;
1429 +       /* look initial class up in the row */
1430 +       DEVIK_MSTART(6);
1431 +       start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
1432 +       
1433 +       do {
1434 +               BUG_TRAP(cl && cl->un.leaf.q->q.qlen); if (!cl) return NULL;
1435 +               HTB_DBG(4,1,"htb_deq_tr prio=%d lev=%d cl=%X defic=%d\n",
1436 +                               prio,level,cl->classid,cl->un.leaf.deficit[level]);
1437 +       
1438 +               if (likely((skb = cl->un.leaf.q->dequeue(cl->un.leaf.q)) != NULL)) 
1439 +                       break;
1440 +               if (!cl->warned) {
1441 +                       printk(KERN_WARNING "htb: class %X isn't work conserving ?!\n",cl->classid);
1442 +                       cl->warned = 1;
1443 +               }
1444 +               q->nwc_hit++;
1445 +               htb_next_rb_node((level?cl->parent->un.inner.ptr:q->ptr[0])+prio);
1446 +               cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
1447 +       } while (cl != start);
1448 +
1449 +       DEVIK_MEND(6);
1450 +       DEVIK_MSTART(7);
1451 +       if (likely(skb != NULL)) {
1452 +               if ((cl->un.leaf.deficit[level] -= skb->len) < 0) {
1453 +                       HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n",
1454 +                               level?cl->parent->un.inner.ptr[prio]:q->ptr[0][prio],cl->un.leaf.quantum);
1455 +                       cl->un.leaf.deficit[level] += cl->un.leaf.quantum;
1456 +                       htb_next_rb_node((level?cl->parent->un.inner.ptr:q->ptr[0])+prio);
1457 +               }
1458 +               /* this used to be after charge_class but this constelation
1459 +                  gives us slightly better performance */
1460 +               if (!cl->un.leaf.q->q.qlen)
1461 +                       htb_deactivate (q,cl);
1462 +       DEVIK_MSTART(8);
1463 +               htb_charge_class (q,cl,level,skb->len);
1464 +       DEVIK_MEND(8);
1465 +       }
1466 +       DEVIK_MEND(7);
1467         return skb;
1468 -    }
1469 -    q->last_tx = NULL; /* can't use cache ? invalidate */
1470 -    
1471 -    for (i = 0; i < TC_HTB_MAXDEPTH; i++) {
1472 -       /* first try: dequeue leaves (level 0) */
1473 -       oklev = TC_HTB_MAXDEPTH;
1474 -       q->trials_c++;
1475 -       for (prio = 0; prio < TC_HTB_NUMPRIO; prio++) {
1476 -           if (!q->active[prio][0]) continue;
1477 -           lev = 0; skb = htb_dequeue_prio(sch, prio, &lev);
1478 -           HTB_DBG(3,2,"htb_deq_1 i=%d p=%d skb=%p blev=%d\n",i,prio,skb,lev);
1479 -           if (skb) {
1480 -               sch->flags &= ~TCQ_F_THROTTLED;
1481 -               goto fin;
1482 -           }
1483 -           if (lev < oklev) {
1484 -               oklev = lev; okprio = prio;
1485 -           }
1486 -       }
1487 -       if (oklev >= TC_HTB_MAXDEPTH) break; 
1488 -       /* second try: use ok level we learned in first try; 
1489 -          it really should succeed */
1490 -       q->trials_c++;
1491 -       skb = htb_dequeue_prio(sch, okprio, &oklev);
1492 -       HTB_DBG(3,2,"htb_deq_2 p=%d lev=%d skb=%p\n",okprio,oklev,skb);
1493 -       if (skb) {
1494 -           sch->flags &= ~TCQ_F_THROTTLED;
1495 -           goto fin;
1496 -       }
1497 -       /* probably qdisc at oklev can't transmit - it is not good
1498 -          idea to have TBF as HTB's child ! retry with that node
1499 -          disabled */
1500 -    }
1501 -    if (i >= TC_HTB_MAXDEPTH)
1502 -       printk(KERN_ERR "htb: too many dequeue trials\n");
1503 +}
1504  
1505 -    /* no-one gave us packet, setup timer if someone wants it */
1506 -    if (sch->q.qlen && !netif_queue_stopped(sch->dev) && q->delay) {
1507 -       long delay = PSCHED_US2JIFFIE(q->delay);
1508 -       if (delay == 0) delay = 1;
1509 -       if (delay > 5*HZ) {
1510 -           if (net_ratelimit())
1511 -               printk(KERN_INFO "HTB delay %ld > 5sec\n", delay);
1512 -           delay = 5*HZ;
1513 +static void htb_delay_by(struct Qdisc *sch,long delay)
1514 +{
1515 +       struct htb_sched *q = (struct htb_sched *)sch->data;
1516 +       if (netif_queue_stopped(sch->dev)) return;
1517 +       if (delay <= 0) delay = 1;
1518 +       if (unlikely(delay > 5*HZ)) {
1519 +               if (net_ratelimit())
1520 +                       printk(KERN_INFO "HTB delay %ld > 5sec\n", delay);
1521 +               delay = 5*HZ;
1522         }
1523         del_timer(&q->timer);
1524         q->timer.expires = jiffies + delay;
1525 @@ -725,439 +1007,605 @@
1526         sch->flags |= TCQ_F_THROTTLED;
1527         sch->stats.overlimits++;
1528         HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay);
1529 -    }
1530 -fin:
1531 -    do {
1532 -       static unsigned util = 0; unsigned d;
1533 -       PSCHED_GET_TIME(endt); q->deq_rate_c++;
1534 -       d = PSCHED_TDIFF(endt,q->now);
1535 -       q->utilz_c += d; util += d;
1536 -#if 0
1537 -       /* special debug hack */
1538 -       if (skb) { 
1539 -           memcpy (skb->data+28,_dbg,sizeof(_dbg));
1540 -           memset (_dbg,0,sizeof(_dbg));
1541 +}
1542 +
1543 +static struct sk_buff *htb_dequeue(struct Qdisc *sch)
1544 +{
1545 +       struct sk_buff *skb = NULL;
1546 +       struct htb_sched *q = (struct htb_sched *)sch->data;
1547 +       int level;
1548 +       long min_delay;
1549 +
1550 +       HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue),
1551 +                       sch->q.qlen);
1552 +
1553 +       /* try to dequeue direct packets as high prio (!) to minimize cpu work */
1554 +       if ((skb = __skb_dequeue(&q->direct_queue)) != NULL) {
1555 +               sch->flags &= ~TCQ_F_THROTTLED;
1556 +               sch->q.qlen--;
1557 +               return skb;
1558 +       }
1559 +
1560 +       DEVIK_MSTART(2);
1561 +       if (!sch->q.qlen) goto fin;
1562 +       PSCHED_GET_TIME(q->now);
1563 +
1564 +       min_delay = HZ*5;
1565 +       q->nwc_hit = 0;
1566 +       for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
1567 +               /* common case optimization - skip event handler quickly */
1568 +               int m;
1569 +               long delay;
1570 +       DEVIK_MSTART(3);
1571 +               if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
1572 +                       delay = htb_do_events(q,level);
1573 +                       q->near_ev_cache[level] += delay ? delay : HZ;
1574 +               } else
1575 +                       delay = q->near_ev_cache[level] - jiffies;      
1576 +               
1577 +               if (delay && min_delay > delay) 
1578 +                       min_delay = delay;
1579 +       DEVIK_MEND(3);
1580 +       DEVIK_MSTART(5);
1581 +               m = ~q->row_mask[level];
1582 +               while (m != (int)(-1)) {
1583 +                       int prio = ffz (m);
1584 +                       m |= 1 << prio;
1585 +                       skb = htb_dequeue_tree(q,prio,level);
1586 +                       if (likely(skb != NULL)) {
1587 +                               sch->q.qlen--;
1588 +                               sch->flags &= ~TCQ_F_THROTTLED;
1589 +       DEVIK_MEND(5);
1590 +                               goto fin;
1591 +                       }
1592 +               }
1593 +       DEVIK_MEND(5);
1594 +       }
1595 +       DEVIK_MSTART(4);
1596 +#ifdef HTB_DEBUG
1597 +       if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { 
1598 +               printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay);
1599 +               htb_debug_dump(q);
1600         }
1601  #endif
1602 -    } while (0);
1603 -    HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p (28/11)\n",sch->dev->name,jiffies,skb);
1604 -    return skb;
1605 +       htb_delay_by (sch,min_delay);
1606 +       DEVIK_MEND(4);
1607 +fin:
1608 +       HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb);
1609 +       DEVIK_MEND(2);
1610 +       return skb;
1611  }
1612  
1613  /* try to drop from each class (by prio) until one succeed */
1614  static int htb_drop(struct Qdisc* sch)
1615  {
1616 -    struct htb_sched *q = (struct htb_sched *)sch->data;
1617 -    int prio;
1618 +       struct htb_sched *q = (struct htb_sched *)sch->data;
1619 +       int prio;
1620  
1621 -    for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) {
1622 -       struct htb_class *cl = q->active[prio][0];
1623 -       if (cl) do {
1624 -           if (cl->q->ops->drop && cl->q->ops->drop(cl->q)) {
1625 -               sch->q.qlen--;
1626 -               return 1;
1627 -           }
1628 -       } while ((cl = cl->active.next) != q->active[prio][0]);
1629 -    }
1630 -    return 0;
1631 +       for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) {
1632 +               struct list_head *p;
1633 +               list_for_each (p,q->drops+prio) {
1634 +                       struct htb_class *cl = list_entry(p,struct htb_class,
1635 +                                       un.leaf.drop_list);
1636 +                       if (cl->un.leaf.q->ops->drop && 
1637 +                               cl->un.leaf.q->ops->drop(cl->un.leaf.q)) {
1638 +                               sch->q.qlen--;
1639 +                               if (!cl->un.leaf.q->q.qlen)
1640 +                                       htb_deactivate (q,cl);
1641 +                               return 1;
1642 +                       }
1643 +               }
1644 +       }
1645 +       return 0;
1646  }
1647  
1648  /* reset all classes */
1649  /* always caled under BH & queue lock */
1650  static void htb_reset(struct Qdisc* sch)
1651  {
1652 -    struct htb_sched *q = (struct htb_sched *)sch->data;
1653 -    int i;
1654 -    HTB_DBG(0,1,"htb_reset sch=%X, handle=%X\n",(int)sch,sch->handle);
1655 -
1656 -    for (i = 0; i < HTB_HSIZE; i++) {
1657 -       struct htb_class *cl = q->hash[i];
1658 -       if (cl) do {
1659 -           if (cl->q) qdisc_reset(cl->q);
1660 +       struct htb_sched *q = (struct htb_sched *)sch->data;
1661 +       int i;
1662 +       HTB_DBG(0,1,"htb_reset sch=%p, handle=%X\n",sch,sch->handle);
1663 +
1664 +       for (i = 0; i < HTB_HSIZE; i++) {
1665 +               struct list_head *p;
1666 +               list_for_each (p,q->hash+i) {
1667 +                       struct htb_class *cl = list_entry(p,struct htb_class,hlist);
1668 +                       if (cl->level)
1669 +                               memset(&cl->un.inner,0,sizeof(cl->un.inner));
1670 +                       else {
1671 +                               if (cl->un.leaf.q) 
1672 +                                       qdisc_reset(cl->un.leaf.q);
1673 +                               INIT_LIST_HEAD(&cl->un.leaf.drop_list);
1674 +                       }
1675 +                       cl->prio_activity = 0;
1676 +                       cl->cmode = HTB_CAN_SEND;
1677 +#ifdef HTB_DEBUG
1678 +                       cl->pq_node.rb_color = -1;
1679 +                       memset(cl->node,255,sizeof(cl->node));
1680 +#endif
1681  
1682 -       } while ((cl = cl->hlist.next) != q->hash[i]);
1683 -    }
1684 -    sch->flags &= ~TCQ_F_THROTTLED;
1685 -    del_timer(&q->timer);
1686 -    __skb_queue_purge(&q->direct_queue);
1687 -    sch->q.qlen = 0; q->last_tx = NULL;
1688 +               }
1689 +       }
1690 +       sch->flags &= ~TCQ_F_THROTTLED;
1691 +       del_timer(&q->timer);
1692 +       __skb_queue_purge(&q->direct_queue);
1693 +       sch->q.qlen = 0;
1694 +       memset(q->row,0,sizeof(q->row));
1695 +       memset(q->row_mask,0,sizeof(q->row_mask));
1696 +       memset(q->wait_pq,0,sizeof(q->wait_pq));
1697 +       memset(q->ptr,0,sizeof(q->ptr));
1698 +       for (i = 0; i < TC_HTB_NUMPRIO; i++)
1699 +               INIT_LIST_HEAD(q->drops+i);
1700  }
1701  
1702  static int htb_init(struct Qdisc *sch, struct rtattr *opt)
1703  {
1704 -    struct htb_sched *q = (struct htb_sched*)sch->data;
1705 -    struct rtattr *tb[TCA_HTB_INIT];
1706 -    struct tc_htb_glob *gopt;
1707 -
1708 -    if (!opt || 
1709 -           rtattr_parse(tb, TCA_HTB_INIT, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
1710 -           tb[TCA_HTB_INIT-1] == NULL ||
1711 -           RTA_PAYLOAD(tb[TCA_HTB_INIT-1]) < sizeof(*gopt))
1712 -       return -EINVAL;
1713 -
1714 -    gopt = RTA_DATA(tb[TCA_HTB_INIT-1]);
1715 -    memset(q,0,sizeof(*q));
1716 -    q->debug = gopt->debug;
1717 -    HTB_DBG(0,1,"htb_init sch=%p handle=%X r2q=%d\n",sch,sch->handle,gopt->rate2quantum);
1718 -    init_timer(&q->timer);
1719 -    init_timer(&q->rttim);
1720 -    skb_queue_head_init(&q->direct_queue);
1721 -    q->direct_qlen = sch->dev->tx_queue_len;
1722 -    q->timer.function = htb_timer;
1723 -    q->timer.data = (unsigned long)sch;
1724 -    q->rttim.function = htb_rate_timer;
1725 -    q->rttim.data = (unsigned long)sch;
1726 -    q->rttim.expires = jiffies + HZ;
1727 -    add_timer(&q->rttim);
1728 -    if ((q->rate2quantum = gopt->rate2quantum) < 1)
1729 -       q->rate2quantum = 1;
1730 -    q->defcls = gopt->defcls;
1731 -    q->use_dcache = gopt->use_dcache;
1732 +       struct htb_sched *q = (struct htb_sched*)sch->data;
1733 +       struct rtattr *tb[TCA_HTB_INIT];
1734 +       struct tc_htb_glob *gopt;
1735 +       int i;
1736 +#ifdef HTB_DEBUG
1737 +       printk(KERN_INFO "HTB init, kernel part version %d.%d\n",
1738 +                         HTB_VER >> 16,HTB_VER & 0xffff);
1739 +#endif
1740 +       if (!opt || rtattr_parse(tb, TCA_HTB_INIT, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
1741 +                       tb[TCA_HTB_INIT-1] == NULL ||
1742 +                       RTA_PAYLOAD(tb[TCA_HTB_INIT-1]) < sizeof(*gopt)) {
1743 +               printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
1744 +               return -EINVAL;
1745 +       }
1746 +       gopt = RTA_DATA(tb[TCA_HTB_INIT-1]);
1747 +       if (gopt->version != HTB_VER >> 16) {
1748 +               printk(KERN_ERR "HTB: need tc/htb version %d (minor is %d), you have %d\n",
1749 +                               HTB_VER >> 16,HTB_VER & 0xffff,gopt->version);
1750 +               return -EINVAL;
1751 +       }
1752 +       memset(q,0,sizeof(*q));
1753 +       q->debug = gopt->debug;
1754 +       HTB_DBG(0,1,"htb_init sch=%p handle=%X r2q=%d\n",sch,sch->handle,gopt->rate2quantum);
1755 +
1756 +       INIT_LIST_HEAD(&q->root);
1757 +       for (i = 0; i < HTB_HSIZE; i++)
1758 +               INIT_LIST_HEAD(q->hash+i);
1759 +       for (i = 0; i < TC_HTB_NUMPRIO; i++)
1760 +               INIT_LIST_HEAD(q->drops+i);
1761 +
1762 +       init_timer(&q->timer);
1763 +       skb_queue_head_init(&q->direct_queue);
1764 +
1765 +       q->direct_qlen = sch->dev->tx_queue_len;
1766 +       if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */
1767 +               q->direct_qlen = 2;
1768 +       q->timer.function = htb_timer;
1769 +       q->timer.data = (unsigned long)sch;
1770 +
1771 +#ifdef HTB_RATECM
1772 +       init_timer(&q->rttim);
1773 +       q->rttim.function = htb_rate_timer;
1774 +       q->rttim.data = (unsigned long)sch;
1775 +       q->rttim.expires = jiffies + HZ;
1776 +       add_timer(&q->rttim);
1777 +#endif
1778 +       if ((q->rate2quantum = gopt->rate2quantum) < 1)
1779 +               q->rate2quantum = 1;
1780 +       q->defcls = gopt->defcls;
1781  
1782 -    MOD_INC_USE_COUNT;
1783 -    return 0;
1784 +       MOD_INC_USE_COUNT;
1785 +       return 0;
1786  }
1787  
1788 -#ifdef CONFIG_RTNETLINK
1789  static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
1790  {
1791 -    struct htb_sched *q = (struct htb_sched*)sch->data;
1792 -    unsigned char       *b = skb->tail;
1793 -    struct rtattr *rta;
1794 -    struct tc_htb_glob gopt;
1795 -    HTB_DBG(0,1,"htb_dump sch=%p, handle=%X\n",sch,sch->handle);
1796 -    /* stats */
1797 -    HTB_QLOCK(sch);
1798 -    gopt.deq_rate = q->deq_rate/HTB_EWMAC;
1799 -    gopt.utilz = q->utilz/HTB_EWMAC;
1800 -    gopt.trials = q->trials/HTB_EWMAC;
1801 -    gopt.dcache_hits = q->dcache_hits;
1802 -    gopt.direct_pkts = q->direct_pkts;
1803 -
1804 -    gopt.use_dcache = q->use_dcache;
1805 -    gopt.rate2quantum = q->rate2quantum;
1806 -    gopt.defcls = q->defcls;
1807 -    gopt.debug = q->debug;
1808 -    rta = (struct rtattr*)b;
1809 -    RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1810 -    RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
1811 -    rta->rta_len = skb->tail - b;
1812 -    sch->stats.qlen = sch->q.qlen;
1813 -    RTA_PUT(skb, TCA_STATS, sizeof(sch->stats), &sch->stats);
1814 -    HTB_QUNLOCK(sch);
1815 -    return skb->len;
1816 +       struct htb_sched *q = (struct htb_sched*)sch->data;
1817 +       unsigned char    *b = skb->tail;
1818 +       struct rtattr *rta;
1819 +       struct tc_htb_glob gopt;
1820 +       HTB_DBG(0,1,"htb_dump sch=%p, handle=%X\n",sch,sch->handle);
1821 +       /* stats */
1822 +       HTB_QLOCK(sch);
1823 +       gopt.direct_pkts = q->direct_pkts;
1824 +
1825 +#ifdef HTB_DEBUG
1826 +       htb_debug_dump(q);
1827 +#endif
1828 +       gopt.version = HTB_VER;
1829 +       gopt.rate2quantum = q->rate2quantum;
1830 +       gopt.defcls = q->defcls;
1831 +       gopt.debug = q->debug;
1832 +       rta = (struct rtattr*)b;
1833 +       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1834 +       RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
1835 +       rta->rta_len = skb->tail - b;
1836 +       sch->stats.qlen = sch->q.qlen;
1837 +       RTA_PUT(skb, TCA_STATS, sizeof(sch->stats), &sch->stats);
1838 +       HTB_QUNLOCK(sch);
1839 +       return skb->len;
1840  rtattr_failure:
1841 -    HTB_QUNLOCK(sch);
1842 -    skb_trim(skb, skb->tail - skb->data);
1843 -    return -1;
1844 +       HTB_QUNLOCK(sch);
1845 +       skb_trim(skb, skb->tail - skb->data);
1846 +       return -1;
1847  }
1848  
1849 -static int
1850 -htb_dump_class(struct Qdisc *sch, unsigned long arg,
1851 +static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1852         struct sk_buff *skb, struct tcmsg *tcm)
1853  {
1854 -    struct htb_sched *q = (struct htb_sched*)sch->data;
1855 -    struct htb_class *cl = (struct htb_class*)arg;
1856 -    unsigned char       *b = skb->tail;
1857 -    struct rtattr *rta;
1858 -    struct tc_htb_opt opt;
1859 -
1860 -    HTB_DBG(0,1,"htb_dump_class handle=%X clid=%X\n",sch->handle,cl->classid);
1861 -
1862 -    HTB_QLOCK(sch);
1863 -    tcm->tcm_parent = cl->parent ? cl->parent->classid : TC_H_ROOT;
1864 -    tcm->tcm_handle = cl->classid;
1865 -    if (cl->q) {
1866 -       tcm->tcm_info = cl->q->handle;
1867 -       cl->stats.qlen = cl->q->q.qlen;
1868 -    }
1869 +#ifdef HTB_DEBUG
1870 +       struct htb_sched *q = (struct htb_sched*)sch->data;
1871 +#endif
1872 +       struct htb_class *cl = (struct htb_class*)arg;
1873 +       unsigned char    *b = skb->tail;
1874 +       struct rtattr *rta;
1875 +       struct tc_htb_opt opt;
1876 +
1877 +       HTB_DBG(0,1,"htb_dump_class handle=%X clid=%X\n",sch->handle,cl->classid);
1878 +
1879 +       HTB_QLOCK(sch);
1880 +       tcm->tcm_parent = cl->parent ? cl->parent->classid : TC_H_ROOT;
1881 +       tcm->tcm_handle = cl->classid;
1882 +       if (!cl->level && cl->un.leaf.q) {
1883 +               tcm->tcm_info = cl->un.leaf.q->handle;
1884 +               cl->stats.qlen = cl->un.leaf.q->q.qlen;
1885 +       }
1886 +
1887 +       rta = (struct rtattr*)b;
1888 +       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1889  
1890 -    rta = (struct rtattr*)b;
1891 -    RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
1892 +       memset (&opt,0,sizeof(opt));
1893  
1894 -    memset (&opt,0,sizeof(opt));
1895 +       opt.rate = cl->rate->rate; opt.buffer = cl->buffer;
1896 +       opt.ceil = cl->ceil->rate; opt.cbuffer = cl->cbuffer;
1897 +       opt.quantum = cl->un.leaf.quantum; opt.prio = cl->un.leaf.prio;
1898 +       opt.level = cl->level; 
1899 +       RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
1900 +       rta->rta_len = skb->tail - b;
1901 +
1902 +#ifdef HTB_RATECM
1903 +       cl->stats.bps = cl->rate_bytes/(HTB_EWMAC*HTB_HSIZE);
1904 +       cl->stats.pps = cl->rate_packets/(HTB_EWMAC*HTB_HSIZE);
1905 +#endif
1906  
1907 -    opt.rate = cl->rate->rate; opt.buffer = cl->buffer;
1908 -    opt.ceil = cl->ceil->rate; opt.cbuffer = cl->cbuffer;
1909 -    opt.quantum = cl->quantum; opt.prio = cl->prio;
1910 -    opt.level = cl->level; opt.injectd = cl->injectd;
1911 -    RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
1912 -    rta->rta_len = skb->tail - b;
1913 -
1914 -    cl->stats.bps = cl->rate_bytes/(HTB_EWMAC*HTB_HSIZE);
1915 -    cl->stats.pps = cl->rate_packets/(HTB_EWMAC*HTB_HSIZE);
1916 -
1917 -    cl->xstats.tokens = cl->tokens;
1918 -    cl->xstats.ctokens = cl->ctokens;
1919 -    RTA_PUT(skb, TCA_STATS, sizeof(cl->stats), &cl->stats);
1920 -    RTA_PUT(skb, TCA_XSTATS, sizeof(cl->xstats), &cl->xstats);
1921 -    HTB_QUNLOCK(sch);
1922 -    return skb->len;
1923 +       cl->xstats.tokens = cl->tokens;
1924 +       cl->xstats.ctokens = cl->ctokens;
1925 +       RTA_PUT(skb, TCA_STATS, sizeof(cl->stats), &cl->stats);
1926 +       RTA_PUT(skb, TCA_XSTATS, sizeof(cl->xstats), &cl->xstats);
1927 +       HTB_QUNLOCK(sch);
1928 +       return skb->len;
1929  rtattr_failure:
1930 -    HTB_QUNLOCK(sch);
1931 -    skb_trim(skb, b - skb->data);
1932 -    return -1;
1933 +       HTB_QUNLOCK(sch);
1934 +       skb_trim(skb, b - skb->data);
1935 +       return -1;
1936  }
1937 -#endif
1938  
1939  static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1940         struct Qdisc **old)
1941  {
1942 -    struct htb_class *cl = (struct htb_class*)arg;
1943 +       struct htb_class *cl = (struct htb_class*)arg;
1944  
1945 -    if (cl && !cl->level) {
1946 -       if (new == NULL) {
1947 -           if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)) == NULL)
1948 -               return -ENOBUFS;
1949 -       } 
1950 -       if ((*old = xchg(&cl->q, new)) != NULL) /* xchg is atomical :-) */
1951 -           qdisc_reset(*old);
1952 -       return 0;
1953 -    }
1954 -    return -ENOENT;
1955 +       if (cl && !cl->level) {
1956 +               if (new == NULL && (new = qdisc_create_dflt(sch->dev, 
1957 +                                       &pfifo_qdisc_ops)) == NULL)
1958 +                                       return -ENOBUFS;
1959 +               sch_tree_lock(sch);
1960 +               if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) {
1961 +                       /* TODO: is it correct ? Why CBQ doesn't do it ? */
1962 +                       sch->q.qlen -= (*old)->q.qlen;  
1963 +                       qdisc_reset(*old);
1964 +               }
1965 +               sch_tree_unlock(sch);
1966 +               return 0;
1967 +       }
1968 +       return -ENOENT;
1969  }
1970  
1971 -static struct Qdisc *
1972 -htb_leaf(struct Qdisc *sch, unsigned long arg)
1973 +static struct Qdisc * htb_leaf(struct Qdisc *sch, unsigned long arg)
1974  {
1975 -    struct htb_class *cl = (struct htb_class*)arg;
1976 -    return cl ? cl->q : NULL;
1977 +       struct htb_class *cl = (struct htb_class*)arg;
1978 +       return (cl && !cl->level) ? cl->un.leaf.q : NULL;
1979  }
1980  
1981  static unsigned long htb_get(struct Qdisc *sch, u32 classid)
1982  {
1983 -    struct htb_sched *q = (struct htb_sched *)sch->data;
1984 -    struct htb_class *cl = htb_find(classid,sch);
1985 -    HTB_DBG(0,1,"htb_get clid=%X q=%p cl=%p ref=%d\n",classid,q,cl,cl?cl->refcnt:0);
1986 -    if (cl) cl->refcnt++;
1987 -    return (unsigned long)cl;
1988 +#ifdef HTB_DEBUG
1989 +       struct htb_sched *q = (struct htb_sched *)sch->data;
1990 +#endif
1991 +       struct htb_class *cl = htb_find(classid,sch);
1992 +       HTB_DBG(0,1,"htb_get clid=%X q=%p cl=%p ref=%d\n",classid,q,cl,cl?cl->refcnt:0);
1993 +       if (cl) 
1994 +               cl->refcnt++;
1995 +       return (unsigned long)cl;
1996  }
1997  
1998  static void htb_destroy_filters(struct tcf_proto **fl)
1999  {
2000 -    struct tcf_proto *tp;
2001 +       struct tcf_proto *tp;
2002  
2003 -    while ((tp = *fl) != NULL) {
2004 -       *fl = tp->next;
2005 -       tp->ops->destroy(tp);
2006 -    }
2007 +       while ((tp = *fl) != NULL) {
2008 +               *fl = tp->next;
2009 +               tp->ops->destroy(tp);
2010 +       }
2011  }
2012  
2013  static void htb_destroy_class(struct Qdisc* sch,struct htb_class *cl)
2014  {
2015 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2016 -    HTB_DBG(0,1,"htb_destrycls clid=%X q=%p ref=%d\n", cl?cl->classid:0,cl->q,cl?cl->refcnt:0);
2017 -    if (cl->q) qdisc_destroy(cl->q);
2018 -    qdisc_put_rtab(cl->rate);
2019 -    qdisc_put_rtab(cl->ceil);
2020 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2021 +       HTB_DBG(0,1,"htb_destrycls clid=%X ref=%d\n", cl?cl->classid:0,cl?cl->refcnt:0);
2022 +       if (!cl->level) {
2023 +               BUG_TRAP(cl->un.leaf.q);
2024 +               sch->q.qlen -= cl->un.leaf.q->q.qlen;
2025 +               qdisc_destroy(cl->un.leaf.q);
2026 +       }
2027 +       qdisc_put_rtab(cl->rate);
2028 +       qdisc_put_rtab(cl->ceil);
2029 +       
2030  #ifdef CONFIG_NET_ESTIMATOR
2031 -    qdisc_kill_estimator(&cl->stats);
2032 +       qdisc_kill_estimator(&cl->stats);
2033  #endif
2034 -    htb_destroy_filters (&cl->filter_list);
2035 -    /* remove children */
2036 -    while (cl->children) htb_destroy_class (sch,cl->children);
2037 -
2038 -    /* remove class from all lists it is on */
2039 -    q->last_tx = NULL;
2040 -    if (cl->hlist.prev)
2041 -       HTB_DELETE(hlist,cl,q->hash[htb_hash(cl->classid)]);
2042 -    if (cl->active.prev) 
2043 -       htb_deactivate (q,cl,0);
2044 -    if (cl->parent) 
2045 -       HTB_DELETE(sibling,cl,cl->parent->children);
2046 -    else
2047 -       HTB_DELETE(sibling,cl,q->root);
2048 -
2049 -    kfree(cl);
2050 +       htb_destroy_filters (&cl->filter_list);
2051 +       
2052 +       while (!list_empty(&cl->children)) 
2053 +               htb_destroy_class (sch,list_entry(cl->children.next,
2054 +                                       struct htb_class,sibling));
2055 +
2056 +       /* note: this delete may happen twice (see htb_delete) */
2057 +       list_del(&cl->hlist);
2058 +       list_del(&cl->sibling);
2059 +       
2060 +       if (cl->prio_activity)
2061 +               htb_deactivate (q,cl);
2062 +       
2063 +       if (cl->cmode != HTB_CAN_SEND)
2064 +               htb_safe_rb_erase(&cl->pq_node,q->wait_pq+cl->level);
2065 +       
2066 +       kfree(cl);
2067  }
2068  
2069  /* always caled under BH & queue lock */
2070  static void htb_destroy(struct Qdisc* sch)
2071  {
2072 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2073 -    HTB_DBG(0,1,"htb_destroy q=%p\n",q);
2074 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2075 +       HTB_DBG(0,1,"htb_destroy q=%p\n",q);
2076  
2077 -    del_timer_sync (&q->timer);
2078 -    del_timer_sync (&q->rttim);
2079 -    while (q->root) htb_destroy_class(sch,q->root);
2080 -    htb_destroy_filters(&q->filter_list);
2081 -    __skb_queue_purge(&q->direct_queue);
2082 -    MOD_DEC_USE_COUNT;
2083 +       del_timer_sync (&q->timer);
2084 +#ifdef HTB_RATECM
2085 +       del_timer_sync (&q->rttim);
2086 +#endif
2087 +       while (!list_empty(&q->root)) 
2088 +               htb_destroy_class (sch,list_entry(q->root.next,
2089 +                                       struct htb_class,sibling));
2090 +
2091 +       htb_destroy_filters(&q->filter_list);
2092 +       __skb_queue_purge(&q->direct_queue);
2093 +       MOD_DEC_USE_COUNT;
2094  }
2095  
2096 -static void htb_put(struct Qdisc *sch, unsigned long arg)
2097 +static int htb_delete(struct Qdisc *sch, unsigned long arg)
2098  {
2099 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2100 -    struct htb_class *cl = (struct htb_class*)arg;
2101 -    HTB_DBG(0,1,"htb_put q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0);
2102 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2103 +       struct htb_class *cl = (struct htb_class*)arg;
2104 +       HTB_DBG(0,1,"htb_delete q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0);
2105 +
2106 +       // TODO: why don't allow to delete subtree ? references ? does
2107 +       // tc subsys quarantee us that in htb_destroy it holds no class
2108 +       // refs so that we can remove children safely there ?
2109 +       if (!list_empty(&cl->children) || cl->filter_cnt)
2110 +               return -EBUSY;
2111 +       
2112 +       sch_tree_lock(sch);
2113 +       
2114 +       /* delete from hash and active; remainder in destroy_class */
2115 +       list_del_init(&cl->hlist);
2116 +       if (cl->prio_activity)
2117 +               htb_deactivate (q,cl);
2118 +
2119 +       if (--cl->refcnt == 0)
2120 +               htb_destroy_class(sch,cl);
2121  
2122 -    if (--cl->refcnt == 0)
2123 -       htb_destroy_class(sch,cl);
2124 +       sch_tree_unlock(sch);
2125 +       return 0;
2126  }
2127  
2128 -static int
2129 -htb_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **tca,
2130 -       unsigned long *arg)
2131 +static void htb_put(struct Qdisc *sch, unsigned long arg)
2132  {
2133 -    int err = -EINVAL,h;
2134 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2135 -    struct htb_class *cl = (struct htb_class*)*arg,*parent;
2136 -    struct rtattr *opt = tca[TCA_OPTIONS-1];
2137 -    struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
2138 -    struct rtattr *tb[TCA_HTB_RTAB];
2139 -    struct tc_htb_opt *hopt;
2140 -
2141 -    if (parentid == TC_H_ROOT) parent = NULL; 
2142 -    else parent = htb_find (parentid,sch);
2143 -
2144 -    /* extract all subattrs from opt attr */
2145 -    if (!opt || 
2146 -           rtattr_parse(tb, TCA_HTB_RTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
2147 -           tb[TCA_HTB_PARMS-1] == NULL ||
2148 -           RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt))
2149 -       goto failure;
2150 -
2151 -    hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]);
2152 -    HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
2153 -    rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]);
2154 -    ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]);
2155 -    if (!rtab || !ctab) goto failure;
2156 -
2157 -    if (!cl) { /* new class */
2158 -       /* check maximal depth */
2159 -       if (parent && parent->parent && parent->parent->level < 2) {
2160 -           printk(KERN_ERR "htb: tree is too deep\n");
2161 -           goto failure;
2162 -       }
2163 -       err = -ENOBUFS;
2164 -       cl = kmalloc(sizeof(*cl), GFP_KERNEL);
2165 -       if (cl == NULL) goto failure;
2166 -       memset(cl, 0, sizeof(*cl));
2167 -       cl->refcnt = 1; cl->level = 0; /* assume leaf */
2168 -
2169 -       if (parent && !parent->level) {
2170 -           /* turn parent into inner node */
2171 -           qdisc_destroy (parent->q); parent->q = &noop_qdisc;
2172 -           parent->level = (parent->parent ? 
2173 -                   parent->parent->level : TC_HTB_MAXDEPTH) - 1;
2174 -       }
2175 -       /* leaf (we) needs elementary qdisc */
2176 -       if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
2177 -           cl->q = &noop_qdisc;
2178 -
2179 -       cl->classid = classid; cl->parent = parent;
2180 -       cl->tokens = hopt->buffer;
2181 -       cl->ctokens = hopt->cbuffer;
2182 -       cl->mbuffer = 60000000; /* 1min */
2183 -       PSCHED_GET_TIME(cl->t_c);
2184 +#ifdef HTB_DEBUG
2185 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2186 +#endif
2187 +       struct htb_class *cl = (struct htb_class*)arg;
2188 +       HTB_DBG(0,1,"htb_put q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0);
2189  
2190 -       /* attach to the hash list and parent's family */
2191 -       sch_tree_lock(sch);
2192 -       h = htb_hash(classid);
2193 -       if (!cl->hlist.prev)
2194 -           HTB_INSERTB(hlist,q->hash[h],cl);
2195 -       if (parent) 
2196 -           HTB_INSERTB(sibling,parent->children,cl);
2197 -       else HTB_INSERTB(sibling,q->root,cl);
2198 -
2199 -    } else sch_tree_lock(sch);
2200 -
2201 -    q->last_tx = NULL;
2202 -    cl->quantum = rtab->rate.rate / q->rate2quantum;
2203 -    cl->injectd = hopt->injectd;
2204 -    if (cl->quantum < 100) cl->quantum = 100;
2205 -    if (cl->quantum > 60000) cl->quantum = 60000;
2206 -    if ((cl->prio = hopt->prio) >= TC_HTB_NUMPRIO)
2207 -       cl->prio = TC_HTB_NUMPRIO - 1;
2208 -
2209 -    cl->buffer = hopt->buffer;
2210 -    cl->cbuffer = hopt->cbuffer;
2211 -    if (cl->rate) qdisc_put_rtab(cl->rate); cl->rate = rtab;
2212 -    if (cl->ceil) qdisc_put_rtab(cl->ceil); cl->ceil = ctab;
2213 -    sch_tree_unlock(sch);
2214 +       if (--cl->refcnt == 0)
2215 +               htb_destroy_class(sch,cl);
2216 +}
2217  
2218 -    *arg = (unsigned long)cl;
2219 -    return 0;
2220 +static int htb_change_class(struct Qdisc *sch, u32 classid, 
2221 +               u32 parentid, struct rtattr **tca, unsigned long *arg)
2222 +{
2223 +       int err = -EINVAL;
2224 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2225 +       struct htb_class *cl = (struct htb_class*)*arg,*parent;
2226 +       struct rtattr *opt = tca[TCA_OPTIONS-1];
2227 +       struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
2228 +       struct rtattr *tb[TCA_HTB_RTAB];
2229 +       struct tc_htb_opt *hopt;
2230 +
2231 +       /* extract all subattrs from opt attr */
2232 +       if (!opt || rtattr_parse(tb, TCA_HTB_RTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
2233 +                       tb[TCA_HTB_PARMS-1] == NULL ||
2234 +                       RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt))
2235 +               goto failure;
2236 +       
2237 +       parent = parentid == TC_H_ROOT ? NULL : htb_find (parentid,sch);
2238 +
2239 +       hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]);
2240 +       HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
2241 +       rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]);
2242 +       ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]);
2243 +       if (!rtab || !ctab) goto failure;
2244 +
2245 +       if (!cl) { /* new class */
2246 +               /* check for valid classid */
2247 +               if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch))
2248 +                       goto failure;
2249 +
2250 +               /* check maximal depth */
2251 +               if (parent && parent->parent && parent->parent->level < 2) {
2252 +                       printk(KERN_ERR "htb: tree is too deep\n");
2253 +                       goto failure;
2254 +               }
2255 +               err = -ENOBUFS;
2256 +               if ((cl = kmalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
2257 +                       goto failure;
2258 +               
2259 +               memset(cl, 0, sizeof(*cl));
2260 +               cl->refcnt = 1;
2261 +               INIT_LIST_HEAD(&cl->sibling);
2262 +               INIT_LIST_HEAD(&cl->hlist);
2263 +               INIT_LIST_HEAD(&cl->children);
2264 +               INIT_LIST_HEAD(&cl->un.leaf.drop_list);
2265 +#ifdef HTB_DEBUG
2266 +               cl->magic = HTB_CMAGIC;
2267 +#endif
2268  
2269 -failure:
2270 -    if (rtab) qdisc_put_rtab(rtab);
2271 -    if (ctab) qdisc_put_rtab(ctab);
2272 -    return err;
2273 -}
2274 +               sch_tree_lock(sch);
2275 +               if (parent && !parent->level) {
2276 +                       /* turn parent into inner node */
2277 +                       sch->q.qlen -= parent->un.leaf.q->q.qlen;
2278 +                       qdisc_destroy (parent->un.leaf.q);
2279 +                       if (parent->prio_activity) 
2280 +                               htb_deactivate (q,parent);
2281 +
2282 +                       /* remove from evt list because of level change */
2283 +                       if (parent->cmode != HTB_CAN_SEND) {
2284 +                               htb_safe_rb_erase(&parent->pq_node,q->wait_pq /*+0*/);
2285 +                               parent->cmode = HTB_CAN_SEND;
2286 +                       }
2287 +                       parent->level = (parent->parent ? parent->parent->level
2288 +                                       : TC_HTB_MAXDEPTH) - 1;
2289 +                       memset (&parent->un.inner,0,sizeof(parent->un.inner));
2290 +               }
2291 +               /* leaf (we) needs elementary qdisc */
2292 +               if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
2293 +                       cl->un.leaf.q = &noop_qdisc;
2294 +
2295 +               cl->classid = classid; cl->parent = parent;
2296 +
2297 +               /* set class to be in HTB_CAN_SEND state */
2298 +               cl->tokens = hopt->buffer;
2299 +               cl->ctokens = hopt->cbuffer;
2300 +               cl->mbuffer = 60000000; /* 1min */
2301 +               PSCHED_GET_TIME(cl->t_c);
2302 +               cl->cmode = HTB_CAN_SEND;
2303 +
2304 +               /* attach to the hash list and parent's family */
2305 +               list_add_tail(&cl->hlist, q->hash+htb_hash(classid));
2306 +               list_add_tail(&cl->sibling, parent ? &parent->children : &q->root);
2307 +#ifdef HTB_DEBUG
2308 +               { 
2309 +                       int i;
2310 +                       for (i = 0; i < TC_HTB_NUMPRIO; i++) cl->node[i].rb_color = -1;
2311 +                       cl->pq_node.rb_color = -1;
2312 +               }
2313 +#endif
2314 +       } else sch_tree_lock(sch);
2315  
2316 -static int htb_delete(struct Qdisc *sch, unsigned long arg)
2317 -{
2318 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2319 -    struct htb_class *cl = (struct htb_class*)arg;
2320 -    HTB_DBG(0,1,"htb_delete q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0);
2321 +       /* it used to be a nasty bug here, we have to check that node
2322 +           is really leaf before changing cl->un.leaf ! */
2323 +       if (!cl->level) {
2324 +               cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
2325 +               if (!hopt->quantum && cl->un.leaf.quantum < 1000) {
2326 +                       printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid);
2327 +                       cl->un.leaf.quantum = 1000;
2328 +               }
2329 +               if (!hopt->quantum && cl->un.leaf.quantum > 200000) {
2330 +                       printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid);
2331 +                       cl->un.leaf.quantum = 200000;
2332 +               }
2333 +               if (hopt->quantum)
2334 +                       cl->un.leaf.quantum = hopt->quantum;
2335 +               if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO)
2336 +                       cl->un.leaf.prio = TC_HTB_NUMPRIO - 1;
2337 +       }
2338  
2339 -    if (cl->children || cl->filter_cnt) return -EBUSY;
2340 -    sch_tree_lock(sch);
2341 -    /* delete from hash and active; remainder in destroy_class */
2342 -    if (cl->hlist.prev)
2343 -       HTB_DELETE(hlist,cl,q->hash[htb_hash(cl->classid)]);
2344 -    if (cl->active.prev) 
2345 -       htb_deactivate (q,cl,0);
2346 -    q->last_tx = NULL;
2347 +       cl->buffer = hopt->buffer;
2348 +       cl->cbuffer = hopt->cbuffer;
2349 +       if (cl->rate) qdisc_put_rtab(cl->rate); cl->rate = rtab;
2350 +       if (cl->ceil) qdisc_put_rtab(cl->ceil); cl->ceil = ctab;
2351 +       sch_tree_unlock(sch);
2352  
2353 -    if (--cl->refcnt == 0)
2354 -       htb_destroy_class(sch,cl);
2355 +       *arg = (unsigned long)cl;
2356 +       return 0;
2357  
2358 -    sch_tree_unlock(sch);
2359 -    return 0;
2360 +failure:
2361 +       if (rtab) qdisc_put_rtab(rtab);
2362 +       if (ctab) qdisc_put_rtab(ctab);
2363 +       return err;
2364  }
2365  
2366  static struct tcf_proto **htb_find_tcf(struct Qdisc *sch, unsigned long arg)
2367  {
2368 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2369 -    struct htb_class *cl = (struct htb_class *)arg;
2370 -    struct tcf_proto **fl = cl ? &cl->filter_list : &q->filter_list;
2371 -    HTB_DBG(0,2,"htb_tcf q=%p clid=%X fref=%d fl=%p\n",q,cl?cl->classid:0,cl?cl->filter_cnt:q->filter_cnt,*fl);
2372 -    return fl;
2373 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2374 +       struct htb_class *cl = (struct htb_class *)arg;
2375 +       struct tcf_proto **fl = cl ? &cl->filter_list : &q->filter_list;
2376 +       HTB_DBG(0,2,"htb_tcf q=%p clid=%X fref=%d fl=%p\n",q,cl?cl->classid:0,cl?cl->filter_cnt:q->filter_cnt,*fl);
2377 +       return fl;
2378  }
2379  
2380  static unsigned long htb_bind_filter(struct Qdisc *sch, unsigned long parent,
2381         u32 classid)
2382  {
2383 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2384 -    struct htb_class *cl = htb_find (classid,sch);
2385 -    HTB_DBG(0,2,"htb_bind q=%p clid=%X cl=%p fref=%d\n",q,classid,cl,cl?cl->filter_cnt:q->filter_cnt);
2386 -    if (cl && !cl->level) return 0;
2387 -    if (cl) cl->filter_cnt++; else q->filter_cnt++;
2388 -    return (unsigned long)cl;
2389 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2390 +       struct htb_class *cl = htb_find (classid,sch);
2391 +       HTB_DBG(0,2,"htb_bind q=%p clid=%X cl=%p fref=%d\n",q,classid,cl,cl?cl->filter_cnt:q->filter_cnt);
2392 +       /*if (cl && !cl->level) return 0;
2393 +         The line above used to be there to prevent attaching filters to 
2394 +         leaves. But at least tc_index filter uses this just to get class 
2395 +         for other reasons so that we have to allow for it.
2396 +         ----
2397 +         19.6.2002 As Werner explained it is ok - bind filter is just
2398 +         another way to "lock" the class - unlike "get" this lock can
2399 +         be broken by class during destroy IIUC.
2400 +        */
2401 +       if (cl) 
2402 +               cl->filter_cnt++; 
2403 +       else 
2404 +               q->filter_cnt++;
2405 +       return (unsigned long)cl;
2406  }
2407  
2408  static void htb_unbind_filter(struct Qdisc *sch, unsigned long arg)
2409  {
2410 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2411 -    struct htb_class *cl = (struct htb_class *)arg;
2412 -    HTB_DBG(0,2,"htb_unbind q=%p cl=%p fref=%d\n",q,cl,cl?cl->filter_cnt:q->filter_cnt);
2413 -    if (cl) cl->filter_cnt--; else q->filter_cnt--;
2414 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2415 +       struct htb_class *cl = (struct htb_class *)arg;
2416 +       HTB_DBG(0,2,"htb_unbind q=%p cl=%p fref=%d\n",q,cl,cl?cl->filter_cnt:q->filter_cnt);
2417 +       if (cl) 
2418 +               cl->filter_cnt--; 
2419 +       else 
2420 +               q->filter_cnt--;
2421  }
2422  
2423  static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg)
2424  {
2425 -    struct htb_sched *q = (struct htb_sched *)sch->data;
2426 -    int i;
2427 +       struct htb_sched *q = (struct htb_sched *)sch->data;
2428 +       int i;
2429  
2430 -    if (arg->stop)
2431 -       return;
2432 -
2433 -    for (i = 0; i < HTB_HSIZE; i++) {
2434 -       struct htb_class *cl = q->hash[i];
2435 -       if (cl) do {
2436 -           if (arg->count < arg->skip) {
2437 -               arg->count++;
2438 -               continue;
2439 -           }
2440 -           if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
2441 -               arg->stop = 1;
2442 +       if (arg->stop)
2443                 return;
2444 -           }
2445 -           arg->count++;
2446  
2447 -       } while ((cl = cl->hlist.next) != q->hash[i]);
2448 -    }
2449 +       for (i = 0; i < HTB_HSIZE; i++) {
2450 +               struct list_head *p;
2451 +               list_for_each (p,q->hash+i) {
2452 +                       struct htb_class *cl = list_entry(p,struct htb_class,hlist);
2453 +                       if (arg->count < arg->skip) {
2454 +                               arg->count++;
2455 +                               continue;
2456 +                       }
2457 +                       if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
2458 +                               arg->stop = 1;
2459 +                               return;
2460 +                       }
2461 +                       arg->count++;
2462 +               }
2463 +       }
2464  }
2465  
2466  static struct Qdisc_class_ops htb_class_ops =
2467 @@ -1174,9 +1622,7 @@
2468      htb_bind_filter,
2469      htb_unbind_filter,
2470  
2471 -#ifdef CONFIG_RTNETLINK
2472      htb_dump_class,
2473 -#endif
2474  };
2475  
2476  struct Qdisc_ops htb_qdisc_ops =
2477 @@ -1196,9 +1642,7 @@
2478      htb_destroy,
2479      NULL /* htb_change */,
2480  
2481 -#ifdef CONFIG_RTNETLINK
2482      htb_dump,
2483 -#endif
2484  };
2485  
2486  #ifdef MODULE
This page took 0.201717 seconds and 3 git commands to generate.