netem: fix delay calculation in rate extension
The delay calculation with the rate extension introduces in v3.3 does not properly work, if other packets are still queued for transmission. For the delay calculation to work, both delay types (latency and delay introduces by rate limitation) have to be handled differently. The latency delay for a packet can overlap with the delay of other packets. The delay introduced by the rate however is separate, and can only start, once all other rate-introduced delays finished. Latency delay is from same distribution for each packet, rate delay depends on the packet size. .: latency delay -: rate delay x: additional delay we have to wait since another packet is currently transmitted .....---- Packet 1 .....xx------ Packet 2 .....------ Packet 3 ^^^^^ latency stacks ^^ rate delay doesn't stack ^^ latency stacks -----> time When a packet is enqueued, we first consider the latency delay. If other packets are already queued, we can reduce the latency delay until the last packet in the queue is send, however the latency delay cannot be <0, since this would mean that the rate is overcommitted. The new reference point is the time at which the last packet will be send. To find the time, when the packet should be send, the rate introduces delay has to be added on top of that. Signed-off-by: Johannes Naab <jn@stusta.de> Acked-by: Hagen Paul Pfeifer <hagen@jauu.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
80d84ef3ff
Коммит
a13d310471
|
@ -438,18 +438,18 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
|||
if (q->rate) {
|
||||
struct sk_buff_head *list = &sch->q;
|
||||
|
||||
delay += packet_len_2_sched_time(skb->len, q);
|
||||
|
||||
if (!skb_queue_empty(list)) {
|
||||
/*
|
||||
* Last packet in queue is reference point (now).
|
||||
* First packet in queue is already in flight,
|
||||
* calculate this time bonus and substract
|
||||
* Last packet in queue is reference point (now),
|
||||
* calculate this time bonus and subtract
|
||||
* from delay.
|
||||
*/
|
||||
delay -= now - netem_skb_cb(skb_peek(list))->time_to_send;
|
||||
delay -= netem_skb_cb(skb_peek_tail(list))->time_to_send - now;
|
||||
delay = max_t(psched_tdiff_t, 0, delay);
|
||||
now = netem_skb_cb(skb_peek_tail(list))->time_to_send;
|
||||
}
|
||||
|
||||
delay += packet_len_2_sched_time(skb->len, q);
|
||||
}
|
||||
|
||||
cb->time_to_send = now + delay;
|
||||
|
|
Загрузка…
Ссылка в новой задаче