aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_netem.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-03-16 04:20:31 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:26:08 -0400
commit59cb5c6734021acc68590c7c2e0e92ad9a4952c6 (patch)
treed2c35a5a7f8c6766f825a6b7684fe8e526dbd3d7 /net/sched/sch_netem.c
parentf7f593e383145931cb2a65df62c31ce1bcc0cffc (diff)
[NET_SCHED]: sch_netem: use hrtimer based watchdog
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_netem.c')
-rw-r--r--net/sched/sch_netem.c25
1 files changed, 5 insertions, 20 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 1ccbfb55b0b8..915f82a2cc3d 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -54,7 +54,7 @@
54 54
55struct netem_sched_data { 55struct netem_sched_data {
56 struct Qdisc *qdisc; 56 struct Qdisc *qdisc;
57 struct timer_list timer; 57 struct qdisc_watchdog watchdog;
58 58
59 u32 latency; 59 u32 latency;
60 u32 loss; 60 u32 loss;
@@ -284,7 +284,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
284 sch->flags &= ~TCQ_F_THROTTLED; 284 sch->flags &= ~TCQ_F_THROTTLED;
285 return skb; 285 return skb;
286 } else { 286 } else {
287 psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now); 287 qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
288 288
289 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) { 289 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
290 qdisc_tree_decrease_qlen(q->qdisc, 1); 290 qdisc_tree_decrease_qlen(q->qdisc, 1);
@@ -292,32 +292,19 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
292 printk(KERN_ERR "netem: queue discpline %s could not requeue\n", 292 printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
293 q->qdisc->ops->id); 293 q->qdisc->ops->id);
294 } 294 }
295
296 mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay));
297 sch->flags |= TCQ_F_THROTTLED;
298 } 295 }
299 } 296 }
300 297
301 return NULL; 298 return NULL;
302} 299}
303 300
304static void netem_watchdog(unsigned long arg)
305{
306 struct Qdisc *sch = (struct Qdisc *)arg;
307
308 pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen);
309 sch->flags &= ~TCQ_F_THROTTLED;
310 netif_schedule(sch->dev);
311}
312
313static void netem_reset(struct Qdisc *sch) 301static void netem_reset(struct Qdisc *sch)
314{ 302{
315 struct netem_sched_data *q = qdisc_priv(sch); 303 struct netem_sched_data *q = qdisc_priv(sch);
316 304
317 qdisc_reset(q->qdisc); 305 qdisc_reset(q->qdisc);
318 sch->q.qlen = 0; 306 sch->q.qlen = 0;
319 sch->flags &= ~TCQ_F_THROTTLED; 307 qdisc_watchdog_cancel(&q->watchdog);
320 del_timer_sync(&q->timer);
321} 308}
322 309
323/* Pass size change message down to embedded FIFO */ 310/* Pass size change message down to embedded FIFO */
@@ -567,9 +554,7 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
567 if (!opt) 554 if (!opt)
568 return -EINVAL; 555 return -EINVAL;
569 556
570 init_timer(&q->timer); 557 qdisc_watchdog_init(&q->watchdog, sch);
571 q->timer.function = netem_watchdog;
572 q->timer.data = (unsigned long) sch;
573 558
574 q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops, 559 q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops,
575 TC_H_MAKE(sch->handle, 1)); 560 TC_H_MAKE(sch->handle, 1));
@@ -590,7 +575,7 @@ static void netem_destroy(struct Qdisc *sch)
590{ 575{
591 struct netem_sched_data *q = qdisc_priv(sch); 576 struct netem_sched_data *q = qdisc_priv(sch);
592 577
593 del_timer_sync(&q->timer); 578 qdisc_watchdog_cancel(&q->watchdog);
594 qdisc_destroy(q->qdisc); 579 qdisc_destroy(q->qdisc);
595 kfree(q->delay_dist); 580 kfree(q->delay_dist);
596} 581}