diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2005-11-03 16:43:07 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-11-05 14:03:46 -0500 |
commit | 07aaa11540828f4482c09e1a936a1f63cdb9fc9d (patch) | |
tree | 45a368df3e1031fc4458818942f52bcb2a54c8ff /net/sched/sch_netem.c | |
parent | 1758ee0ea26561943813c5f5a7b27272f2cbc4cf (diff) |
[NETEM]: use PSCHED_LESS
Convert netem to use PSCHED_LESS and warn if requeue fails.
With some of the psched clock sources, the subtraction doesn't
work always work right without wrapping.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/sched/sch_netem.c')
-rw-r--r-- | net/sched/sch_netem.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index bb9bf8d5003c..d871fe7f81a9 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -185,10 +185,13 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
185 | || q->counter < q->gap /* inside last reordering gap */ | 185 | || q->counter < q->gap /* inside last reordering gap */ |
186 | || q->reorder < get_crandom(&q->reorder_cor)) { | 186 | || q->reorder < get_crandom(&q->reorder_cor)) { |
187 | psched_time_t now; | 187 | psched_time_t now; |
188 | psched_tdiff_t delay; | ||
189 | |||
190 | delay = tabledist(q->latency, q->jitter, | ||
191 | &q->delay_cor, q->delay_dist); | ||
192 | |||
188 | PSCHED_GET_TIME(now); | 193 | PSCHED_GET_TIME(now); |
189 | PSCHED_TADD2(now, tabledist(q->latency, q->jitter, | 194 | PSCHED_TADD2(now, delay, cb->time_to_send); |
190 | &q->delay_cor, q->delay_dist), | ||
191 | cb->time_to_send); | ||
192 | ++q->counter; | 195 | ++q->counter; |
193 | ret = q->qdisc->enqueue(skb, q->qdisc); | 196 | ret = q->qdisc->enqueue(skb, q->qdisc); |
194 | } else { | 197 | } else { |
@@ -248,24 +251,31 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) | |||
248 | const struct netem_skb_cb *cb | 251 | const struct netem_skb_cb *cb |
249 | = (const struct netem_skb_cb *)skb->cb; | 252 | = (const struct netem_skb_cb *)skb->cb; |
250 | psched_time_t now; | 253 | psched_time_t now; |
251 | long delay; | ||
252 | 254 | ||
253 | /* if more time remaining? */ | 255 | /* if more time remaining? */ |
254 | PSCHED_GET_TIME(now); | 256 | PSCHED_GET_TIME(now); |
255 | delay = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now)); | 257 | |
256 | pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay); | 258 | if (PSCHED_TLESS(cb->time_to_send, now)) { |
257 | if (delay <= 0) { | ||
258 | pr_debug("netem_dequeue: return skb=%p\n", skb); | 259 | pr_debug("netem_dequeue: return skb=%p\n", skb); |
259 | sch->q.qlen--; | 260 | sch->q.qlen--; |
260 | sch->flags &= ~TCQ_F_THROTTLED; | 261 | sch->flags &= ~TCQ_F_THROTTLED; |
261 | return skb; | 262 | return skb; |
262 | } | 263 | } else { |
264 | psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now); | ||
263 | 265 | ||
264 | mod_timer(&q->timer, jiffies + delay); | 266 | if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) { |
265 | sch->flags |= TCQ_F_THROTTLED; | 267 | sch->qstats.drops++; |
266 | 268 | ||
267 | if (q->qdisc->ops->requeue(skb, q->qdisc) != 0) | 269 | /* After this qlen is confused */ |
268 | sch->qstats.drops++; | 270 | printk(KERN_ERR "netem: queue discpline %s could not requeue\n", |
271 | q->qdisc->ops->id); | ||
272 | |||
273 | sch->q.qlen--; | ||
274 | } | ||
275 | |||
276 | mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay)); | ||
277 | sch->flags |= TCQ_F_THROTTLED; | ||
278 | } | ||
269 | } | 279 | } |
270 | 280 | ||
271 | return NULL; | 281 | return NULL; |