This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / net / sched / sch_htb.c
index 2de5a8a..61c8fa4 100644 (file)
@@ -31,7 +31,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>
@@ -142,9 +142,8 @@ struct htb_class
 #endif
     /* general class parameters */
     u32 classid;
-    struct gnet_stats_basic bstats;
-    struct gnet_stats_queue qstats;
-    struct gnet_stats_rate_est rate_est;
+    struct tc_stats    stats;  /* generic stats */
+    spinlock_t         *stats_lock;
     struct tc_htb_xstats xstats;/* our special stats */
     int refcnt;                        /* usage count of this class */
 
@@ -736,7 +735,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        }
     } else if (!cl) {
            if (NET_XMIT_DROP == ret) {
-                   sch->qstats.drops++;
+                   sch->stats.drops++;
            }
            return ret;
     }
@@ -748,22 +747,22 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
            q->direct_pkts++;
        } else {
            kfree_skb (skb);
-           sch->qstats.drops++;
+           sch->stats.drops++;
            return NET_XMIT_DROP;
        }
     }
 #endif
     else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
-       sch->qstats.drops++;
-       cl->qstats.drops++;
+       sch->stats.drops++;
+       cl->stats.drops++;
        return NET_XMIT_DROP;
     } else {
-       cl->bstats.packets++; cl->bstats.bytes += skb->len;
+       cl->stats.packets++; cl->stats.bytes += skb->len;
        htb_activate (q,cl);
     }
 
     sch->q.qlen++;
-    sch->bstats.packets++; sch->bstats.bytes += skb->len;
+    sch->stats.packets++; sch->stats.bytes += skb->len;
     HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb);
     return NET_XMIT_SUCCESS;
 }
@@ -784,18 +783,17 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
             __skb_queue_head(&q->direct_queue, skb);
             tskb = __skb_dequeue_tail(&q->direct_queue);
             kfree_skb (tskb);
-            sch->qstats.drops++;
+            sch->stats.drops++;
             return NET_XMIT_CN;        
        }
     } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
-       sch->qstats.drops++;
-       cl->qstats.drops++;
+       sch->stats.drops++;
+       cl->stats.drops++;
        return NET_XMIT_DROP;
     } else 
            htb_activate (q,cl);
 
     sch->q.qlen++;
-    sch->qstats.requeues++;
     HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb);
     return NET_XMIT_SUCCESS;
 }
@@ -907,8 +905,8 @@ static void htb_charge_class(struct htb_sched *q,struct htb_class *cl,
 
                /* update byte stats except for leaves which are already updated */
                if (cl->level) {
-                       cl->bstats.bytes += bytes;
-                       cl->bstats.packets++;
+                       cl->stats.bytes += bytes;
+                       cl->stats.packets++;
                }
                cl = cl->parent;
        }
@@ -1119,7 +1117,7 @@ static void htb_delay_by(struct Qdisc *sch,long delay)
        /* why don't use jiffies here ? because expires can be in past */
        mod_timer(&q->timer, q->jiffies + delay);
        sch->flags |= TCQ_F_THROTTLED;
-       sch->qstats.overlimits++;
+       sch->stats.overlimits++;
        HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay);
 }
 
@@ -1318,6 +1316,7 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct rtattr *rta;
        struct tc_htb_glob gopt;
        HTB_DBG(0,1,"htb_dump sch=%p, handle=%X\n",sch,sch->handle);
+       /* stats */
        HTB_QLOCK(sch);
        gopt.direct_pkts = q->direct_pkts;
 
@@ -1333,6 +1332,8 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
        RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
        RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
        rta->rta_len = skb->tail - b;
+       sch->stats.qlen = sch->q.qlen;
+       RTA_PUT(skb, TCA_STATS, sizeof(sch->stats), &sch->stats);
        HTB_QUNLOCK(sch);
        return skb->len;
 rtattr_failure:
@@ -1357,8 +1358,10 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
        HTB_QLOCK(sch);
        tcm->tcm_parent = cl->parent ? cl->parent->classid : TC_H_ROOT;
        tcm->tcm_handle = cl->classid;
-       if (!cl->level && cl->un.leaf.q)
+       if (!cl->level && cl->un.leaf.q) {
                tcm->tcm_info = cl->un.leaf.q->handle;
+               cl->stats.qlen = cl->un.leaf.q->q.qlen;
+       }
 
        rta = (struct rtattr*)b;
        RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
@@ -1371,36 +1374,22 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
        opt.level = cl->level; 
        RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
        rta->rta_len = skb->tail - b;
-       HTB_QUNLOCK(sch);
-       return skb->len;
-rtattr_failure:
-       HTB_QUNLOCK(sch);
-       skb_trim(skb, b - skb->data);
-       return -1;
-}
-
-static int
-htb_dump_class_stats(struct Qdisc *sch, unsigned long arg,
-       struct gnet_dump *d)
-{
-       struct htb_class *cl = (struct htb_class*)arg;
 
 #ifdef HTB_RATECM
-       cl->rate_est.bps = cl->rate_bytes/(HTB_EWMAC*HTB_HSIZE);
-       cl->rate_est.pps = cl->rate_packets/(HTB_EWMAC*HTB_HSIZE);
+       cl->stats.bps = cl->rate_bytes/(HTB_EWMAC*HTB_HSIZE);
+       cl->stats.pps = cl->rate_packets/(HTB_EWMAC*HTB_HSIZE);
 #endif
 
-       if (!cl->level && cl->un.leaf.q)
-               cl->qstats.qlen = cl->un.leaf.q->q.qlen;
        cl->xstats.tokens = cl->tokens;
        cl->xstats.ctokens = cl->ctokens;
-
-       if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-           gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
-           gnet_stats_copy_queue(d, &cl->qstats) < 0)
-               return -1;
-
-       return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
+       RTA_PUT(skb, TCA_STATS, sizeof(cl->stats), &cl->stats);
+       RTA_PUT(skb, TCA_XSTATS, sizeof(cl->xstats), &cl->xstats);
+       HTB_QUNLOCK(sch);
+       return skb->len;
+rtattr_failure:
+       HTB_QUNLOCK(sch);
+       skb_trim(skb, b - skb->data);
+       return -1;
 }
 
 static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
@@ -1467,6 +1456,9 @@ static void htb_destroy_class(struct Qdisc* sch,struct htb_class *cl)
        qdisc_put_rtab(cl->rate);
        qdisc_put_rtab(cl->ceil);
        
+#ifdef CONFIG_NET_ESTIMATOR
+       qdisc_kill_estimator(&cl->stats);
+#endif
        htb_destroy_filters (&cl->filter_list);
        
        while (!list_empty(&cl->children)) 
@@ -1754,7 +1746,6 @@ static struct Qdisc_class_ops htb_class_ops = {
        .bind_tcf       =       htb_bind_filter,
        .unbind_tcf     =       htb_unbind_filter,
        .dump           =       htb_dump_class,
-       .dump_stats     =       htb_dump_class_stats,
 };
 
 static struct Qdisc_ops htb_qdisc_ops = {