I'm using tc with kernel 2.6.38.8 for traffic shaping. Limit bandwidth works, adding delay works, but when shaping both bandwidth with delay, the achieved bandwidth is always much lower than the limit if the limit is >1.5 Mbps or so.
Example:
tc qdisc del dev usb0 root
tc qdisc add dev usb0 root handle 1: tbf rate 2Mbit burst 100kb latency 300ms
tc qdisc add dev usb0 parent 1:1 handle 10: netem limit 2000 delay 200ms
Yields a delay (from ping) of 201 ms, but a capacity of just 1.66 Mbps (from iperf). If I eliminate the delay, the bandwidth is precisely 2 Mbps. If I specify a bandwidth of 1 Mbps and 200 ms RTT, everything works. I've also tried ipfw / dummynet, which yields similar results.
I've tried using rebuilding the kernel with HZ=1000 in Kconfig -- that didn't fix the problem. Other ideas?
Imagine trying to drive exactly 55 miles per hour if you had a one second delay between when you pressed on the accelerator and when the car went faster. You'd have a pretty hard time doing it.
And you would at least have the advantage that you know you need to drive 55 miles per hour. Now, imagine you don't know that. So what happens is when you go over 55 miles per hour, you get stopped and have to accelerate all over again, having no idea at what speed you're going to get stopped.
You sure as heck wouldn't average 55, would you?
Same thing here. The TCP stack has no idea it's limited to 2MBps and has to try to find that limit. And the latency means it cannot react quickly to the information that it has reached its limit. Since it can never actually go over 2Mbps, due to the hard limit, its average is going to be less than that.
You may be able to improve this with
burst
and/orminburst
settings. Essentially what those do is let the connection go a bit over its limit if it's been below its limit. This way, it will go a bit over 2Mbps some of the time and that way it will have an average closer to 2Mbps.