Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / net / sched / sch_sfq.c
index acf2666..e057768 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
@@ -144,6 +144,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
                if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
                    (iph->protocol == IPPROTO_TCP ||
                     iph->protocol == IPPROTO_UDP ||
+                    iph->protocol == IPPROTO_SCTP ||
+                    iph->protocol == IPPROTO_DCCP ||
                     iph->protocol == IPPROTO_ESP))
                        h2 ^= *(((u32*)iph) + iph->ihl);
                break;
@@ -155,6 +157,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
                h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
                if (iph->nexthdr == IPPROTO_TCP ||
                    iph->nexthdr == IPPROTO_UDP ||
+                   iph->nexthdr == IPPROTO_SCTP ||
+                   iph->nexthdr == IPPROTO_DCCP ||
                    iph->nexthdr == IPPROTO_ESP)
                        h2 ^= *(u32*)&iph[1];
                break;
@@ -211,7 +215,7 @@ static inline void sfq_inc(struct sfq_sched_data *q, sfq_index x)
 
 static unsigned int sfq_drop(struct Qdisc *sch)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        sfq_index d = q->max_depth;
        struct sk_buff *skb;
        unsigned int len;
@@ -227,7 +231,8 @@ static unsigned int sfq_drop(struct Qdisc *sch)
                kfree_skb(skb);
                sfq_dec(q, x);
                sch->q.qlen--;
-               sch->stats.drops++;
+               sch->qstats.drops++;
+               sch->qstats.backlog -= len;
                return len;
        }
 
@@ -243,7 +248,8 @@ static unsigned int sfq_drop(struct Qdisc *sch)
                sfq_dec(q, d);
                sch->q.qlen--;
                q->ht[q->hash[d]] = SFQ_DEPTH;
-               sch->stats.drops++;
+               sch->qstats.drops++;
+               sch->qstats.backlog -= len;
                return len;
        }
 
@@ -253,7 +259,7 @@ static unsigned int sfq_drop(struct Qdisc *sch)
 static int
 sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        unsigned hash = sfq_hash(q, skb);
        sfq_index x;
 
@@ -262,6 +268,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
                q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
                q->hash[x] = hash;
        }
+       sch->qstats.backlog += skb->len;
        __skb_queue_tail(&q->qs[x], skb);
        sfq_inc(q, x);
        if (q->qs[x].qlen == 1) {               /* The flow is new */
@@ -276,8 +283,8 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
                }
        }
        if (++sch->q.qlen < q->limit-1) {
-               sch->stats.bytes += skb->len;
-               sch->stats.packets++;
+               sch->bstats.bytes += skb->len;
+               sch->bstats.packets++;
                return 0;
        }
 
@@ -288,7 +295,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 static int
 sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        unsigned hash = sfq_hash(q, skb);
        sfq_index x;
 
@@ -297,6 +304,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
                q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
                q->hash[x] = hash;
        }
+       sch->qstats.backlog += skb->len;
        __skb_queue_head(&q->qs[x], skb);
        sfq_inc(q, x);
        if (q->qs[x].qlen == 1) {               /* The flow is new */
@@ -310,10 +318,12 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
                        q->tail = x;
                }
        }
-       if (++sch->q.qlen < q->limit - 1)
+       if (++sch->q.qlen < q->limit - 1) {
+               sch->qstats.requeues++;
                return 0;
+       }
 
-       sch->stats.drops++;
+       sch->qstats.drops++;
        sfq_drop(sch);
        return NET_XMIT_CN;
 }
@@ -324,7 +334,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
 static struct sk_buff *
 sfq_dequeue(struct Qdisc* sch)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
        sfq_index a, old_a;
 
@@ -338,6 +348,7 @@ sfq_dequeue(struct Qdisc* sch)
        skb = __skb_dequeue(&q->qs[a]);
        sfq_dec(q, a);
        sch->q.qlen--;
+       sch->qstats.backlog -= skb->len;
 
        /* Is the slot empty? */
        if (q->qs[a].qlen == 0) {
@@ -369,10 +380,9 @@ sfq_reset(struct Qdisc* sch)
 static void sfq_perturbation(unsigned long arg)
 {
        struct Qdisc *sch = (struct Qdisc*)arg;
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
 
        q->perturbation = net_random()&0x1F;
-       q->perturb_timer.expires = jiffies + q->perturb_period;
 
        if (q->perturb_period) {
                q->perturb_timer.expires = jiffies + q->perturb_period;
@@ -382,7 +392,7 @@ static void sfq_perturbation(unsigned long arg)
 
 static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        struct tc_sfq_qopt *ctl = RTA_DATA(opt);
 
        if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
@@ -408,7 +418,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
 
 static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        int i;
 
        init_timer(&q->perturb_timer);
@@ -440,13 +450,13 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
 
 static void sfq_destroy(struct Qdisc *sch)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        del_timer(&q->perturb_timer);
 }
 
 static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
-       struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data;
+       struct sfq_sched_data *q = qdisc_priv(sch);
        unsigned char    *b = skb->tail;
        struct tc_sfq_qopt opt;