aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-12-20 16:18:16 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-20 16:18:16 -0500
commitaa3e219997e4b949be4199660936099ded0b401f (patch)
treee463d695dbf0e92f7fd2c6b3132bbb9c38493829 /net
parent914e5cea14b2e4651cdb0707e0936b43246deda0 (diff)
net_sched: sch_sfq: fix allot handling
When deploying SFQ/IFB here at work, I found the allot management was pretty wrong in sfq, even changing allot from short to int... We should init allot for each new flow, not using a previous value found in slot. Before patch, I saw bursts of several packets per flow, apparently denying the default "quantum 1514" limit I had on my SFQ class. class sfq 11:1 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 7p requeues 0 allot 11546 class sfq 11:46 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 1p requeues 0 allot -23873 class sfq 11:78 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 5p requeues 0 allot 11393 After patch, better fairness among each flow, allot limit being respected, allot is positive : class sfq 11:e parent 11: (dropped 0, overlimits 0 requeues 86) backlog 0b 3p requeues 86 allot 596 class sfq 11:94 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 3p requeues 0 allot 1468 class sfq 11:a4 parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 4p requeues 0 allot 650 class sfq 11:bb parent 11: (dropped 0, overlimits 0 requeues 0) backlog 0b 3p requeues 0 allot 596 Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/sched/sch_sfq.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 3cf478d012dd..7150705f1d0b 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch)
270 /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ 270 /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
271 d = q->next[q->tail]; 271 d = q->next[q->tail];
272 q->next[q->tail] = q->next[d]; 272 q->next[q->tail] = q->next[d];
273 q->allot[q->next[d]] += q->quantum;
274 skb = q->qs[d].prev; 273 skb = q->qs[d].prev;
275 len = qdisc_pkt_len(skb); 274 len = qdisc_pkt_len(skb);
276 __skb_unlink(skb, &q->qs[d]); 275 __skb_unlink(skb, &q->qs[d]);
@@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
321 sfq_inc(q, x); 320 sfq_inc(q, x);
322 if (q->qs[x].qlen == 1) { /* The flow is new */ 321 if (q->qs[x].qlen == 1) { /* The flow is new */
323 if (q->tail == SFQ_DEPTH) { /* It is the first flow */ 322 if (q->tail == SFQ_DEPTH) { /* It is the first flow */
324 q->tail = x;
325 q->next[x] = x; 323 q->next[x] = x;
326 q->allot[x] = q->quantum;
327 } else { 324 } else {
328 q->next[x] = q->next[q->tail]; 325 q->next[x] = q->next[q->tail];
329 q->next[q->tail] = x; 326 q->next[q->tail] = x;
330 q->tail = x;
331 } 327 }
328 q->tail = x;
329 q->allot[x] = q->quantum;
332 } 330 }
333 if (++sch->q.qlen <= q->limit) { 331 if (++sch->q.qlen <= q->limit) {
334 sch->bstats.bytes += qdisc_pkt_len(skb); 332 sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch)
359{ 357{
360 struct sfq_sched_data *q = qdisc_priv(sch); 358 struct sfq_sched_data *q = qdisc_priv(sch);
361 struct sk_buff *skb; 359 struct sk_buff *skb;
362 sfq_index a, old_a; 360 sfq_index a, next_a;
363 361
364 /* No active slots */ 362 /* No active slots */
365 if (q->tail == SFQ_DEPTH) 363 if (q->tail == SFQ_DEPTH)
366 return NULL; 364 return NULL;
367 365
368 a = old_a = q->next[q->tail]; 366 a = q->next[q->tail];
369 367
370 /* Grab packet */ 368 /* Grab packet */
371 skb = __skb_dequeue(&q->qs[a]); 369 skb = __skb_dequeue(&q->qs[a]);
@@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch)
376 /* Is the slot empty? */ 374 /* Is the slot empty? */
377 if (q->qs[a].qlen == 0) { 375 if (q->qs[a].qlen == 0) {
378 q->ht[q->hash[a]] = SFQ_DEPTH; 376 q->ht[q->hash[a]] = SFQ_DEPTH;
379 a = q->next[a]; 377 next_a = q->next[a];
380 if (a == old_a) { 378 if (a == next_a) {
381 q->tail = SFQ_DEPTH; 379 q->tail = SFQ_DEPTH;
382 return skb; 380 return skb;
383 } 381 }
384 q->next[q->tail] = a; 382 q->next[q->tail] = next_a;
385 q->allot[a] += q->quantum;
386 } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { 383 } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) {
387 q->tail = a;
388 a = q->next[a];
389 q->allot[a] += q->quantum; 384 q->allot[a] += q->quantum;
385 q->tail = a;
390 } 386 }
391 return skb; 387 return skb;
392} 388}