X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsched%2Fsch_prio.c;h=3395ca7bcadfa76e3200e45cddf7944081965031;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=6961f081170f8990ee978041c5bc675af1dfa096;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 6961f0811..3395ca7bc 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,36 +47,23 @@ struct prio_sched_data }; -struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r) +static struct Qdisc * +prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) { struct prio_sched_data *q = qdisc_priv(sch); u32 band = skb->priority; struct tcf_result res; + *qerr = NET_XMIT_BYPASS; if (TC_H_MAJ(skb->priority) != sch->handle) { #ifdef CONFIG_NET_CLS_ACT - int result = 0, terminal = 0; - result = tc_classify(skb, q->filter_list, &res); - - switch (result) { - case TC_ACT_SHOT: - *r = NET_XMIT_DROP; - terminal = 1; - break; - case TC_ACT_STOLEN: - case TC_ACT_QUEUED: - terminal = 1; - break; - case TC_ACT_RECLASSIFY: - case TC_ACT_OK: - case TC_ACT_UNSPEC: - default: - break; - }; - if (terminal) { - kfree_skb(skb); + switch (tc_classify(skb, q->filter_list, &res)) { + case TC_ACT_STOLEN: + case TC_ACT_QUEUED: + *qerr = NET_XMIT_SUCCESS; + case TC_ACT_SHOT: return NULL; - } + }; if (!q->filter_list ) { #else @@ -96,33 +83,29 @@ struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r) } static int -prio_enqueue(struct sk_buff *skb, struct Qdisc* sch) +prio_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct Qdisc *qdisc; - int ret = NET_XMIT_SUCCESS; + int ret; qdisc = prio_classify(skb, sch, &ret); +#ifdef CONFIG_NET_CLS_ACT + if (qdisc == NULL) { - if (NULL == qdisc) - goto dropped; + if (ret == NET_XMIT_BYPASS) + sch->qstats.drops++; + kfree_skb(skb); + return ret; + } +#endif if ((ret = qdisc->enqueue(skb, qdisc)) == NET_XMIT_SUCCESS) { - sch->stats.bytes += skb->len; - sch->stats.packets++; + sch->bstats.bytes += skb->len; + sch->bstats.packets++; sch->q.qlen++; return NET_XMIT_SUCCESS; } - -dropped: -#ifdef CONFIG_NET_CLS_ACT - if (NET_XMIT_DROP == ret) { -#endif - sch->stats.drops++; -#ifdef CONFIG_NET_CLS_ACT - } else { - sch->stats.overlimits++; /* abuse, but noone uses it */ - } -#endif + sch->qstats.drops++; return ret; } @@ -131,18 +114,24 @@ static int prio_requeue(struct sk_buff *skb, struct Qdisc* sch) { struct Qdisc *qdisc; - int ret = NET_XMIT_DROP; + int ret; qdisc = prio_classify(skb, sch, &ret); - if (qdisc == NULL) - goto dropped; +#ifdef CONFIG_NET_CLS_ACT + if (qdisc == NULL) { + if (ret == NET_XMIT_BYPASS) + sch->qstats.drops++; + kfree_skb(skb); + return ret; + } +#endif - if ((ret = qdisc->ops->requeue(skb, qdisc)) == 0) { + if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) { sch->q.qlen++; + sch->qstats.requeues++; return 0; } -dropped: - sch->stats.drops++; + sch->qstats.drops++; return NET_XMIT_DROP; } @@ -176,7 +165,7 @@ static unsigned int prio_drop(struct Qdisc* sch) for (prio = q->bands-1; prio >= 0; prio--) { qdisc = q->queues[prio]; - if ((len = qdisc->ops->drop(qdisc)) != 0) { + if (qdisc->ops->drop && (len = qdisc->ops->drop(qdisc)) != 0) { sch->q.qlen--; return len; } @@ -239,14 +228,13 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) } sch_tree_unlock(sch); - for (i=0; i<=TC_PRIO_MAX; i++) { - int band = q->prio2band[i]; - if (q->queues[band] == &noop_qdisc) { + for (i=0; ibands; i++) { + if (q->queues[i] == &noop_qdisc) { struct Qdisc *child; child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); if (child) { sch_tree_lock(sch); - child = xchg(&q->queues[band], child); + child = xchg(&q->queues[i], child); if (child != &noop_qdisc) qdisc_destroy(child);