diff -Naur iproute2/tc/q_htb.c iproute2-new/tc/q_htb.c --- iproute2/tc/q_htb.c 2009-01-22 11:10:36.000000000 +0200 +++ iproute2-new/tc/q_htb.c 2009-01-22 11:31:40.000000000 +0200 @@ -110,6 +110,7 @@ unsigned mtu; unsigned short mpu = 0; unsigned short overhead = 0; + unsigned int bursthz; unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */ struct rtattr *tail; @@ -209,9 +210,16 @@ if (!opt.ceil.rate) opt.ceil = opt.rate; /* 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; - if (!cbuffer) cbuffer = opt.ceil.rate / get_hz() + mtu; + sure that buffer is larger than mtu and to have some safeguard space + With hrtimers enabled, hz variable gets too high resolution. If we + use it for computing burst, burst will be too low. In worst case + we will not reach specified rate/ceil, in best - load will be too + high. + */ + bursthz = get_hz() == 1000000000 ? 1000 : get_hz(); + + if (!buffer) buffer = opt.rate.rate / bursthz + mtu; + if (!cbuffer) cbuffer = opt.ceil.rate / bursthz + mtu; opt.ceil.overhead = overhead; opt.rate.overhead = overhead;