diff options
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 50 |
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 | ||
186 | struct 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 | |||
186 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) | 201 | struct 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 | ||
206 | static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) | 216 | static 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 | } |
368 | EXPORT_SYMBOL(qdisc_put_stab); | 378 | EXPORT_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 | ||
1539 | done: | 1549 | done: |