aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-17 03:50:32 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-17 22:21:26 -0400
commitead81cc5fc6d996db6afb20f211241612610a07a (patch)
tree5ffc3c7960f6ba755fe6e44eda0b82cdb8209180 /net/sched
parent15b458fa65cbba395724a99ab1b7d3785ca76c1c (diff)
netdevice: Move qdisc_list back into net_device proper.
And give it it's own lock. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_api.c31
-rw-r--r--net/sched/sch_generic.c9
2 files changed, 14 insertions, 26 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 8e8c5becc348..6958fe7c9a77 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -183,30 +183,17 @@ EXPORT_SYMBOL(unregister_qdisc);
183 (root qdisc, all its children, children of children etc.) 183 (root qdisc, all its children, children of children etc.)
184 */ 184 */
185 185
186static struct Qdisc *__qdisc_lookup(struct netdev_queue *dev_queue, u32 handle) 186struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
187{ 187{
188 struct Qdisc *q; 188 struct Qdisc *q;
189 189
190 list_for_each_entry(q, &dev_queue->qdisc_list, list) { 190 list_for_each_entry(q, &dev->qdisc_list, list) {
191 if (q->handle == handle) 191 if (q->handle == handle)
192 return q; 192 return q;
193 } 193 }
194 return NULL; 194 return NULL;
195} 195}
196 196
197struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
198{
199 unsigned int i;
200
201 for (i = 0; i < dev->num_tx_queues; i++) {
202 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
203 struct Qdisc *q = __qdisc_lookup(txq, handle);
204 if (q)
205 return q;
206 }
207 return NULL;
208}
209
210static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 197static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
211{ 198{
212 unsigned long cl; 199 unsigned long cl;
@@ -645,9 +632,9 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
645 goto err_out3; 632 goto err_out3;
646 } 633 }
647 } 634 }
648 qdisc_lock_tree(dev); 635 spin_lock_bh(&dev->qdisc_list_lock);
649 list_add_tail(&sch->list, &dev_queue->qdisc_list); 636 list_add_tail(&sch->list, &dev->qdisc_list);
650 qdisc_unlock_tree(dev); 637 spin_unlock_bh(&dev->qdisc_list_lock);
651 638
652 return sch; 639 return sch;
653 } 640 }
@@ -1032,14 +1019,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
1032 read_lock(&dev_base_lock); 1019 read_lock(&dev_base_lock);
1033 idx = 0; 1020 idx = 0;
1034 for_each_netdev(&init_net, dev) { 1021 for_each_netdev(&init_net, dev) {
1035 struct netdev_queue *dev_queue;
1036 if (idx < s_idx) 1022 if (idx < s_idx)
1037 goto cont; 1023 goto cont;
1038 if (idx > s_idx) 1024 if (idx > s_idx)
1039 s_q_idx = 0; 1025 s_q_idx = 0;
1040 q_idx = 0; 1026 q_idx = 0;
1041 dev_queue = netdev_get_tx_queue(dev, 0); 1027 list_for_each_entry(q, &dev->qdisc_list, list) {
1042 list_for_each_entry(q, &dev_queue->qdisc_list, list) {
1043 if (q_idx < s_q_idx) { 1028 if (q_idx < s_q_idx) {
1044 q_idx++; 1029 q_idx++;
1045 continue; 1030 continue;
@@ -1269,7 +1254,6 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk
1269static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) 1254static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1270{ 1255{
1271 struct net *net = sock_net(skb->sk); 1256 struct net *net = sock_net(skb->sk);
1272 struct netdev_queue *dev_queue;
1273 int t; 1257 int t;
1274 int s_t; 1258 int s_t;
1275 struct net_device *dev; 1259 struct net_device *dev;
@@ -1288,8 +1272,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1288 s_t = cb->args[0]; 1272 s_t = cb->args[0];
1289 t = 0; 1273 t = 0;
1290 1274
1291 dev_queue = netdev_get_tx_queue(dev, 0); 1275 list_for_each_entry(q, &dev->qdisc_list, list) {
1292 list_for_each_entry(q, &dev_queue->qdisc_list, list) {
1293 if (t < s_t || !q->ops->cl_ops || 1276 if (t < s_t || !q->ops->cl_ops ||
1294 (tcm->tcm_parent && 1277 (tcm->tcm_parent &&
1295 TC_H_MAJ(tcm->tcm_parent) != q->handle)) { 1278 TC_H_MAJ(tcm->tcm_parent) != q->handle)) {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index efa418a1b34e..8cdf0b4a6a5a 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -563,11 +563,15 @@ static void __qdisc_destroy(struct rcu_head *head)
563 563
564void qdisc_destroy(struct Qdisc *qdisc) 564void qdisc_destroy(struct Qdisc *qdisc)
565{ 565{
566 struct net_device *dev = qdisc_dev(qdisc);
567
566 if (qdisc->flags & TCQ_F_BUILTIN || 568 if (qdisc->flags & TCQ_F_BUILTIN ||
567 !atomic_dec_and_test(&qdisc->refcnt)) 569 !atomic_dec_and_test(&qdisc->refcnt))
568 return; 570 return;
569 571
572 spin_lock_bh(&dev->qdisc_list_lock);
570 list_del(&qdisc->list); 573 list_del(&qdisc->list);
574 spin_unlock_bh(&dev->qdisc_list_lock);
571 575
572 call_rcu(&qdisc->q_rcu, __qdisc_destroy); 576 call_rcu(&qdisc->q_rcu, __qdisc_destroy);
573} 577}
@@ -599,7 +603,9 @@ static void attach_one_default_qdisc(struct net_device *dev,
599 printk(KERN_INFO "%s: activation failed\n", dev->name); 603 printk(KERN_INFO "%s: activation failed\n", dev->name);
600 return; 604 return;
601 } 605 }
602 list_add_tail(&qdisc->list, &dev_queue->qdisc_list); 606 spin_lock_bh(&dev->qdisc_list_lock);
607 list_add_tail(&qdisc->list, &dev->qdisc_list);
608 spin_unlock_bh(&dev->qdisc_list_lock);
603 } else { 609 } else {
604 qdisc = &noqueue_qdisc; 610 qdisc = &noqueue_qdisc;
605 } 611 }
@@ -738,7 +744,6 @@ static void dev_init_scheduler_queue(struct net_device *dev,
738 744
739 dev_queue->qdisc = qdisc; 745 dev_queue->qdisc = qdisc;
740 dev_queue->qdisc_sleeping = qdisc; 746 dev_queue->qdisc_sleeping = qdisc;
741 INIT_LIST_HEAD(&dev_queue->qdisc_list);
742} 747}
743 748
744void dev_init_scheduler(struct net_device *dev) 749void dev_init_scheduler(struct net_device *dev)