This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / net / sched / sch_cbq.c
index 74ca4ee..2ae7382 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <linux/bitops.h>
+#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -146,9 +146,7 @@ struct cbq_class
        long                    avgidle;
        long                    deficit;        /* Saved deficit for WRR */
        unsigned long           penalized;
-       struct gnet_stats_basic bstats;
-       struct gnet_stats_queue qstats;
-       struct gnet_stats_rate_est rate_est;
+       struct tc_stats         stats;
        spinlock_t              *stats_lock;
        struct tc_cbq_xstats    xstats;
 
@@ -435,8 +433,8 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 #endif
                if ((ret = cl->q->enqueue(skb, cl->q)) == NET_XMIT_SUCCESS) {
                        sch->q.qlen++;
-                       sch->bstats.packets++;
-                       sch->bstats.bytes+=len;
+                       sch->stats.packets++;
+                       sch->stats.bytes+=len;
                        cbq_mark_toplevel(q, cl);
                        if (!cl->next_alive)
                                cbq_activate_class(cl);
@@ -445,21 +443,21 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        }
 
 #ifndef CONFIG_NET_CLS_ACT
-       sch->qstats.drops++;
+       sch->stats.drops++;
        if (cl == NULL)
                kfree_skb(skb);
        else {
                cbq_mark_toplevel(q, cl);
-               cl->qstats.drops++;
+               cl->stats.drops++;
        }
 #else
        if ( NET_XMIT_DROP == ret) {
-               sch->qstats.drops++;
+               sch->stats.drops++;
        }
 
        if (cl != NULL) {
                cbq_mark_toplevel(q, cl);
-               cl->qstats.drops++;
+               cl->stats.drops++;
        }
 #endif
        return ret;
@@ -474,7 +472,7 @@ cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
 
        if ((cl = q->tx_class) == NULL) {
                kfree_skb(skb);
-               sch->qstats.drops++;
+               sch->stats.drops++;
                return NET_XMIT_CN;
        }
        q->tx_class = NULL;
@@ -487,13 +485,12 @@ cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
 #endif
        if ((ret = cl->q->ops->requeue(skb, cl->q)) == 0) {
                sch->q.qlen++;
-               sch->qstats.requeues++;
                if (!cl->next_alive)
                        cbq_activate_class(cl);
                return 0;
        }
-       sch->qstats.drops++;
-       cl->qstats.drops++;
+       sch->stats.drops++;
+       cl->stats.drops++;
        return ret;
 }
 
@@ -732,17 +729,17 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
 
                if (cl->q->enqueue(skb, cl->q) == 0) {
                        sch->q.qlen++;
-                       sch->bstats.packets++;
-                       sch->bstats.bytes+=len;
+                       sch->stats.packets++;
+                       sch->stats.bytes+=len;
                        if (!cl->next_alive)
                                cbq_activate_class(cl);
                        return 0;
                }
-               sch->qstats.drops++;
+               sch->stats.drops++;
                return 0;
        }
 
-       sch->qstats.drops++;
+       sch->stats.drops++;
        return -1;
 }
 #endif
@@ -791,8 +788,8 @@ cbq_update(struct cbq_sched_data *q)
                long avgidle = cl->avgidle;
                long idle;
 
-               cl->bstats.packets++;
-               cl->bstats.bytes += len;
+               cl->stats.packets++;
+               cl->stats.bytes += len;
 
                /*
                   (now - last) is total time between packet right edges.
@@ -890,7 +887,7 @@ cbq_under_limit(struct cbq_class *cl)
                   no another solution exists.
                 */
                if ((cl = cl->borrow) == NULL) {
-                       this_cl->qstats.overlimits++;
+                       this_cl->stats.overlimits++;
                        this_cl->overlimit(this_cl);
                        return NULL;
                }
@@ -1093,7 +1090,7 @@ cbq_dequeue(struct Qdisc *sch)
           Sigh... start watchdog timer in the last case. */
 
        if (sch->q.qlen) {
-               sch->qstats.overlimits++;
+               sch->stats.overlimits++;
                if (q->wd_expires) {
                        long delay = PSCHED_US2JIFFIE(q->wd_expires);
                        if (delay <= 0)
@@ -1614,6 +1611,16 @@ static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
        return 0;
 }
 
+int cbq_copy_xstats(struct sk_buff *skb, struct tc_cbq_xstats *st)
+{
+       RTA_PUT(skb, TCA_XSTATS, sizeof(*st), st);
+       return 0;
+
+rtattr_failure:
+       return -1;
+}
+
+
 static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct cbq_sched_data *q = qdisc_priv(sch);
@@ -1625,6 +1632,13 @@ static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
        if (cbq_dump_attr(skb, &q->link) < 0)
                goto rtattr_failure;
        rta->rta_len = skb->tail - b;
+       spin_lock_bh(&sch->dev->queue_lock);
+       q->link.xstats.avgidle = q->link.avgidle;
+       if (cbq_copy_xstats(skb, &q->link.xstats)) {
+               spin_unlock_bh(&sch->dev->queue_lock);
+               goto rtattr_failure;
+       }
+       spin_unlock_bh(&sch->dev->queue_lock);
        return skb->len;
 
 rtattr_failure:
@@ -1632,19 +1646,11 @@ rtattr_failure:
        return -1;
 }
 
-static int
-cbq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
-{
-       struct cbq_sched_data *q = qdisc_priv(sch);
-
-       q->link.xstats.avgidle = q->link.avgidle;
-       return gnet_stats_copy_app(d, &q->link.xstats, sizeof(q->link.xstats));
-}
-
 static int
 cbq_dump_class(struct Qdisc *sch, unsigned long arg,
               struct sk_buff *skb, struct tcmsg *tcm)
 {
+       struct cbq_sched_data *q = qdisc_priv(sch);
        struct cbq_class *cl = (struct cbq_class*)arg;
        unsigned char    *b = skb->tail;
        struct rtattr *rta;
@@ -1661,35 +1667,25 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
        if (cbq_dump_attr(skb, cl) < 0)
                goto rtattr_failure;
        rta->rta_len = skb->tail - b;
-       return skb->len;
-
-rtattr_failure:
-       skb_trim(skb, b - skb->data);
-       return -1;
-}
-
-static int
-cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
-       struct gnet_dump *d)
-{
-       struct cbq_sched_data *q = qdisc_priv(sch);
-       struct cbq_class *cl = (struct cbq_class*)arg;
-
-       cl->qstats.qlen = cl->q->q.qlen;
+       cl->stats.qlen = cl->q->q.qlen;
+       if (qdisc_copy_stats(skb, &cl->stats, cl->stats_lock))
+               goto rtattr_failure;
+       spin_lock_bh(&sch->dev->queue_lock);
        cl->xstats.avgidle = cl->avgidle;
        cl->xstats.undertime = 0;
-
        if (!PSCHED_IS_PASTPERFECT(cl->undertime))
                cl->xstats.undertime = PSCHED_TDIFF(cl->undertime, q->now);
+       if (cbq_copy_xstats(skb, &cl->xstats)) {
+               spin_unlock_bh(&sch->dev->queue_lock);
+               goto rtattr_failure;
+       }
+       spin_unlock_bh(&sch->dev->queue_lock);
 
-       if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
-           gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
-#endif
-           gnet_stats_copy_queue(d, &cl->qstats) < 0)
-               return -1;
+       return skb->len;
 
-       return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
+rtattr_failure:
+       skb_trim(skb, b - skb->data);
+       return -1;
 }
 
 static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
@@ -1753,13 +1749,11 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
 {
        struct cbq_sched_data *q = qdisc_priv(sch);
 
-       BUG_TRAP(!cl->filters);
-
        cbq_destroy_filters(cl);
        qdisc_destroy(cl->q);
        qdisc_put_rtab(cl->R_tab);
 #ifdef CONFIG_NET_ESTIMATOR
-       gen_kill_estimator(&cl->bstats, &cl->rate_est);
+       qdisc_kill_estimator(&cl->stats);
 #endif
        if (cl != &q->link)
                kfree(cl);
@@ -1775,14 +1769,6 @@ cbq_destroy(struct Qdisc* sch)
 #ifdef CONFIG_NET_CLS_POLICE
        q->rx_class = NULL;
 #endif
-       /*
-        * Filters must be destroyed first because we don't destroy the
-        * classes from root to leafs which means that filters can still
-        * be bound to classes which have been destroyed already. --TGR '04
-        */
-       for (h = 0; h < 16; h++)
-               for (cl = q->classes[h]; cl; cl = cl->next)
-                       cbq_destroy_filters(cl);
 
        for (h = 0; h < 16; h++) {
                struct cbq_class *next;
@@ -1905,9 +1891,11 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
                sch_tree_unlock(sch);
 
 #ifdef CONFIG_NET_ESTIMATOR
-               if (tca[TCA_RATE-1])
-                       gen_replace_estimator(&cl->bstats, &cl->rate_est,
-                               cl->stats_lock, tca[TCA_RATE-1]);
+               if (tca[TCA_RATE-1]) {
+                       qdisc_kill_estimator(&cl->stats);
+                       qdisc_new_estimator(&cl->stats, cl->stats_lock,
+                                           tca[TCA_RATE-1]);
+               }
 #endif
                return 0;
        }
@@ -1997,8 +1985,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
 
 #ifdef CONFIG_NET_ESTIMATOR
        if (tca[TCA_RATE-1])
-               gen_new_estimator(&cl->bstats, &cl->rate_est,
-                       cl->stats_lock, tca[TCA_RATE-1]);
+               qdisc_new_estimator(&cl->stats, cl->stats_lock,
+                                   tca[TCA_RATE-1]);
 #endif
 
        *arg = (unsigned long)cl;
@@ -2118,7 +2106,6 @@ static struct Qdisc_class_ops cbq_class_ops = {
        .bind_tcf       =       cbq_bind_filter,
        .unbind_tcf     =       cbq_unbind_filter,
        .dump           =       cbq_dump_class,
-       .dump_stats     =       cbq_dump_class_stats,
 };
 
 static struct Qdisc_ops cbq_qdisc_ops = {
@@ -2135,7 +2122,6 @@ static struct Qdisc_ops cbq_qdisc_ops = {
        .destroy        =       cbq_destroy,
        .change         =       NULL,
        .dump           =       cbq_dump,
-       .dump_stats     =       cbq_dump_stats,
        .owner          =       THIS_MODULE,
 };