aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_api.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-09-06 04:58:51 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-06 05:07:05 -0400
commit6ec1c69a8f6492fd25722f4762721921da074c12 (patch)
treea78323d1f7f84acbe08c25d7300b935ae4bb7c62 /net/sched/sch_api.c
parent589983cd21f4a2e4ed74a958805a90fa676845c5 (diff)
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.c18
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,
678 if (dev->flags & IFF_UP) 678 if (dev->flags & IFF_UP)
679 dev_deactivate(dev); 679 dev_deactivate(dev);
680 680
681 if (new && new->ops->attach) {
682 new->ops->attach(new);
683 num_q = 0;
684 }
685
681 for (i = 0; i < num_q; i++) { 686 for (i = 0; i < num_q; i++) {
682 struct netdev_queue *dev_queue = &dev->rx_queue; 687 struct netdev_queue *dev_queue = &dev->rx_queue;
683 688
@@ -692,7 +697,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
692 } 697 }
693 698
694 notify_and_destroy(skb, n, classid, dev->qdisc, new); 699 notify_and_destroy(skb, n, classid, dev->qdisc, new);
695 if (new) 700 if (new && !new->ops->attach)
696 atomic_inc(&new->refcnt); 701 atomic_inc(&new->refcnt);
697 dev->qdisc = new ? : &noop_qdisc; 702 dev->qdisc = new ? : &noop_qdisc;
698 703
@@ -1095,10 +1100,16 @@ create_n_graft:
1095 q = qdisc_create(dev, &dev->rx_queue, 1100 q = qdisc_create(dev, &dev->rx_queue,
1096 tcm->tcm_parent, tcm->tcm_parent, 1101 tcm->tcm_parent, tcm->tcm_parent,
1097 tca, &err); 1102 tca, &err);
1098 else 1103 else {
1099 q = qdisc_create(dev, netdev_get_tx_queue(dev, 0), 1104 unsigned int ntx = 0;
1105
1106 if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue)
1107 ntx = p->ops->cl_ops->select_queue(p, tcm);
1108
1109 q = qdisc_create(dev, netdev_get_tx_queue(dev, ntx),
1100 tcm->tcm_parent, tcm->tcm_handle, 1110 tcm->tcm_parent, tcm->tcm_handle,
1101 tca, &err); 1111 tca, &err);
1112 }
1102 if (q == NULL) { 1113 if (q == NULL) {
1103 if (err == -EAGAIN) 1114 if (err == -EAGAIN)
1104 goto replay; 1115 goto replay;
@@ -1674,6 +1685,7 @@ static int __init pktsched_init(void)
1674{ 1685{
1675 register_qdisc(&pfifo_qdisc_ops); 1686 register_qdisc(&pfifo_qdisc_ops);
1676 register_qdisc(&bfifo_qdisc_ops); 1687 register_qdisc(&bfifo_qdisc_ops);
1688 register_qdisc(&mq_qdisc_ops);
1677 proc_net_fops_create(&init_net, "psched", 0, &psched_fops); 1689 proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
1678 1690
1679 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); 1691 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);