diff -Nurp linux-2.6.22-660/net/sched/sch_htb.c linux-2.6.22-670/net/sched/sch_htb.c --- linux-2.6.22-660/net/sched/sch_htb.c 2007-07-09 01:32:17.000000000 +0200 +++ linux-2.6.22-670/net/sched/sch_htb.c 2008-11-12 17:35:17.000000000 +0100 @@ -71,7 +71,7 @@ #define HTB_HSIZE 16 /* classid hash size */ #define HTB_EWMAC 2 /* rate average over HTB_EWMAC*HTB_HSIZE sec */ #define HTB_RATECM 1 /* whether to use rate computer */ -#define HTB_HYSTERESIS 1 /* whether to use mode hysteresis for speedup */ +#define HTB_HYSTERESIS 0 /* whether to use mode hysteresis for speedup */ #define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */ #if HTB_VER >> 16 != TC_HTB_PROTOVER @@ -153,15 +153,12 @@ struct htb_class { /* of un.leaf originals should be done. */ }; -/* TODO: maybe compute rate when size is too large .. or drop ? */ static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate, int size) { int slot = size >> rate->rate.cell_log; - if (slot > 255) { - cl->xstats.giants++; - slot = 255; - } + if (slot > 255) + return (rate->data[255]*(slot >> 8) + rate->data[slot & 0xFF]); return rate->data[slot]; } @@ -634,13 +631,13 @@ static int htb_enqueue(struct sk_buff *s cl->qstats.drops++; return NET_XMIT_DROP; } else { - cl->bstats.packets++; + cl->bstats.packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; cl->bstats.bytes += skb->len; htb_activate(q, cl); } sch->q.qlen++; - sch->bstats.packets++; + sch->bstats.packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; sch->bstats.bytes += skb->len; return NET_XMIT_SUCCESS; } @@ -717,8 +714,9 @@ static void htb_rate_timer(unsigned long * In such case we remove class from event queue first. */ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, - int level, int bytes) + int level, struct sk_buff *skb) { + int bytes = skb->len; long toks, diff; enum htb_cmode old_mode; @@ -759,7 +757,8 @@ static void htb_charge_class(struct htb_ /* update byte stats except for leaves which are already updated */ if (cl->level) { cl->bstats.bytes += bytes; - cl->bstats.packets++; + cl->bstats.packets += + skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; } cl = cl->parent; } @@ -943,7 +942,7 @@ next: gives us slightly better performance */ if (!cl->un.leaf.q->q.qlen) htb_deactivate(q, cl); - htb_charge_class(q, cl, level, skb->len); + htb_charge_class(q, cl, level, skb); } return skb; }