diff options
author | David S. Miller <davem@davemloft.net> | 2009-09-06 01:58:51 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-06 02:07:05 -0700 |
commit | 6ec1c69a8f6492fd25722f4762721921da074c12 (patch) | |
tree | a78323d1f7f84acbe08c25d7300b935ae4bb7c62 /net/sched/sch_api.c | |
parent | 589983cd21f4a2e4ed74a958805a90fa676845c5 (diff) | |
download | linux-stable-6ec1c69a8f6492fd25722f4762721921da074c12.tar.gz linux-stable-6ec1c69a8f6492fd25722f4762721921da074c12.tar.bz2 linux-stable-6ec1c69a8f6492fd25722f4762721921da074c12.zip |
net_sched: add classful multiqueue dummy scheduler
This patch adds a classful dummy scheduler which can be used as root qdisc
for multiqueue devices and exposes each device queue as a child class.
This allows to address queues individually and graft them similar to regular
classes. Additionally it presents an accumulated view of the statistics of
all real root qdiscs in the dummy root.
Two new callbacks are added to the qdisc_ops and qdisc_class_ops:
- cl_ops->select_queue selects the tx queue number for new child classes.
- qdisc_ops->attach() overrides root qdisc device grafting to attach
non-shared qdiscs to the queues.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index d71f12be6e29..2a78d5410154 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -678,6 +678,11 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, if (dev->flags & IFF_UP) dev_deactivate(dev); + if (new && new->ops->attach) { + new->ops->attach(new); + num_q = 0; + } + for (i = 0; i < num_q; i++) { struct netdev_queue *dev_queue = &dev->rx_queue; @@ -692,7 +697,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, } notify_and_destroy(skb, n, classid, dev->qdisc, new); - if (new) + if (new && !new->ops->attach) atomic_inc(&new->refcnt); dev->qdisc = new ? : &noop_qdisc; @@ -1095,10 +1100,16 @@ create_n_graft: q = qdisc_create(dev, &dev->rx_queue, tcm->tcm_parent, tcm->tcm_parent, tca, &err); - else - q = qdisc_create(dev, netdev_get_tx_queue(dev, 0), + else { + unsigned int ntx = 0; + + if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue) + ntx = p->ops->cl_ops->select_queue(p, tcm); + + q = qdisc_create(dev, netdev_get_tx_queue(dev, ntx), tcm->tcm_parent, tcm->tcm_handle, tca, &err); + } if (q == NULL) { if (err == -EAGAIN) goto replay; @@ -1674,6 +1685,7 @@ static int __init pktsched_init(void) { register_qdisc(&pfifo_qdisc_ops); register_qdisc(&bfifo_qdisc_ops); + register_qdisc(&mq_qdisc_ops); proc_net_fops_create(&init_net, "psched", 0, &psched_fops); rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); |