X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fsched%2Fsch_prio.c;h=4aa2b45dad0a80232ed1d1d1c2fbabf33b19ec8f;hb=84081bd2205efd1e6c7203bc7099b4350839ee39;hp=404522046289cba0fddcad38dff6a4d7608ba17f;hpb=d62733c8e437fdb58325617c4b3331769ba82d70;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 4045220..4aa2b45 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -12,28 +12,12 @@ */ #include -#include -#include -#include #include #include #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include @@ -54,22 +38,21 @@ 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; + int err; *qerr = NET_XMIT_BYPASS; if (TC_H_MAJ(skb->priority) != sch->handle) { + err = tc_classify(skb, q->filter_list, &res); #ifdef CONFIG_NET_CLS_ACT - switch (tc_classify(skb, q->filter_list, &res)) { + switch (err) { case TC_ACT_STOLEN: case TC_ACT_QUEUED: *qerr = NET_XMIT_SUCCESS; case TC_ACT_SHOT: return NULL; } - - if (!q->filter_list ) { -#else - if (!q->filter_list || tc_classify(skb, q->filter_list, &res)) { #endif + if (!q->filter_list || err < 0) { if (TC_H_MAJ(band)) band = 0; band = q->prio2band[band&TC_PRIO_MAX]; @@ -153,7 +136,7 @@ prio_dequeue(struct Qdisc* sch) * pulling an skb. This way we avoid excessive requeues * for slower queues. */ - if (!netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) { + if (!__netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) { qdisc = q->queues[prio]; skb = qdisc->dequeue(qdisc); if (skb) { @@ -182,7 +165,7 @@ static struct sk_buff *rr_dequeue(struct Qdisc* sch) * for slower queues. If the queue is stopped, try the * next queue. */ - if (!netif_subqueue_stopped(sch->dev, + if (!__netif_subqueue_stopped(sch->dev, (q->mq ? q->curband : 0))) { qdisc = q->queues[q->curband]; skb = qdisc->dequeue(qdisc); @@ -241,25 +224,30 @@ prio_destroy(struct Qdisc* sch) qdisc_destroy(q->queues[prio]); } -static int prio_tune(struct Qdisc *sch, struct rtattr *opt) +static int prio_tune(struct Qdisc *sch, struct nlattr *opt) { struct prio_sched_data *q = qdisc_priv(sch); struct tc_prio_qopt *qopt; - struct rtattr *tb[TCA_PRIO_MAX]; + struct nlattr *tb[TCA_PRIO_MAX + 1]; + int err; int i; - if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt, qopt, - sizeof(*qopt))) - return -EINVAL; + err = nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt, + sizeof(*qopt)); + if (err < 0) + return err; + q->bands = qopt->bands; /* If we're multiqueue, make sure the number of incoming bands * matches the number of queues on the device we're associating with. * If the number of bands requested is zero, then set q->bands to - * dev->egress_subqueue_count. + * dev->egress_subqueue_count. Also, the root qdisc must be the + * only one that is enabled for multiqueue, since it's the only one + * that interacts with the underlying device. */ - q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]); + q->mq = nla_get_flag(tb[TCA_PRIO_MQ]); if (q->mq) { - if (sch->handle != TC_H_ROOT) + if (sch->parent != TC_H_ROOT) return -EINVAL; if (netif_is_multiqueue(sch->dev)) { if (q->bands == 0) @@ -311,7 +299,7 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) return 0; } -static int prio_init(struct Qdisc *sch, struct rtattr *opt) +static int prio_init(struct Qdisc *sch, struct nlattr *opt) { struct prio_sched_data *q = qdisc_priv(sch); int i; @@ -334,20 +322,24 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb) { struct prio_sched_data *q = qdisc_priv(sch); unsigned char *b = skb_tail_pointer(skb); - struct rtattr *nest; + struct nlattr *nest; struct tc_prio_qopt opt; opt.bands = q->bands; memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1); - nest = RTA_NEST_COMPAT(skb, TCA_OPTIONS, sizeof(opt), &opt); - if (q->mq) - RTA_PUT_FLAG(skb, TCA_PRIO_MQ); - RTA_NEST_COMPAT_END(skb, nest); + nest = nla_nest_compat_start(skb, TCA_OPTIONS, sizeof(opt), &opt); + if (nest == NULL) + goto nla_put_failure; + if (q->mq) { + if (nla_put_flag(skb, TCA_PRIO_MQ) < 0) + goto nla_put_failure; + } + nla_nest_compat_end(skb, nest); return skb->len; -rtattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } @@ -407,7 +399,7 @@ static void prio_put(struct Qdisc *q, unsigned long cl) return; } -static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct rtattr **tca, unsigned long *arg) +static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct nlattr **tca, unsigned long *arg) { unsigned long cl = *arg; struct prio_sched_data *q = qdisc_priv(sch); @@ -483,7 +475,7 @@ static struct tcf_proto ** prio_find_tcf(struct Qdisc *sch, unsigned long cl) return &q->filter_list; } -static struct Qdisc_class_ops prio_class_ops = { +static const struct Qdisc_class_ops prio_class_ops = { .graft = prio_graft, .leaf = prio_leaf, .get = prio_get, @@ -498,7 +490,7 @@ static struct Qdisc_class_ops prio_class_ops = { .dump_stats = prio_dump_class_stats, }; -static struct Qdisc_ops prio_qdisc_ops = { +static struct Qdisc_ops prio_qdisc_ops __read_mostly = { .next = NULL, .cl_ops = &prio_class_ops, .id = "prio", @@ -515,7 +507,7 @@ static struct Qdisc_ops prio_qdisc_ops = { .owner = THIS_MODULE, }; -static struct Qdisc_ops rr_qdisc_ops = { +static struct Qdisc_ops rr_qdisc_ops __read_mostly = { .next = NULL, .cl_ops = &prio_class_ops, .id = "rr",