[NETEM]: use PSCHED_LESS
authorStephen Hemminger <shemminger@osdl.org>
Thu, 3 Nov 2005 21:43:07 +0000 (13:43 -0800)
committerArnaldo Carvalho de Melo <acme@mandriva.com>
Sat, 5 Nov 2005 19:03:46 +0000 (17:03 -0200)
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>
net/sched/sch_netem.c

index bb9bf8d..d871fe7 100644 (file)
@@ -185,10 +185,13 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
            || q->counter < q->gap      /* inside last reordering gap */
            || q->reorder < get_crandom(&q->reorder_cor)) {
                psched_time_t now;
+               psched_tdiff_t delay;
+
+               delay = tabledist(q->latency, q->jitter,
+                                 &q->delay_cor, q->delay_dist);
+
                PSCHED_GET_TIME(now);
-               PSCHED_TADD2(now, tabledist(q->latency, q->jitter, 
-                                           &q->delay_cor, q->delay_dist),
-                            cb->time_to_send);
+               PSCHED_TADD2(now, delay, cb->time_to_send);
                ++q->counter;
                ret = q->qdisc->enqueue(skb, q->qdisc);
        } else {
@@ -248,24 +251,31 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
                const struct netem_skb_cb *cb
                        = (const struct netem_skb_cb *)skb->cb;
                psched_time_t now;
-               long delay;
 
                /* if more time remaining? */
                PSCHED_GET_TIME(now);
-               delay = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
-               pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
-               if (delay <= 0) {
+
+               if (PSCHED_TLESS(cb->time_to_send, now)) {
                        pr_debug("netem_dequeue: return skb=%p\n", skb);
                        sch->q.qlen--;
                        sch->flags &= ~TCQ_F_THROTTLED;
                        return skb;
-               }
+               } else {
+                       psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now);
 
-               mod_timer(&q->timer, jiffies + delay);
-               sch->flags |= TCQ_F_THROTTLED;
+                       if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
+                               sch->qstats.drops++;
 
-               if (q->qdisc->ops->requeue(skb, q->qdisc) != 0)
-                       sch->qstats.drops++;
+                               /* After this qlen is confused */
+                               printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
+                                      q->qdisc->ops->id);
+
+                               sch->q.qlen--;
+                       }
+
+                       mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay));
+                       sch->flags |= TCQ_F_THROTTLED;
+               }
        }
 
        return NULL;