#661048 tc: htb calculates too small burst sizes

Package:
iproute2
Source:
iproute2
Description:
networking and traffic control tools
Submitter:
Thomas Mühlgrabner
Date:
2017-12-30 20:12:21 UTC
Severity:
normal
#661048#5
Date:
2012-02-23 19:07:23 UTC
From:
To:
When letting htb calculate the burst sizes, it chooses too small burst sizes, resulting in degraded performance.
This is especially true for high rates.

#661048#10
Date:
2012-03-09 15:24:23 UTC
From:
To:
Hello Thomas!

This is something you probably want to bring directly to upstream and discuss
it there....

Some examples would be useful where you can both see which options you used,
what the result was and some additional comments on what you expected to get!


This is from q_htb.c and should hopefully be the relevant code:

        /* compute minimal allowed burst from rate; mtu is added here to make
           sute that buffer is larger than mtu and to have some safeguard space */
        if (!buffer) buffer = opt.rate.rate / get_hz() + mtu;

#661048#17
Date:
2012-03-09 23:15:49 UTC
From:
To:
100mbit, 1:2 below that with a rate and ceil of 90mbit.
For this I used the commands:
tc qdisc add dev eth0 root handle 1 htb default 2
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
tc class add dev eth0 parent 1:1 classid 1:2 htb rate 90mbit ceil 90mbit

For both eth0 and eth1.

Without specifying a burst size, tc reports burst and cburst of 1586b
for class 1:2.
This results in a maximum of ~43300Kb/s download (or upload) speed. This
is far from the achievable 90mbit.

When using a burst and cburst of 51kb for class 1:1 and 44kb for class
1:2, the speed increases to ~87600Kb/s - much closer to what is expected.

#661048#22
Date:
2012-06-20 02:27:37 UTC
From:
To:
Hi Thomas,

I read the htb code before so I'll show the problem here.

When tc comes to calculate buffer & cbuffer, it set lookup get_hz()
and set buffer = rate / get_hz() + mtu.

But nowadays, packet scheduling (sched) in kernel employ hrtimer so
that the old limit of activity only HZ (100) times per second is
removed. Also get_hz() returns 10^9 so that tc pretend that sched
start 10^9 times per second. So buffer would be set to no more than
mtu.

But hrtimer doesn't work by this way. So every time htb starts, it can
only send about 2 packet and because of sched won't start too
frequently, the desired rate can't be reached.

I would suggest that buffer should be manually set by user, and
converted to 10ms amount of data by default in future version of tc.

#661048#27
Date:
2012-06-20 02:38:04 UTC
From:
To:
What about backward compatibility with older kernels. Maybe the
kernel should just be fixed instead.

#661048#32
Date:
2012-06-20 13:18:06 UTC
From:
To:
2012/6/20 Stephen Hemminger <shemminger@vyatta.com>:

Good point. tc communicate to htb by the netlink socket.
buffer/cbuffer value is set by tc because (old and present version of)
htb require it. So that for backward compatibility tc should just add
a few checks for example if get_hz() may return 10^9 or 10^6, fallback
to 100, which in another word means 10ms.

#661048#37
Date:
2012-06-20 16:12:34 UTC
From:
To:
Hi,

I just realized that buffer is converted to time by tc before it's
send to HTB. In the old version of HTB it's the limit of how much data
measured in time can be sent at once(in 1 time unit).  Basicly buffer
value is used as fine control of the speed limiting, which define the
peak rate measured in a smaller unit of time.

So It's still possible just change the kernel code to choose a fine
control time unit and then multiply to calculate the amount of data or
let user pass this value to the kernel (via tc, however). But then the
workaround of "+ mtu" will be a new problem.

2012/6/20 YANG Zhe <yangzhe1990@gmail.com>: