aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_generic.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-09-04 02:41:18 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-06 05:07:03 -0400
commitaf356afa010f3cd2c8b8fcc3bce90f7a7b7ec02a (patch)
tree302d938363bbaec3e69a58e36dbf8a304b24144c /net/sched/sch_generic.c
parent5b9a9ccfad8553dbf7a9b17ba78bad70215ed0e2 (diff)
net_sched: reintroduce dev->qdisc for use by sch_api
Currently the multiqueue integration with the qdisc API suffers from a few problems: - with multiple queues, all root qdiscs use the same handle. This means they can't be exposed to userspace in a backwards compatible fashion. - all API operations always refer to queue number 0. Newly created qdiscs are automatically shared between all queues, its not possible to address individual queues or restore multiqueue behaviour once a shared qdisc has been attached. - Dumps only contain the root qdisc of queue 0, in case of non-shared qdiscs this means the statistics are incomplete. This patch reintroduces dev->qdisc, which points to the (single) root qdisc from userspace's point of view. Currently it either points to the first (non-shared) default qdisc, or a qdisc shared between all queues. The following patches will introduce a classful dummy qdisc, which will be used as root qdisc and contain the per-queue qdiscs as children. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r--net/sched/sch_generic.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 6128e6f24589..a91f079fb47a 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -623,19 +623,6 @@ void qdisc_destroy(struct Qdisc *qdisc)
623} 623}
624EXPORT_SYMBOL(qdisc_destroy); 624EXPORT_SYMBOL(qdisc_destroy);
625 625
626static bool dev_all_qdisc_sleeping_noop(struct net_device *dev)
627{
628 unsigned int i;
629
630 for (i = 0; i < dev->num_tx_queues; i++) {
631 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
632
633 if (txq->qdisc_sleeping != &noop_qdisc)
634 return false;
635 }
636 return true;
637}
638
639static void attach_one_default_qdisc(struct net_device *dev, 626static void attach_one_default_qdisc(struct net_device *dev,
640 struct netdev_queue *dev_queue, 627 struct netdev_queue *dev_queue,
641 void *_unused) 628 void *_unused)
@@ -677,6 +664,7 @@ static void transition_one_qdisc(struct net_device *dev,
677 664
678void dev_activate(struct net_device *dev) 665void dev_activate(struct net_device *dev)
679{ 666{
667 struct netdev_queue *txq;
680 int need_watchdog; 668 int need_watchdog;
681 669
682 /* No queueing discipline is attached to device; 670 /* No queueing discipline is attached to device;
@@ -685,9 +673,14 @@ void dev_activate(struct net_device *dev)
685 virtual interfaces 673 virtual interfaces
686 */ 674 */
687 675
688 if (dev_all_qdisc_sleeping_noop(dev)) 676 if (dev->qdisc == &noop_qdisc) {
689 netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL); 677 netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
690 678
679 txq = netdev_get_tx_queue(dev, 0);
680 dev->qdisc = txq->qdisc_sleeping;
681 atomic_inc(&dev->qdisc->refcnt);
682 }
683
691 if (!netif_carrier_ok(dev)) 684 if (!netif_carrier_ok(dev))
692 /* Delay activation until next carrier-on event */ 685 /* Delay activation until next carrier-on event */
693 return; 686 return;
@@ -777,6 +770,7 @@ static void dev_init_scheduler_queue(struct net_device *dev,
777 770
778void dev_init_scheduler(struct net_device *dev) 771void dev_init_scheduler(struct net_device *dev)
779{ 772{
773 dev->qdisc = &noop_qdisc;
780 netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); 774 netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
781 dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); 775 dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
782 776
@@ -802,5 +796,8 @@ void dev_shutdown(struct net_device *dev)
802{ 796{
803 netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); 797 netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
804 shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); 798 shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
799 qdisc_destroy(dev->qdisc);
800 dev->qdisc = &noop_qdisc;
801
805 WARN_ON(timer_pending(&dev->watchdog_timer)); 802 WARN_ON(timer_pending(&dev->watchdog_timer));
806} 803}