Message ID | 510057F3.80707@stusta.de |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Johannes Naab <jn@stusta.de> Date: Wed, 23 Jan 2013 22:36:51 +0100 > From: Johannes Naab <jn@stusta.de> > > 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> Applied, thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 298c0dd..3d2acc7 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -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;