Skip to contentSkip to conversation

cbq: incorrect processing of high limits

PATCH Applied Vasily Averin 3 participants 3 messages Apr 1, 2013 – Apr 2, 2013

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cbq: incorrect processing of high limits

currently cbq works incorrectly for limits > 10% real link bandwidth, and practically does not work for limits > 50% real link bandwidth. Below are results of experiments taken on 1 Gbit link

In shaper | Actual Result
-----------+---------------

  100M     | 108 Mbps
  200M     | 244 Mbps
  300M     | 412 Mbps
  500M     | 893 Mbps

This happen because of q->now changes incorrectly in cbq_dequeue():
when it is called before real end of packet transmitting, L2T is greater than real time delay, q_now gets an extra boost but never compensate it.

To fix this problem we prevent change of q->now until its synchronization with real time.

---
 net/sched/sch_cbq.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
net/sched/sch_cbq.c +0 -0
index 6aabd77..5b5c83a 100644
@@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch)
		cbq_update(q);
		if ((incr -= incr2) < 0)
			incr = 0;
+		q->now += incr;
+	} else {
+		if (now > q->now)
+			q->now = now;
	}
-	q->now += incr;
	q->now_rt = now;

	for (;;) {

--
1.7.5.4

Acked-by on v1 1/1
#1 lore raw
Quoted 32 lines · Vasily Averin

currently cbq works incorrectly for limits > 10% real link bandwidth, and practically does not work for limits > 50% real link bandwidth. Below are results of experiments taken on 1 Gbit link

In shaper | Actual Result
-----------+---------------

  100M     | 108 Mbps
  200M     | 244 Mbps
  300M     | 412 Mbps
  500M     | 893 Mbps

This happen because of q->now changes incorrectly in cbq_dequeue():
when it is called before real end of packet transmitting, L2T is greater than real time delay, q_now gets an extra boost but never compensate it.

To fix this problem we prevent change of q->now until its synchronization with real time.

---
 net/sched/sch_cbq.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
net/sched/sch_cbq.c +0 -0
index 6aabd77..5b5c83a 100644
@@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch)
 		cbq_update(q);
 		if ((incr -= incr2) < 0)

net/sched/sch_cbq.c cbq_dequeue(struct Qdisc *sch) · line 972

Quoted 10 lines
net/sched/sch_cbq.c +4 -1
 			incr = 0;
+		q->now += incr;
+	} else {
+		if (now > q->now)
+			q->now = now;
 	}
-	q->now += incr;
 	q->now_rt = now;
 
 	for (;;) {

Still, after your patch a limit of 500Mbit gives :

rate 515872Kbit 946pps backlog 0b 2p requeues 0

HTB is more precise :

rate 500667Kbit 41336pps backlog 0b 2p requeues 0

maintainer Applied
#2 lore raw

From: Eric Dumazet <[email protected]>
Date: Mon, 01 Apr 2013 09:24:36 -0700

Quoted 22 lines · Vasily Averin
Quoted 21 lines

currently cbq works incorrectly for limits > 10% real link bandwidth, and practically does not work for limits > 50% real link bandwidth. Below are results of experiments taken on 1 Gbit link

In shaper | Actual Result
-----------+---------------

  100M     | 108 Mbps
  200M     | 244 Mbps
  300M     | 412 Mbps
  500M     | 893 Mbps

This happen because of q->now changes incorrectly in cbq_dequeue():
when it is called before real end of packet transmitting, L2T is greater than real time delay, q_now gets an extra boost but never compensate it.

To fix this problem we prevent change of q->now until its synchronization with real time.

...

Quoted 1 line

Applied, thanks.