KVM: PIT: provide an option to disable interrupt reinjection
[safe/jmp/linux-2.6] / net / sched / sch_netem.c
index 2ad0959..d876b87 100644 (file)
@@ -46,9 +46,6 @@
         layering other disciplines.  It does not need to do bandwidth
         control either since that can be handled by using token
         bucket or other rate control.
-
-        The simulator is limited by the Linux timer resolution
-        and will create packet bursts on the HZ boundary (1ms).
 */
 
 struct netem_sched_data {
@@ -233,7 +230,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                 */
                cb->time_to_send = psched_get_time();
                q->counter = 0;
-               ret = q->qdisc->ops->requeue(skb, q->qdisc);
+
+               __skb_queue_head(&q->qdisc->q, skb);
+               q->qdisc->qstats.backlog += qdisc_pkt_len(skb);
+               q->qdisc->qstats.requeues++;
+               ret = NET_XMIT_SUCCESS;
        }
 
        if (likely(ret == NET_XMIT_SUCCESS)) {
@@ -248,20 +249,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return ret;
 }
 
-/* Requeue packets but don't change time stamp */
-static int netem_requeue(struct sk_buff *skb, struct Qdisc *sch)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-       int ret;
-
-       if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-       }
-
-       return ret;
-}
-
 static unsigned int netem_drop(struct Qdisc* sch)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
@@ -279,7 +266,6 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
        struct netem_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
 
-       smp_mb();
        if (sch->flags & TCQ_F_THROTTLED)
                return NULL;
 
@@ -341,14 +327,13 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
        root_lock = qdisc_root_sleeping_lock(sch);
 
        spin_lock_bh(root_lock);
-       d = xchg(&q->delay_dist, d);
+       kfree(q->delay_dist);
+       q->delay_dist = d;
        spin_unlock_bh(root_lock);
-
-       kfree(d);
        return 0;
 }
 
-static int get_correlation(struct Qdisc *sch, const struct nlattr *attr)
+static void get_correlation(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        const struct tc_netem_corr *c = nla_data(attr);
@@ -356,27 +341,24 @@ static int get_correlation(struct Qdisc *sch, const struct nlattr *attr)
        init_crandom(&q->delay_cor, c->delay_corr);
        init_crandom(&q->loss_cor, c->loss_corr);
        init_crandom(&q->dup_cor, c->dup_corr);
-       return 0;
 }
 
-static int get_reorder(struct Qdisc *sch, const struct nlattr *attr)
+static void get_reorder(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        const struct tc_netem_reorder *r = nla_data(attr);
 
        q->reorder = r->probability;
        init_crandom(&q->reorder_cor, r->correlation);
-       return 0;
 }
 
-static int get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
+static void get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        const struct tc_netem_corrupt *r = nla_data(attr);
 
        q->corrupt = r->probability;
        init_crandom(&q->corrupt_cor, r->correlation);
-       return 0;
 }
 
 static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
@@ -435,11 +417,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
        if (q->gap)
                q->reorder = ~0;
 
-       if (tb[TCA_NETEM_CORR]) {
-               ret = get_correlation(sch, tb[TCA_NETEM_CORR]);
-               if (ret)
-                       return ret;
-       }
+       if (tb[TCA_NETEM_CORR])
+               get_correlation(sch, tb[TCA_NETEM_CORR]);
 
        if (tb[TCA_NETEM_DELAY_DIST]) {
                ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
@@ -447,17 +426,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
                        return ret;
        }
 
-       if (tb[TCA_NETEM_REORDER]) {
-               ret = get_reorder(sch, tb[TCA_NETEM_REORDER]);
-               if (ret)
-                       return ret;
-       }
+       if (tb[TCA_NETEM_REORDER])
+               get_reorder(sch, tb[TCA_NETEM_REORDER]);
 
-       if (tb[TCA_NETEM_CORRUPT]) {
-               ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
-               if (ret)
-                       return ret;
-       }
+       if (tb[TCA_NETEM_CORRUPT])
+               get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
 
        return 0;
 }
@@ -539,7 +512,6 @@ static struct Qdisc_ops tfifo_qdisc_ops __read_mostly = {
        .enqueue        =       tfifo_enqueue,
        .dequeue        =       qdisc_dequeue_head,
        .peek           =       qdisc_peek_head,
-       .requeue        =       qdisc_requeue,
        .drop           =       qdisc_queue_drop,
        .init           =       tfifo_init,
        .reset          =       qdisc_reset_queue,
@@ -628,7 +600,6 @@ static struct Qdisc_ops netem_qdisc_ops __read_mostly = {
        .enqueue        =       netem_enqueue,
        .dequeue        =       netem_dequeue,
        .peek           =       qdisc_peek_dequeued,
-       .requeue        =       netem_requeue,
        .drop           =       netem_drop,
        .init           =       netem_init,
        .reset          =       netem_reset,