X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsched%2Fsch_sfq.c;h=d0d6e595a78c8f824480b3f656815c2c0942839d;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=f37d9cdd00fe420494b85121e07bedc7c8a54a0d;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index f37d9cdd0..d0d6e595a 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -9,11 +9,10 @@ * Authors: Alexey Kuznetsov, */ -#include #include #include #include -#include +#include #include #include #include @@ -144,6 +143,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 +156,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; @@ -227,7 +230,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 +247,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; } @@ -262,6 +267,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 +282,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; } @@ -297,6 +303,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 +317,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; } @@ -338,6 +347,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) { @@ -372,7 +382,6 @@ static void sfq_perturbation(unsigned long arg) 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;