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 | |
| 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')
| -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; |
