Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 103585
b: refs/heads/master
c: 1d8ae3f
h: refs/heads/master
i:
  103583: 31faec9
v: v3
  • Loading branch information
David S. Miller committed Jul 18, 2008
1 parent 1ad7339 commit 1fa0f59
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 130 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 09e83b5d7d1878065e2453239b49b684cd0fe4e5
refs/heads/master: 1d8ae3fdeb001b8f534a6782c261aba6ec1779f5
9 changes: 0 additions & 9 deletions trunk/include/linux/pkt_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,6 @@ struct tc_prio_qopt
__u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
};

enum
{
TCA_PRIO_UNSPEC,
TCA_PRIO_MQ,
__TCA_PRIO_MAX
};

#define TCA_PRIO_MAX (__TCA_PRIO_MAX - 1)

/* TBF section */

struct tc_tbf_qopt
Expand Down
136 changes: 16 additions & 120 deletions trunk/net/sched/sch_prio.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@
struct prio_sched_data
{
int bands;
int curband; /* for round-robin */
struct tcf_proto *filter_list;
u8 prio2band[TC_PRIO_MAX+1];
struct Qdisc *queues[TCQ_PRIO_BANDS];
int mq;
};


Expand All @@ -55,17 +53,14 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
if (!q->filter_list || err < 0) {
if (TC_H_MAJ(band))
band = 0;
band = q->prio2band[band&TC_PRIO_MAX];
goto out;
return q->queues[q->prio2band[band&TC_PRIO_MAX]];
}
band = res.classid;
}
band = TC_H_MIN(band) - 1;
if (band >= q->bands)
band = q->prio2band[0];
out:
if (q->mq)
skb_set_queue_mapping(skb, band);
return q->queues[q->prio2band[0]];

return q->queues[band];
}

Expand Down Expand Up @@ -123,68 +118,23 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
}


static struct sk_buff *
prio_dequeue(struct Qdisc* sch)
static struct sk_buff *prio_dequeue(struct Qdisc* sch)
{
struct sk_buff *skb;
struct prio_sched_data *q = qdisc_priv(sch);
int prio;
struct Qdisc *qdisc;

for (prio = 0; prio < q->bands; prio++) {
/* Check if the target subqueue is available before
* pulling an skb. This way we avoid excessive requeues
* for slower queues.
*/
if (!__netif_subqueue_stopped(qdisc_dev(sch),
(q->mq ? prio : 0))) {
qdisc = q->queues[prio];
skb = qdisc->dequeue(qdisc);
if (skb) {
sch->q.qlen--;
return skb;
}
struct Qdisc *qdisc = q->queues[prio];
struct sk_buff *skb = qdisc->dequeue(qdisc);
if (skb) {
sch->q.qlen--;
return skb;
}
}
return NULL;

}

static struct sk_buff *rr_dequeue(struct Qdisc* sch)
{
struct sk_buff *skb;
struct prio_sched_data *q = qdisc_priv(sch);
struct Qdisc *qdisc;
int bandcount;

/* Only take one pass through the queues. If nothing is available,
* return nothing.
*/
for (bandcount = 0; bandcount < q->bands; bandcount++) {
/* Check if the target subqueue is available before
* pulling an skb. This way we avoid excessive requeues
* for slower queues. If the queue is stopped, try the
* next queue.
*/
if (!__netif_subqueue_stopped(qdisc_dev(sch),
(q->mq ? q->curband : 0))) {
qdisc = q->queues[q->curband];
skb = qdisc->dequeue(qdisc);
if (skb) {
sch->q.qlen--;
q->curband++;
if (q->curband >= q->bands)
q->curband = 0;
return skb;
}
}
q->curband++;
if (q->curband >= q->bands)
q->curband = 0;
}
return NULL;
}

static unsigned int prio_drop(struct Qdisc* sch)
{
struct prio_sched_data *q = qdisc_priv(sch);
Expand Down Expand Up @@ -229,45 +179,22 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
{
struct prio_sched_data *q = qdisc_priv(sch);
struct tc_prio_qopt *qopt;
struct nlattr *tb[TCA_PRIO_MAX + 1];
int err;
int i;

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. 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 = nla_get_flag(tb[TCA_PRIO_MQ]);
if (q->mq) {
if (sch->parent != TC_H_ROOT)
return -EINVAL;
if (netif_is_multiqueue(qdisc_dev(sch))) {
if (q->bands == 0)
q->bands = qdisc_dev(sch)->egress_subqueue_count;
else if (q->bands != qdisc_dev(sch)->egress_subqueue_count)
return -EINVAL;
} else
return -EOPNOTSUPP;
}
if (nla_len(opt) < sizeof(*qopt))
return -EINVAL;
qopt = nla_data(opt);

if (q->bands > TCQ_PRIO_BANDS || q->bands < 2)
if (qopt->bands > TCQ_PRIO_BANDS || qopt->bands < 2)
return -EINVAL;

for (i=0; i<=TC_PRIO_MAX; i++) {
if (qopt->priomap[i] >= q->bands)
if (qopt->priomap[i] >= qopt->bands)
return -EINVAL;
}

sch_tree_lock(sch);
q->bands = qopt->bands;
memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);

for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
Expand Down Expand Up @@ -333,10 +260,6 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
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;
Expand Down Expand Up @@ -509,44 +432,17 @@ static struct Qdisc_ops prio_qdisc_ops __read_mostly = {
.owner = THIS_MODULE,
};

static struct Qdisc_ops rr_qdisc_ops __read_mostly = {
.next = NULL,
.cl_ops = &prio_class_ops,
.id = "rr",
.priv_size = sizeof(struct prio_sched_data),
.enqueue = prio_enqueue,
.dequeue = rr_dequeue,
.requeue = prio_requeue,
.drop = prio_drop,
.init = prio_init,
.reset = prio_reset,
.destroy = prio_destroy,
.change = prio_tune,
.dump = prio_dump,
.owner = THIS_MODULE,
};

static int __init prio_module_init(void)
{
int err;

err = register_qdisc(&prio_qdisc_ops);
if (err < 0)
return err;
err = register_qdisc(&rr_qdisc_ops);
if (err < 0)
unregister_qdisc(&prio_qdisc_ops);
return err;
return register_qdisc(&prio_qdisc_ops);
}

static void __exit prio_module_exit(void)
{
unregister_qdisc(&prio_qdisc_ops);
unregister_qdisc(&rr_qdisc_ops);
}

module_init(prio_module_init)
module_exit(prio_module_exit)

MODULE_LICENSE("GPL");
MODULE_ALIAS("sch_rr");

0 comments on commit 1fa0f59

Please sign in to comment.