X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsched%2Fsch_htb.c;h=61c8fa4db6080b3df2ab967a1c976bf29351352d;hb=9e1bf581d67d87a1d7fc0ea500729e3a03643a26;hp=2de5a8a0148185a1aaf47007d0c50b30f5873eab;hpb=8d40237c730b8be87c1b80a5d96b9c603fefa829;p=linux-2.6.git diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 2de5a8a01..61c8fa4db 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -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 = {