aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r--net/sched/sch_api.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index ba1d121f3127..c25465e5607a 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -183,6 +183,21 @@ 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
186struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
187{
188 struct Qdisc *q;
189
190 if (!(root->flags & TCQ_F_BUILTIN) &&
191 root->handle == handle)
192 return root;
193
194 list_for_each_entry(q, &root->list, list) {
195 if (q->handle == handle)
196 return q;
197 }
198 return NULL;
199}
200
186struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) 201struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
187{ 202{
188 unsigned int i; 203 unsigned int i;
@@ -191,16 +206,11 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
191 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 206 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
192 struct Qdisc *q, *txq_root = txq->qdisc_sleeping; 207 struct Qdisc *q, *txq_root = txq->qdisc_sleeping;
193 208
194 if (!(txq_root->flags & TCQ_F_BUILTIN) && 209 q = qdisc_match_from_root(txq_root, handle);
195 txq_root->handle == handle) 210 if (q)
196 return txq_root; 211 return q;
197
198 list_for_each_entry(q, &txq_root->list, list) {
199 if (q->handle == handle)
200 return q;
201 }
202 } 212 }
203 return NULL; 213 return qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
204} 214}
205 215
206static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 216static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
@@ -321,7 +331,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
321 if (!s || tsize != s->tsize || (!tab && tsize > 0)) 331 if (!s || tsize != s->tsize || (!tab && tsize > 0))
322 return ERR_PTR(-EINVAL); 332 return ERR_PTR(-EINVAL);
323 333
324 spin_lock(&qdisc_stab_lock); 334 spin_lock_bh(&qdisc_stab_lock);
325 335
326 list_for_each_entry(stab, &qdisc_stab_list, list) { 336 list_for_each_entry(stab, &qdisc_stab_list, list) {
327 if (memcmp(&stab->szopts, s, sizeof(*s))) 337 if (memcmp(&stab->szopts, s, sizeof(*s)))
@@ -329,11 +339,11 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
329 if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16))) 339 if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16)))
330 continue; 340 continue;
331 stab->refcnt++; 341 stab->refcnt++;
332 spin_unlock(&qdisc_stab_lock); 342 spin_unlock_bh(&qdisc_stab_lock);
333 return stab; 343 return stab;
334 } 344 }
335 345
336 spin_unlock(&qdisc_stab_lock); 346 spin_unlock_bh(&qdisc_stab_lock);
337 347
338 stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL); 348 stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL);
339 if (!stab) 349 if (!stab)
@@ -344,9 +354,9 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
344 if (tsize > 0) 354 if (tsize > 0)
345 memcpy(stab->data, tab, tsize * sizeof(u16)); 355 memcpy(stab->data, tab, tsize * sizeof(u16));
346 356
347 spin_lock(&qdisc_stab_lock); 357 spin_lock_bh(&qdisc_stab_lock);
348 list_add_tail(&stab->list, &qdisc_stab_list); 358 list_add_tail(&stab->list, &qdisc_stab_list);
349 spin_unlock(&qdisc_stab_lock); 359 spin_unlock_bh(&qdisc_stab_lock);
350 360
351 return stab; 361 return stab;
352} 362}
@@ -356,14 +366,14 @@ void qdisc_put_stab(struct qdisc_size_table *tab)
356 if (!tab) 366 if (!tab)
357 return; 367 return;
358 368
359 spin_lock(&qdisc_stab_lock); 369 spin_lock_bh(&qdisc_stab_lock);
360 370
361 if (--tab->refcnt == 0) { 371 if (--tab->refcnt == 0) {
362 list_del(&tab->list); 372 list_del(&tab->list);
363 kfree(tab); 373 kfree(tab);
364 } 374 }
365 375
366 spin_unlock(&qdisc_stab_lock); 376 spin_unlock_bh(&qdisc_stab_lock);
367} 377}
368EXPORT_SYMBOL(qdisc_put_stab); 378EXPORT_SYMBOL(qdisc_put_stab);
369 379
@@ -908,7 +918,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
908 return -ENOENT; 918 return -ENOENT;
909 q = qdisc_leaf(p, clid); 919 q = qdisc_leaf(p, clid);
910 } else { /* ingress */ 920 } else { /* ingress */
911 q = dev->rx_queue.qdisc; 921 q = dev->rx_queue.qdisc_sleeping;
912 } 922 }
913 } else { 923 } else {
914 struct netdev_queue *dev_queue; 924 struct netdev_queue *dev_queue;
@@ -978,7 +988,7 @@ replay:
978 return -ENOENT; 988 return -ENOENT;
979 q = qdisc_leaf(p, clid); 989 q = qdisc_leaf(p, clid);
980 } else { /*ingress */ 990 } else { /*ingress */
981 q = dev->rx_queue.qdisc; 991 q = dev->rx_queue.qdisc_sleeping;
982 } 992 }
983 } else { 993 } else {
984 struct netdev_queue *dev_queue; 994 struct netdev_queue *dev_queue;
@@ -1529,11 +1539,11 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1529 t = 0; 1539 t = 0;
1530 1540
1531 dev_queue = netdev_get_tx_queue(dev, 0); 1541 dev_queue = netdev_get_tx_queue(dev, 0);
1532 if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) 1542 if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
1533 goto done; 1543 goto done;
1534 1544
1535 dev_queue = &dev->rx_queue; 1545 dev_queue = &dev->rx_queue;
1536 if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) 1546 if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
1537 goto done; 1547 goto done;
1538 1548
1539done: 1549done: