diff options
| -rw-r--r-- | drivers/isdn/i4l/isdn_net.c | 2 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 10 | ||||
| -rw-r--r-- | include/net/irda/irda_device.h | 2 | ||||
| -rw-r--r-- | net/core/dev.c | 4 | ||||
| -rw-r--r-- | net/core/link_watch.c | 8 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 6 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 3 | ||||
| -rw-r--r-- | net/mac80211/wme.c | 20 | ||||
| -rw-r--r-- | net/sched/cls_api.c | 7 | ||||
| -rw-r--r-- | net/sched/sch_api.c | 34 | ||||
| -rw-r--r-- | net/sched/sch_generic.c | 90 | ||||
| -rw-r--r-- | net/sched/sch_netem.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_teql.c | 14 |
13 files changed, 125 insertions, 77 deletions
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index ef1a300068dc..457bbd119f9b 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
| @@ -287,7 +287,7 @@ isdn_net_unbind_channel(isdn_net_local * lp) | |||
| 287 | BEWARE! This chunk of code cannot be called from hardware | 287 | BEWARE! This chunk of code cannot be called from hardware |
| 288 | interrupt handler. I hope it is true. --ANK | 288 | interrupt handler. I hope it is true. --ANK |
| 289 | */ | 289 | */ |
| 290 | qdisc_reset(lp->netdev->dev->qdisc); | 290 | qdisc_reset(lp->netdev->dev->tx_queue.qdisc); |
| 291 | } | 291 | } |
| 292 | lp->dialstate = 0; | 292 | lp->dialstate = 0; |
| 293 | dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL; | 293 | dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 633a44c6fa5e..df702a7b3db5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -451,6 +451,9 @@ static inline void napi_synchronize(const struct napi_struct *n) | |||
| 451 | struct netdev_queue { | 451 | struct netdev_queue { |
| 452 | spinlock_t lock; | 452 | spinlock_t lock; |
| 453 | struct net_device *dev; | 453 | struct net_device *dev; |
| 454 | struct Qdisc *qdisc; | ||
| 455 | struct Qdisc *qdisc_sleeping; | ||
| 456 | struct list_head qdisc_list; | ||
| 454 | }; | 457 | }; |
| 455 | 458 | ||
| 456 | /* | 459 | /* |
| @@ -634,13 +637,6 @@ struct net_device | |||
| 634 | 637 | ||
| 635 | struct Qdisc *qdisc_ingress; | 638 | struct Qdisc *qdisc_ingress; |
| 636 | 639 | ||
| 637 | /* | ||
| 638 | * Cache line mostly used on queue transmit path (qdisc) | ||
| 639 | */ | ||
| 640 | /* device queue lock */ | ||
| 641 | struct Qdisc *qdisc; | ||
| 642 | struct Qdisc *qdisc_sleeping; | ||
| 643 | struct list_head qdisc_list; | ||
| 644 | unsigned long tx_queue_len; /* Max frames per queue allowed */ | 640 | unsigned long tx_queue_len; /* Max frames per queue allowed */ |
| 645 | 641 | ||
| 646 | /* Partially transmitted GSO packet. */ | 642 | /* Partially transmitted GSO packet. */ |
diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h index f70e9b39ebaf..16fbf672e0b2 100644 --- a/include/net/irda/irda_device.h +++ b/include/net/irda/irda_device.h | |||
| @@ -223,7 +223,7 @@ int irda_device_is_receiving(struct net_device *dev); | |||
| 223 | /* Interface for internal use */ | 223 | /* Interface for internal use */ |
| 224 | static inline int irda_device_txqueue_empty(const struct net_device *dev) | 224 | static inline int irda_device_txqueue_empty(const struct net_device *dev) |
| 225 | { | 225 | { |
| 226 | return skb_queue_empty(&dev->qdisc->q); | 226 | return skb_queue_empty(&dev->tx_queue.qdisc->q); |
| 227 | } | 227 | } |
| 228 | int irda_device_set_raw_mode(struct net_device* self, int status); | 228 | int irda_device_set_raw_mode(struct net_device* self, int status); |
| 229 | struct net_device *alloc_irdadev(int sizeof_priv); | 229 | struct net_device *alloc_irdadev(int sizeof_priv); |
diff --git a/net/core/dev.c b/net/core/dev.c index 2322fb69fd53..ce79c28d739d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1720,14 +1720,14 @@ gso: | |||
| 1720 | * also serializes access to the device queue. | 1720 | * also serializes access to the device queue. |
| 1721 | */ | 1721 | */ |
| 1722 | 1722 | ||
| 1723 | q = rcu_dereference(dev->qdisc); | 1723 | q = rcu_dereference(txq->qdisc); |
| 1724 | #ifdef CONFIG_NET_CLS_ACT | 1724 | #ifdef CONFIG_NET_CLS_ACT |
| 1725 | skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); | 1725 | skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); |
| 1726 | #endif | 1726 | #endif |
| 1727 | if (q->enqueue) { | 1727 | if (q->enqueue) { |
| 1728 | /* Grab device queue */ | 1728 | /* Grab device queue */ |
| 1729 | spin_lock(&txq->lock); | 1729 | spin_lock(&txq->lock); |
| 1730 | q = dev->qdisc; | 1730 | q = txq->qdisc; |
| 1731 | if (q->enqueue) { | 1731 | if (q->enqueue) { |
| 1732 | /* reset queue_mapping to zero */ | 1732 | /* reset queue_mapping to zero */ |
| 1733 | skb_set_queue_mapping(skb, 0); | 1733 | skb_set_queue_mapping(skb, 0); |
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index a5e372b9ec4d..50218218445b 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
| @@ -79,8 +79,10 @@ static void rfc2863_policy(struct net_device *dev) | |||
| 79 | 79 | ||
| 80 | static int linkwatch_urgent_event(struct net_device *dev) | 80 | static int linkwatch_urgent_event(struct net_device *dev) |
| 81 | { | 81 | { |
| 82 | struct netdev_queue *txq = &dev->tx_queue; | ||
| 83 | |||
| 82 | return netif_running(dev) && netif_carrier_ok(dev) && | 84 | return netif_running(dev) && netif_carrier_ok(dev) && |
| 83 | dev->qdisc != dev->qdisc_sleeping; | 85 | txq->qdisc != txq->qdisc_sleeping; |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | 88 | ||
| @@ -181,7 +183,9 @@ static void __linkwatch_run_queue(int urgent_only) | |||
| 181 | rfc2863_policy(dev); | 183 | rfc2863_policy(dev); |
| 182 | if (dev->flags & IFF_UP) { | 184 | if (dev->flags & IFF_UP) { |
| 183 | if (netif_carrier_ok(dev)) { | 185 | if (netif_carrier_ok(dev)) { |
| 184 | WARN_ON(dev->qdisc_sleeping == &noop_qdisc); | 186 | struct netdev_queue *txq = &dev->tx_queue; |
| 187 | |||
| 188 | WARN_ON(txq->qdisc_sleeping == &noop_qdisc); | ||
| 185 | dev_activate(dev); | 189 | dev_activate(dev); |
| 186 | } else | 190 | } else |
| 187 | dev_deactivate(dev); | 191 | dev_deactivate(dev); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 6c8d7f0ea01a..8ef9f1db610e 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -605,6 +605,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 605 | int type, u32 pid, u32 seq, u32 change, | 605 | int type, u32 pid, u32 seq, u32 change, |
| 606 | unsigned int flags) | 606 | unsigned int flags) |
| 607 | { | 607 | { |
| 608 | struct netdev_queue *txq; | ||
| 608 | struct ifinfomsg *ifm; | 609 | struct ifinfomsg *ifm; |
| 609 | struct nlmsghdr *nlh; | 610 | struct nlmsghdr *nlh; |
| 610 | struct net_device_stats *stats; | 611 | struct net_device_stats *stats; |
| @@ -635,8 +636,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 635 | if (dev->master) | 636 | if (dev->master) |
| 636 | NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex); | 637 | NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex); |
| 637 | 638 | ||
| 638 | if (dev->qdisc_sleeping) | 639 | txq = &dev->tx_queue; |
| 639 | NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id); | 640 | if (txq->qdisc_sleeping) |
| 641 | NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id); | ||
| 640 | 642 | ||
| 641 | if (1) { | 643 | if (1) { |
| 642 | struct rtnl_link_ifmap map = { | 644 | struct rtnl_link_ifmap map = { |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8572cb05fc21..5c84c798331d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -231,7 +231,8 @@ const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTER | |||
| 231 | /* Check if a valid qdisc is available */ | 231 | /* Check if a valid qdisc is available */ |
| 232 | static inline int addrconf_qdisc_ok(struct net_device *dev) | 232 | static inline int addrconf_qdisc_ok(struct net_device *dev) |
| 233 | { | 233 | { |
| 234 | return (dev->qdisc != &noop_qdisc); | 234 | struct netdev_queue *txq = &dev->tx_queue; |
| 235 | return (txq->qdisc != &noop_qdisc); | ||
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | /* Check if a route is valid prefix route */ | 238 | /* Check if a route is valid prefix route */ |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 59ed9cae66b9..6ae43a3c7726 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -574,9 +574,10 @@ static struct Qdisc_ops wme_qdisc_ops __read_mostly = | |||
| 574 | 574 | ||
| 575 | void ieee80211_install_qdisc(struct net_device *dev) | 575 | void ieee80211_install_qdisc(struct net_device *dev) |
| 576 | { | 576 | { |
| 577 | struct netdev_queue *txq = &dev->tx_queue; | ||
| 577 | struct Qdisc *qdisc; | 578 | struct Qdisc *qdisc; |
| 578 | 579 | ||
| 579 | qdisc = qdisc_create_dflt(dev, &dev->tx_queue, | 580 | qdisc = qdisc_create_dflt(dev, txq, |
| 580 | &wme_qdisc_ops, TC_H_ROOT); | 581 | &wme_qdisc_ops, TC_H_ROOT); |
| 581 | if (!qdisc) { | 582 | if (!qdisc) { |
| 582 | printk(KERN_ERR "%s: qdisc installation failed\n", dev->name); | 583 | printk(KERN_ERR "%s: qdisc installation failed\n", dev->name); |
| @@ -587,15 +588,17 @@ void ieee80211_install_qdisc(struct net_device *dev) | |||
| 587 | qdisc->handle = 0x80010000; | 588 | qdisc->handle = 0x80010000; |
| 588 | 589 | ||
| 589 | qdisc_lock_tree(dev); | 590 | qdisc_lock_tree(dev); |
| 590 | list_add_tail(&qdisc->list, &dev->qdisc_list); | 591 | list_add_tail(&qdisc->list, &txq->qdisc_list); |
| 591 | dev->qdisc_sleeping = qdisc; | 592 | txq->qdisc_sleeping = qdisc; |
| 592 | qdisc_unlock_tree(dev); | 593 | qdisc_unlock_tree(dev); |
| 593 | } | 594 | } |
| 594 | 595 | ||
| 595 | 596 | ||
| 596 | int ieee80211_qdisc_installed(struct net_device *dev) | 597 | int ieee80211_qdisc_installed(struct net_device *dev) |
| 597 | { | 598 | { |
| 598 | return dev->qdisc_sleeping->ops == &wme_qdisc_ops; | 599 | struct netdev_queue *txq = &dev->tx_queue; |
| 600 | |||
| 601 | return txq->qdisc_sleeping->ops == &wme_qdisc_ops; | ||
| 599 | } | 602 | } |
| 600 | 603 | ||
| 601 | 604 | ||
| @@ -614,8 +617,9 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
| 614 | struct sta_info *sta, u16 tid) | 617 | struct sta_info *sta, u16 tid) |
| 615 | { | 618 | { |
| 616 | int i; | 619 | int i; |
| 620 | struct netdev_queue *txq = &local->mdev->tx_queue; | ||
| 617 | struct ieee80211_sched_data *q = | 621 | struct ieee80211_sched_data *q = |
| 618 | qdisc_priv(local->mdev->qdisc_sleeping); | 622 | qdisc_priv(txq->qdisc_sleeping); |
| 619 | DECLARE_MAC_BUF(mac); | 623 | DECLARE_MAC_BUF(mac); |
| 620 | 624 | ||
| 621 | /* prepare the filter and save it for the SW queue | 625 | /* prepare the filter and save it for the SW queue |
| @@ -655,8 +659,9 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | |||
| 655 | u8 requeue) | 659 | u8 requeue) |
| 656 | { | 660 | { |
| 657 | struct ieee80211_hw *hw = &local->hw; | 661 | struct ieee80211_hw *hw = &local->hw; |
| 662 | struct netdev_queue *txq = &local->mdev->tx_queue; | ||
| 658 | struct ieee80211_sched_data *q = | 663 | struct ieee80211_sched_data *q = |
| 659 | qdisc_priv(local->mdev->qdisc_sleeping); | 664 | qdisc_priv(txq->qdisc_sleeping); |
| 660 | int agg_queue = sta->tid_to_tx_q[tid]; | 665 | int agg_queue = sta->tid_to_tx_q[tid]; |
| 661 | 666 | ||
| 662 | /* return the qdisc to the pool */ | 667 | /* return the qdisc to the pool */ |
| @@ -671,7 +676,8 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | |||
| 671 | 676 | ||
| 672 | void ieee80211_requeue(struct ieee80211_local *local, int queue) | 677 | void ieee80211_requeue(struct ieee80211_local *local, int queue) |
| 673 | { | 678 | { |
| 674 | struct Qdisc *root_qd = local->mdev->qdisc_sleeping; | 679 | struct netdev_queue *txq = &local->mdev->tx_queue; |
| 680 | struct Qdisc *root_qd = txq->qdisc_sleeping; | ||
| 675 | struct ieee80211_sched_data *q = qdisc_priv(root_qd); | 681 | struct ieee80211_sched_data *q = qdisc_priv(root_qd); |
| 676 | struct Qdisc *qdisc = q->queues[queue]; | 682 | struct Qdisc *qdisc = q->queues[queue]; |
| 677 | struct sk_buff *skb = NULL; | 683 | struct sk_buff *skb = NULL; |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index e2389f161e46..b483bbea6118 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
| @@ -166,7 +166,8 @@ replay: | |||
| 166 | 166 | ||
| 167 | /* Find qdisc */ | 167 | /* Find qdisc */ |
| 168 | if (!parent) { | 168 | if (!parent) { |
| 169 | q = dev->qdisc_sleeping; | 169 | struct netdev_queue *dev_queue = &dev->tx_queue; |
| 170 | q = dev_queue->qdisc_sleeping; | ||
| 170 | parent = q->handle; | 171 | parent = q->handle; |
| 171 | } else { | 172 | } else { |
| 172 | q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent)); | 173 | q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent)); |
| @@ -390,6 +391,7 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, | |||
| 390 | static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) | 391 | static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) |
| 391 | { | 392 | { |
| 392 | struct net *net = sock_net(skb->sk); | 393 | struct net *net = sock_net(skb->sk); |
| 394 | struct netdev_queue *dev_queue; | ||
| 393 | int t; | 395 | int t; |
| 394 | int s_t; | 396 | int s_t; |
| 395 | struct net_device *dev; | 397 | struct net_device *dev; |
| @@ -408,8 +410,9 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 408 | if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) | 410 | if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) |
| 409 | return skb->len; | 411 | return skb->len; |
| 410 | 412 | ||
| 413 | dev_queue = &dev->tx_queue; | ||
| 411 | if (!tcm->tcm_parent) | 414 | if (!tcm->tcm_parent) |
| 412 | q = dev->qdisc_sleeping; | 415 | q = dev_queue->qdisc_sleeping; |
| 413 | else | 416 | else |
| 414 | q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); | 417 | q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); |
| 415 | if (!q) | 418 | if (!q) |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 570cef2a9c5f..2313fa7c97be 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
| @@ -185,9 +185,10 @@ EXPORT_SYMBOL(unregister_qdisc); | |||
| 185 | 185 | ||
| 186 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) | 186 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) |
| 187 | { | 187 | { |
| 188 | struct netdev_queue *dev_queue = &dev->tx_queue; | ||
| 188 | struct Qdisc *q; | 189 | struct Qdisc *q; |
| 189 | 190 | ||
| 190 | list_for_each_entry(q, &dev->qdisc_list, list) { | 191 | list_for_each_entry(q, &dev_queue->qdisc_list, list) { |
| 191 | if (q->handle == handle) | 192 | if (q->handle == handle) |
| 192 | return q; | 193 | return q; |
| 193 | } | 194 | } |
| @@ -441,6 +442,7 @@ static u32 qdisc_alloc_handle(struct net_device *dev) | |||
| 441 | static struct Qdisc * | 442 | static struct Qdisc * |
| 442 | dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) | 443 | dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) |
| 443 | { | 444 | { |
| 445 | struct netdev_queue *dev_queue; | ||
| 444 | struct Qdisc *oqdisc; | 446 | struct Qdisc *oqdisc; |
| 445 | 447 | ||
| 446 | if (dev->flags & IFF_UP) | 448 | if (dev->flags & IFF_UP) |
| @@ -459,8 +461,8 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) | |||
| 459 | } | 461 | } |
| 460 | 462 | ||
| 461 | } else { | 463 | } else { |
| 462 | 464 | dev_queue = &dev->tx_queue; | |
| 463 | oqdisc = dev->qdisc_sleeping; | 465 | oqdisc = dev_queue->qdisc_sleeping; |
| 464 | 466 | ||
| 465 | /* Prune old scheduler */ | 467 | /* Prune old scheduler */ |
| 466 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) | 468 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) |
| @@ -469,8 +471,8 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) | |||
| 469 | /* ... and graft new one */ | 471 | /* ... and graft new one */ |
| 470 | if (qdisc == NULL) | 472 | if (qdisc == NULL) |
| 471 | qdisc = &noop_qdisc; | 473 | qdisc = &noop_qdisc; |
| 472 | dev->qdisc_sleeping = qdisc; | 474 | dev_queue->qdisc_sleeping = qdisc; |
| 473 | dev->qdisc = &noop_qdisc; | 475 | dev_queue->qdisc = &noop_qdisc; |
| 474 | } | 476 | } |
| 475 | 477 | ||
| 476 | qdisc_unlock_tree(dev); | 478 | qdisc_unlock_tree(dev); |
| @@ -633,7 +635,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, | |||
| 633 | } | 635 | } |
| 634 | } | 636 | } |
| 635 | qdisc_lock_tree(dev); | 637 | qdisc_lock_tree(dev); |
| 636 | list_add_tail(&sch->list, &dev->qdisc_list); | 638 | list_add_tail(&sch->list, &dev_queue->qdisc_list); |
| 637 | qdisc_unlock_tree(dev); | 639 | qdisc_unlock_tree(dev); |
| 638 | 640 | ||
| 639 | return sch; | 641 | return sch; |
| @@ -740,7 +742,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 740 | q = dev->qdisc_ingress; | 742 | q = dev->qdisc_ingress; |
| 741 | } | 743 | } |
| 742 | } else { | 744 | } else { |
| 743 | q = dev->qdisc_sleeping; | 745 | struct netdev_queue *dev_queue = &dev->tx_queue; |
| 746 | q = dev_queue->qdisc_sleeping; | ||
| 744 | } | 747 | } |
| 745 | if (!q) | 748 | if (!q) |
| 746 | return -ENOENT; | 749 | return -ENOENT; |
| @@ -814,7 +817,8 @@ replay: | |||
| 814 | q = dev->qdisc_ingress; | 817 | q = dev->qdisc_ingress; |
| 815 | } | 818 | } |
| 816 | } else { | 819 | } else { |
| 817 | q = dev->qdisc_sleeping; | 820 | struct netdev_queue *dev_queue = &dev->tx_queue; |
| 821 | q = dev_queue->qdisc_sleeping; | ||
| 818 | } | 822 | } |
| 819 | 823 | ||
| 820 | /* It may be default qdisc, ignore it */ | 824 | /* It may be default qdisc, ignore it */ |
| @@ -1015,12 +1019,14 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1015 | read_lock(&dev_base_lock); | 1019 | read_lock(&dev_base_lock); |
| 1016 | idx = 0; | 1020 | idx = 0; |
| 1017 | for_each_netdev(&init_net, dev) { | 1021 | for_each_netdev(&init_net, dev) { |
| 1022 | struct netdev_queue *dev_queue; | ||
| 1018 | if (idx < s_idx) | 1023 | if (idx < s_idx) |
| 1019 | goto cont; | 1024 | goto cont; |
| 1020 | if (idx > s_idx) | 1025 | if (idx > s_idx) |
| 1021 | s_q_idx = 0; | 1026 | s_q_idx = 0; |
| 1022 | q_idx = 0; | 1027 | q_idx = 0; |
| 1023 | list_for_each_entry(q, &dev->qdisc_list, list) { | 1028 | dev_queue = &dev->tx_queue; |
| 1029 | list_for_each_entry(q, &dev_queue->qdisc_list, list) { | ||
| 1024 | if (q_idx < s_q_idx) { | 1030 | if (q_idx < s_q_idx) { |
| 1025 | q_idx++; | 1031 | q_idx++; |
| 1026 | continue; | 1032 | continue; |
| @@ -1054,6 +1060,7 @@ done: | |||
| 1054 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 1060 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) |
| 1055 | { | 1061 | { |
| 1056 | struct net *net = sock_net(skb->sk); | 1062 | struct net *net = sock_net(skb->sk); |
| 1063 | struct netdev_queue *dev_queue; | ||
| 1057 | struct tcmsg *tcm = NLMSG_DATA(n); | 1064 | struct tcmsg *tcm = NLMSG_DATA(n); |
| 1058 | struct nlattr *tca[TCA_MAX + 1]; | 1065 | struct nlattr *tca[TCA_MAX + 1]; |
| 1059 | struct net_device *dev; | 1066 | struct net_device *dev; |
| @@ -1091,6 +1098,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1091 | 1098 | ||
| 1092 | /* Step 1. Determine qdisc handle X:0 */ | 1099 | /* Step 1. Determine qdisc handle X:0 */ |
| 1093 | 1100 | ||
| 1101 | dev_queue = &dev->tx_queue; | ||
| 1094 | if (pid != TC_H_ROOT) { | 1102 | if (pid != TC_H_ROOT) { |
| 1095 | u32 qid1 = TC_H_MAJ(pid); | 1103 | u32 qid1 = TC_H_MAJ(pid); |
| 1096 | 1104 | ||
| @@ -1101,7 +1109,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1101 | } else if (qid1) { | 1109 | } else if (qid1) { |
| 1102 | qid = qid1; | 1110 | qid = qid1; |
| 1103 | } else if (qid == 0) | 1111 | } else if (qid == 0) |
| 1104 | qid = dev->qdisc_sleeping->handle; | 1112 | qid = dev_queue->qdisc_sleeping->handle; |
| 1105 | 1113 | ||
| 1106 | /* Now qid is genuine qdisc handle consistent | 1114 | /* Now qid is genuine qdisc handle consistent |
| 1107 | both with parent and child. | 1115 | both with parent and child. |
| @@ -1112,7 +1120,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1112 | pid = TC_H_MAKE(qid, pid); | 1120 | pid = TC_H_MAKE(qid, pid); |
| 1113 | } else { | 1121 | } else { |
| 1114 | if (qid == 0) | 1122 | if (qid == 0) |
| 1115 | qid = dev->qdisc_sleeping->handle; | 1123 | qid = dev_queue->qdisc_sleeping->handle; |
| 1116 | } | 1124 | } |
| 1117 | 1125 | ||
| 1118 | /* OK. Locate qdisc */ | 1126 | /* OK. Locate qdisc */ |
| @@ -1248,6 +1256,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk | |||
| 1248 | static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | 1256 | static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) |
| 1249 | { | 1257 | { |
| 1250 | struct net *net = sock_net(skb->sk); | 1258 | struct net *net = sock_net(skb->sk); |
| 1259 | struct netdev_queue *dev_queue; | ||
| 1251 | int t; | 1260 | int t; |
| 1252 | int s_t; | 1261 | int s_t; |
| 1253 | struct net_device *dev; | 1262 | struct net_device *dev; |
| @@ -1266,7 +1275,8 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1266 | s_t = cb->args[0]; | 1275 | s_t = cb->args[0]; |
| 1267 | t = 0; | 1276 | t = 0; |
| 1268 | 1277 | ||
| 1269 | list_for_each_entry(q, &dev->qdisc_list, list) { | 1278 | dev_queue = &dev->tx_queue; |
| 1279 | list_for_each_entry(q, &dev_queue->qdisc_list, list) { | ||
| 1270 | if (t < s_t || !q->ops->cl_ops || | 1280 | if (t < s_t || !q->ops->cl_ops || |
| 1271 | (tcm->tcm_parent && | 1281 | (tcm->tcm_parent && |
| 1272 | TC_H_MAJ(tcm->tcm_parent) != q->handle)) { | 1282 | TC_H_MAJ(tcm->tcm_parent) != q->handle)) { |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 804d44b00348..3223e5ba76aa 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
| @@ -122,7 +122,7 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb, | |||
| 122 | * | 122 | * |
| 123 | * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this | 123 | * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this |
| 124 | * device at a time. queue->lock serializes queue accesses for | 124 | * device at a time. queue->lock serializes queue accesses for |
| 125 | * this device AND dev->qdisc pointer itself. | 125 | * this device AND txq->qdisc pointer itself. |
| 126 | * | 126 | * |
| 127 | * netif_tx_lock serializes accesses to device driver. | 127 | * netif_tx_lock serializes accesses to device driver. |
| 128 | * | 128 | * |
| @@ -138,7 +138,8 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb, | |||
| 138 | */ | 138 | */ |
| 139 | static inline int qdisc_restart(struct net_device *dev) | 139 | static inline int qdisc_restart(struct net_device *dev) |
| 140 | { | 140 | { |
| 141 | struct Qdisc *q = dev->qdisc; | 141 | struct netdev_queue *txq = &dev->tx_queue; |
| 142 | struct Qdisc *q = txq->qdisc; | ||
| 142 | struct sk_buff *skb; | 143 | struct sk_buff *skb; |
| 143 | int ret = NETDEV_TX_BUSY; | 144 | int ret = NETDEV_TX_BUSY; |
| 144 | 145 | ||
| @@ -148,15 +149,15 @@ static inline int qdisc_restart(struct net_device *dev) | |||
| 148 | 149 | ||
| 149 | 150 | ||
| 150 | /* And release queue */ | 151 | /* And release queue */ |
| 151 | spin_unlock(&q->dev_queue->lock); | 152 | spin_unlock(&txq->lock); |
| 152 | 153 | ||
| 153 | HARD_TX_LOCK(dev, smp_processor_id()); | 154 | HARD_TX_LOCK(dev, smp_processor_id()); |
| 154 | if (!netif_subqueue_stopped(dev, skb)) | 155 | if (!netif_subqueue_stopped(dev, skb)) |
| 155 | ret = dev_hard_start_xmit(skb, dev); | 156 | ret = dev_hard_start_xmit(skb, dev); |
| 156 | HARD_TX_UNLOCK(dev); | 157 | HARD_TX_UNLOCK(dev); |
| 157 | 158 | ||
| 158 | spin_lock(&q->dev_queue->lock); | 159 | spin_lock(&txq->lock); |
| 159 | q = dev->qdisc; | 160 | q = txq->qdisc; |
| 160 | 161 | ||
| 161 | switch (ret) { | 162 | switch (ret) { |
| 162 | case NETDEV_TX_OK: | 163 | case NETDEV_TX_OK: |
| @@ -207,9 +208,10 @@ void __qdisc_run(struct net_device *dev) | |||
| 207 | static void dev_watchdog(unsigned long arg) | 208 | static void dev_watchdog(unsigned long arg) |
| 208 | { | 209 | { |
| 209 | struct net_device *dev = (struct net_device *)arg; | 210 | struct net_device *dev = (struct net_device *)arg; |
| 211 | struct netdev_queue *txq = &dev->tx_queue; | ||
| 210 | 212 | ||
| 211 | netif_tx_lock(dev); | 213 | netif_tx_lock(dev); |
| 212 | if (dev->qdisc != &noop_qdisc) { | 214 | if (txq->qdisc != &noop_qdisc) { |
| 213 | if (netif_device_present(dev) && | 215 | if (netif_device_present(dev) && |
| 214 | netif_running(dev) && | 216 | netif_running(dev) && |
| 215 | netif_carrier_ok(dev)) { | 217 | netif_carrier_ok(dev)) { |
| @@ -539,53 +541,63 @@ EXPORT_SYMBOL(qdisc_destroy); | |||
| 539 | 541 | ||
| 540 | void dev_activate(struct net_device *dev) | 542 | void dev_activate(struct net_device *dev) |
| 541 | { | 543 | { |
| 544 | struct netdev_queue *txq = &dev->tx_queue; | ||
| 545 | |||
| 542 | /* No queueing discipline is attached to device; | 546 | /* No queueing discipline is attached to device; |
| 543 | create default one i.e. pfifo_fast for devices, | 547 | create default one i.e. pfifo_fast for devices, |
| 544 | which need queueing and noqueue_qdisc for | 548 | which need queueing and noqueue_qdisc for |
| 545 | virtual interfaces | 549 | virtual interfaces |
| 546 | */ | 550 | */ |
| 547 | 551 | ||
| 548 | if (dev->qdisc_sleeping == &noop_qdisc) { | 552 | if (txq->qdisc_sleeping == &noop_qdisc) { |
| 549 | struct Qdisc *qdisc; | 553 | struct Qdisc *qdisc; |
| 550 | if (dev->tx_queue_len) { | 554 | if (dev->tx_queue_len) { |
| 551 | qdisc = qdisc_create_dflt(dev, &dev->tx_queue, | 555 | qdisc = qdisc_create_dflt(dev, txq, |
| 552 | &pfifo_fast_ops, | 556 | &pfifo_fast_ops, |
| 553 | TC_H_ROOT); | 557 | TC_H_ROOT); |
| 554 | if (qdisc == NULL) { | 558 | if (qdisc == NULL) { |
| 555 | printk(KERN_INFO "%s: activation failed\n", dev->name); | 559 | printk(KERN_INFO "%s: activation failed\n", dev->name); |
| 556 | return; | 560 | return; |
| 557 | } | 561 | } |
| 558 | list_add_tail(&qdisc->list, &dev->qdisc_list); | 562 | list_add_tail(&qdisc->list, &txq->qdisc_list); |
| 559 | } else { | 563 | } else { |
| 560 | qdisc = &noqueue_qdisc; | 564 | qdisc = &noqueue_qdisc; |
| 561 | } | 565 | } |
| 562 | dev->qdisc_sleeping = qdisc; | 566 | txq->qdisc_sleeping = qdisc; |
| 563 | } | 567 | } |
| 564 | 568 | ||
| 565 | if (!netif_carrier_ok(dev)) | 569 | if (!netif_carrier_ok(dev)) |
| 566 | /* Delay activation until next carrier-on event */ | 570 | /* Delay activation until next carrier-on event */ |
| 567 | return; | 571 | return; |
| 568 | 572 | ||
| 569 | spin_lock_bh(&dev->tx_queue.lock); | 573 | spin_lock_bh(&txq->lock); |
| 570 | rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); | 574 | rcu_assign_pointer(txq->qdisc, txq->qdisc_sleeping); |
| 571 | if (dev->qdisc != &noqueue_qdisc) { | 575 | if (txq->qdisc != &noqueue_qdisc) { |
| 572 | dev->trans_start = jiffies; | 576 | dev->trans_start = jiffies; |
| 573 | dev_watchdog_up(dev); | 577 | dev_watchdog_up(dev); |
| 574 | } | 578 | } |
| 575 | spin_unlock_bh(&dev->tx_queue.lock); | 579 | spin_unlock_bh(&txq->lock); |
| 580 | } | ||
| 581 | |||
| 582 | static void dev_deactivate_queue(struct net_device *dev, | ||
| 583 | struct netdev_queue *dev_queue, | ||
| 584 | struct Qdisc *qdisc_default) | ||
| 585 | { | ||
| 586 | struct Qdisc *qdisc = dev_queue->qdisc; | ||
| 587 | |||
| 588 | if (qdisc) { | ||
| 589 | dev_queue->qdisc = qdisc_default; | ||
| 590 | qdisc_reset(qdisc); | ||
| 591 | } | ||
| 576 | } | 592 | } |
| 577 | 593 | ||
| 578 | void dev_deactivate(struct net_device *dev) | 594 | void dev_deactivate(struct net_device *dev) |
| 579 | { | 595 | { |
| 580 | struct Qdisc *qdisc; | ||
| 581 | struct sk_buff *skb; | 596 | struct sk_buff *skb; |
| 582 | int running; | 597 | int running; |
| 583 | 598 | ||
| 584 | spin_lock_bh(&dev->tx_queue.lock); | 599 | spin_lock_bh(&dev->tx_queue.lock); |
| 585 | qdisc = dev->qdisc; | 600 | dev_deactivate_queue(dev, &dev->tx_queue, &noop_qdisc); |
| 586 | dev->qdisc = &noop_qdisc; | ||
| 587 | |||
| 588 | qdisc_reset(qdisc); | ||
| 589 | 601 | ||
| 590 | skb = dev->gso_skb; | 602 | skb = dev->gso_skb; |
| 591 | dev->gso_skb = NULL; | 603 | dev->gso_skb = NULL; |
| @@ -622,32 +634,44 @@ void dev_deactivate(struct net_device *dev) | |||
| 622 | } while (WARN_ON_ONCE(running)); | 634 | } while (WARN_ON_ONCE(running)); |
| 623 | } | 635 | } |
| 624 | 636 | ||
| 637 | static void dev_init_scheduler_queue(struct net_device *dev, | ||
| 638 | struct netdev_queue *dev_queue, | ||
| 639 | struct Qdisc *qdisc) | ||
| 640 | { | ||
| 641 | dev_queue->qdisc = qdisc; | ||
| 642 | dev_queue->qdisc_sleeping = qdisc; | ||
| 643 | INIT_LIST_HEAD(&dev_queue->qdisc_list); | ||
| 644 | } | ||
| 645 | |||
| 625 | void dev_init_scheduler(struct net_device *dev) | 646 | void dev_init_scheduler(struct net_device *dev) |
| 626 | { | 647 | { |
| 627 | qdisc_lock_tree(dev); | 648 | qdisc_lock_tree(dev); |
| 628 | dev->qdisc = &noop_qdisc; | 649 | dev_init_scheduler_queue(dev, &dev->tx_queue, &noop_qdisc); |
| 629 | dev->qdisc_sleeping = &noop_qdisc; | 650 | dev_init_scheduler_queue(dev, &dev->rx_queue, NULL); |
| 630 | INIT_LIST_HEAD(&dev->qdisc_list); | ||
| 631 | qdisc_unlock_tree(dev); | 651 | qdisc_unlock_tree(dev); |
| 632 | 652 | ||
| 633 | setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); | 653 | setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); |
| 634 | } | 654 | } |
| 635 | 655 | ||
| 636 | void dev_shutdown(struct net_device *dev) | 656 | static void dev_shutdown_scheduler_queue(struct net_device *dev, |
| 657 | struct netdev_queue *dev_queue, | ||
| 658 | struct Qdisc *qdisc_default) | ||
| 637 | { | 659 | { |
| 638 | struct Qdisc *qdisc; | 660 | struct Qdisc *qdisc = dev_queue->qdisc_sleeping; |
| 661 | |||
| 662 | if (qdisc) { | ||
| 663 | dev_queue->qdisc = qdisc_default; | ||
| 664 | dev_queue->qdisc_sleeping = qdisc_default; | ||
| 639 | 665 | ||
| 640 | qdisc_lock_tree(dev); | ||
| 641 | qdisc = dev->qdisc_sleeping; | ||
| 642 | dev->qdisc = &noop_qdisc; | ||
| 643 | dev->qdisc_sleeping = &noop_qdisc; | ||
| 644 | qdisc_destroy(qdisc); | ||
| 645 | #if defined(CONFIG_NET_SCH_INGRESS) || defined(CONFIG_NET_SCH_INGRESS_MODULE) | ||
| 646 | if ((qdisc = dev->qdisc_ingress) != NULL) { | ||
| 647 | dev->qdisc_ingress = NULL; | ||
| 648 | qdisc_destroy(qdisc); | 666 | qdisc_destroy(qdisc); |
| 649 | } | 667 | } |
| 650 | #endif | 668 | } |
| 669 | |||
| 670 | void dev_shutdown(struct net_device *dev) | ||
| 671 | { | ||
| 672 | qdisc_lock_tree(dev); | ||
| 673 | dev_shutdown_scheduler_queue(dev, &dev->tx_queue, &noop_qdisc); | ||
| 674 | dev_shutdown_scheduler_queue(dev, &dev->rx_queue, NULL); | ||
| 651 | BUG_TRAP(!timer_pending(&dev->watchdog_timer)); | 675 | BUG_TRAP(!timer_pending(&dev->watchdog_timer)); |
| 652 | qdisc_unlock_tree(dev); | 676 | qdisc_unlock_tree(dev); |
| 653 | } | 677 | } |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 71b73c528f9b..4093f1eaaf60 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -180,7 +180,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 180 | * skb will be queued. | 180 | * skb will be queued. |
| 181 | */ | 181 | */ |
| 182 | if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { | 182 | if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { |
| 183 | struct Qdisc *rootq = qdisc_dev(sch)->qdisc; | 183 | struct Qdisc *rootq = qdisc_dev(sch)->tx_queue.qdisc; |
| 184 | u32 dupsave = q->duplicate; /* prevent duplicating a dup... */ | 184 | u32 dupsave = q->duplicate; /* prevent duplicating a dup... */ |
| 185 | q->duplicate = 0; | 185 | q->duplicate = 0; |
| 186 | 186 | ||
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 4f3054e8e1ab..8ac05981be20 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
| @@ -107,17 +107,19 @@ static struct sk_buff * | |||
| 107 | teql_dequeue(struct Qdisc* sch) | 107 | teql_dequeue(struct Qdisc* sch) |
| 108 | { | 108 | { |
| 109 | struct teql_sched_data *dat = qdisc_priv(sch); | 109 | struct teql_sched_data *dat = qdisc_priv(sch); |
| 110 | struct netdev_queue *dat_queue; | ||
| 110 | struct sk_buff *skb; | 111 | struct sk_buff *skb; |
| 111 | 112 | ||
| 112 | skb = __skb_dequeue(&dat->q); | 113 | skb = __skb_dequeue(&dat->q); |
| 114 | dat_queue = &dat->m->dev->tx_queue; | ||
| 113 | if (skb == NULL) { | 115 | if (skb == NULL) { |
| 114 | struct net_device *m = qdisc_dev(dat->m->dev->qdisc); | 116 | struct net_device *m = qdisc_dev(dat_queue->qdisc); |
| 115 | if (m) { | 117 | if (m) { |
| 116 | dat->m->slaves = sch; | 118 | dat->m->slaves = sch; |
| 117 | netif_wake_queue(m); | 119 | netif_wake_queue(m); |
| 118 | } | 120 | } |
| 119 | } | 121 | } |
| 120 | sch->q.qlen = dat->q.qlen + dat->m->dev->qdisc->q.qlen; | 122 | sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen; |
| 121 | return skb; | 123 | return skb; |
| 122 | } | 124 | } |
| 123 | 125 | ||
| @@ -155,7 +157,7 @@ teql_destroy(struct Qdisc* sch) | |||
| 155 | if (q == master->slaves) { | 157 | if (q == master->slaves) { |
| 156 | master->slaves = NULL; | 158 | master->slaves = NULL; |
| 157 | spin_lock_bh(&master->dev->tx_queue.lock); | 159 | spin_lock_bh(&master->dev->tx_queue.lock); |
| 158 | qdisc_reset(master->dev->qdisc); | 160 | qdisc_reset(master->dev->tx_queue.qdisc); |
| 159 | spin_unlock_bh(&master->dev->tx_queue.lock); | 161 | spin_unlock_bh(&master->dev->tx_queue.lock); |
| 160 | } | 162 | } |
| 161 | } | 163 | } |
| @@ -216,7 +218,7 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt) | |||
| 216 | static int | 218 | static int |
| 217 | __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) | 219 | __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) |
| 218 | { | 220 | { |
| 219 | struct teql_sched_data *q = qdisc_priv(dev->qdisc); | 221 | struct teql_sched_data *q = qdisc_priv(dev->tx_queue.qdisc); |
| 220 | struct neighbour *mn = skb->dst->neighbour; | 222 | struct neighbour *mn = skb->dst->neighbour; |
| 221 | struct neighbour *n = q->ncache; | 223 | struct neighbour *n = q->ncache; |
| 222 | 224 | ||
| @@ -252,7 +254,7 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * | |||
| 252 | static inline int teql_resolve(struct sk_buff *skb, | 254 | static inline int teql_resolve(struct sk_buff *skb, |
| 253 | struct sk_buff *skb_res, struct net_device *dev) | 255 | struct sk_buff *skb_res, struct net_device *dev) |
| 254 | { | 256 | { |
| 255 | if (dev->qdisc == &noop_qdisc) | 257 | if (dev->tx_queue.qdisc == &noop_qdisc) |
| 256 | return -ENODEV; | 258 | return -ENODEV; |
| 257 | 259 | ||
| 258 | if (dev->header_ops == NULL || | 260 | if (dev->header_ops == NULL || |
| @@ -284,7 +286,7 @@ restart: | |||
| 284 | do { | 286 | do { |
| 285 | struct net_device *slave = qdisc_dev(q); | 287 | struct net_device *slave = qdisc_dev(q); |
| 286 | 288 | ||
| 287 | if (slave->qdisc_sleeping != q) | 289 | if (slave->tx_queue.qdisc_sleeping != q) |
| 288 | continue; | 290 | continue; |
| 289 | if (netif_queue_stopped(slave) || | 291 | if (netif_queue_stopped(slave) || |
| 290 | __netif_subqueue_stopped(slave, subq) || | 292 | __netif_subqueue_stopped(slave, subq) || |
