Merge branch 'smack-for-3.20-rebased' of git://git.gitorious.org/smack-next/kernel...
[linux-2.6-block.git] / net / sched / sch_teql.c
index bd33793b527e176b07f7bacb77143ed38e32d31c..e02687185a594116b125fdbfc7db49bf8a929797 100644 (file)
@@ -96,11 +96,14 @@ teql_dequeue(struct Qdisc *sch)
        struct teql_sched_data *dat = qdisc_priv(sch);
        struct netdev_queue *dat_queue;
        struct sk_buff *skb;
+       struct Qdisc *q;
 
        skb = __skb_dequeue(&dat->q);
        dat_queue = netdev_get_tx_queue(dat->m->dev, 0);
+       q = rcu_dereference_bh(dat_queue->qdisc);
+
        if (skb == NULL) {
-               struct net_device *m = qdisc_dev(dat_queue->qdisc);
+               struct net_device *m = qdisc_dev(q);
                if (m) {
                        dat->m->slaves = sch;
                        netif_wake_queue(m);
@@ -108,7 +111,7 @@ teql_dequeue(struct Qdisc *sch)
        } else {
                qdisc_bstats_update(sch, skb);
        }
-       sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen;
+       sch->q.qlen = dat->q.qlen + q->q.qlen;
        return skb;
 }
 
@@ -119,13 +122,6 @@ teql_peek(struct Qdisc *sch)
        return NULL;
 }
 
-static inline void
-teql_neigh_release(struct neighbour *n)
-{
-       if (n)
-               neigh_release(n);
-}
-
 static void
 teql_reset(struct Qdisc *sch)
 {
@@ -157,9 +153,9 @@ teql_destroy(struct Qdisc *sch)
                                                txq = netdev_get_tx_queue(master->dev, 0);
                                                master->slaves = NULL;
 
-                                               root_lock = qdisc_root_sleeping_lock(txq->qdisc);
+                                               root_lock = qdisc_root_sleeping_lock(rtnl_dereference(txq->qdisc));
                                                spin_lock_bh(root_lock);
-                                               qdisc_reset(txq->qdisc);
+                                               qdisc_reset(rtnl_dereference(txq->qdisc));
                                                spin_unlock_bh(root_lock);
                                        }
                                }
@@ -246,8 +242,8 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
                char haddr[MAX_ADDR_LEN];
 
                neigh_ha_snapshot(haddr, n, dev);
-               err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr,
-                                     NULL, skb->len);
+               err = dev_hard_header(skb, dev, ntohs(tc_skb_protocol(skb)),
+                                     haddr, NULL, skb->len);
 
                if (err < 0)
                        err = -EINVAL;
@@ -266,7 +262,7 @@ static inline int teql_resolve(struct sk_buff *skb,
        struct dst_entry *dst = skb_dst(skb);
        int res;
 
-       if (txq->qdisc == &noop_qdisc)
+       if (rcu_access_pointer(txq->qdisc) == &noop_qdisc)
                return -ENODEV;
 
        if (!dev->header_ops || !dst)
@@ -301,7 +297,6 @@ restart:
        do {
                struct net_device *slave = qdisc_dev(q);
                struct netdev_queue *slave_txq = netdev_get_tx_queue(slave, 0);
-               const struct net_device_ops *slave_ops = slave->netdev_ops;
 
                if (slave_txq->qdisc_sleeping != q)
                        continue;
@@ -317,8 +312,8 @@ restart:
                                unsigned int length = qdisc_pkt_len(skb);
 
                                if (!netif_xmit_frozen_or_stopped(slave_txq) &&
-                                   slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) {
-                                       txq_trans_update(slave_txq);
+                                   netdev_start_xmit(skb, slave, slave_txq, false) ==
+                                   NETDEV_TX_OK) {
                                        __netif_tx_unlock(slave_txq);
                                        master->slaves = NEXT_SLAVE(q);
                                        netif_wake_queue(dev);
@@ -468,7 +463,7 @@ static __init void teql_master_setup(struct net_device *dev)
        dev->tx_queue_len       = 100;
        dev->flags              = IFF_NOARP;
        dev->hard_header_len    = LL_MAX_HEADER;
-       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
+       netif_keep_dst(dev);
 }
 
 static LIST_HEAD(master_dev_list);