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>
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index efa418a1b..8cdf0b4 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -563,11 +563,15 @@
 
 void qdisc_destroy(struct Qdisc *qdisc)
 {
+	struct net_device *dev = qdisc_dev(qdisc);
+
 	if (qdisc->flags & TCQ_F_BUILTIN ||
 	    !atomic_dec_and_test(&qdisc->refcnt))
 		return;
 
+	spin_lock_bh(&dev->qdisc_list_lock);
 	list_del(&qdisc->list);
+	spin_unlock_bh(&dev->qdisc_list_lock);
 
 	call_rcu(&qdisc->q_rcu, __qdisc_destroy);
 }
@@ -599,7 +603,9 @@
 			printk(KERN_INFO "%s: activation failed\n", dev->name);
 			return;
 		}
-		list_add_tail(&qdisc->list, &dev_queue->qdisc_list);
+		spin_lock_bh(&dev->qdisc_list_lock);
+		list_add_tail(&qdisc->list, &dev->qdisc_list);
+		spin_unlock_bh(&dev->qdisc_list_lock);
 	} else {
 		qdisc =  &noqueue_qdisc;
 	}
@@ -738,7 +744,6 @@
 
 	dev_queue->qdisc = qdisc;
 	dev_queue->qdisc_sleeping = qdisc;
-	INIT_LIST_HEAD(&dev_queue->qdisc_list);
 }
 
 void dev_init_scheduler(struct net_device *dev)