Merge git://oss.sgi.com:8090/xfs/xfs-2.6
[linux-drm-fsl-dcu.git] / net / sched / sch_sfq.c
index d0d6e595a78c8f824480b3f656815c2c0942839d..66f32051a99b4b182adf0db17fdb0c29ae67c3c8 100644 (file)
@@ -53,7 +53,7 @@
        Queuing using Deficit Round Robin", Proc. SIGCOMM 95.
 
 
-       This is not the thing that is usually called (W)FQ nowadays. 
+       This is not the thing that is usually called (W)FQ nowadays.
        It does not use any timestamp mechanism, but instead
        processes queues in round-robin order.
 
@@ -63,7 +63,7 @@
 
        DRAWBACKS:
 
-       - "Stochastic" -> It is not 100% fair. 
+       - "Stochastic" -> It is not 100% fair.
        When hash collisions occur, several flows are considered as one.
 
        - "Round-robin" -> It introduces larger delays than virtual clock
@@ -143,6 +143,7 @@ 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_UDPLITE ||
                     iph->protocol == IPPROTO_SCTP ||
                     iph->protocol == IPPROTO_DCCP ||
                     iph->protocol == IPPROTO_ESP))
@@ -156,6 +157,7 @@ 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_UDPLITE ||
                    iph->nexthdr == IPPROTO_SCTP ||
                    iph->nexthdr == IPPROTO_DCCP ||
                    iph->nexthdr == IPPROTO_ESP)
@@ -393,6 +395,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
        struct tc_sfq_qopt *ctl = RTA_DATA(opt);
+       unsigned int qlen;
 
        if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
                return -EINVAL;
@@ -403,8 +406,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
        if (ctl->limit)
                q->limit = min_t(u32, ctl->limit, SFQ_DEPTH);
 
+       qlen = sch->q.qlen;
        while (sch->q.qlen >= q->limit-1)
                sfq_drop(sch);
+       qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
 
        del_timer(&q->perturb_timer);
        if (q->perturb_period) {
@@ -496,7 +501,7 @@ static int __init sfq_module_init(void)
 {
        return register_qdisc(&sfq_qdisc_ops);
 }
-static void __exit sfq_module_exit(void) 
+static void __exit sfq_module_exit(void)
 {
        unregister_qdisc(&sfq_qdisc_ops);
 }