patch-2.3.15 linux/net/sched/sch_generic.c

Next file: linux/net/sched/sch_prio.c
Previous file: linux/net/sched/sch_fifo.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.14/linux/net/sched/sch_generic.c linux/net/sched/sch_generic.c
@@ -30,8 +30,6 @@
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 
-#define BUG_TRAP(x) if (!(x)) { printk("Assertion (" #x ") failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); }
-
 /* Main transmission queue. */
 
 struct Qdisc_head qdisc_head = { &qdisc_head, &qdisc_head };
@@ -90,16 +88,18 @@
 	struct Qdisc *q = dev->qdisc;
 	struct sk_buff *skb;
 
+	/* Dequeue packet */
 	if ((skb = q->dequeue(q)) != NULL) {
-		/* Dequeue packet and release queue */
-		spin_unlock(&dev->queue_lock);
-
-		if (netdev_nit)
-			dev_queue_xmit_nit(skb, dev);
-
 		if (spin_trylock(&dev->xmit_lock)) {
 			/* Remember that the driver is grabbed by us. */
 			dev->xmit_lock_owner = smp_processor_id();
+
+			/* And release queue */
+			spin_unlock(&dev->queue_lock);
+
+			if (netdev_nit)
+				dev_queue_xmit_nit(skb, dev);
+
 			if (dev->hard_start_xmit(skb, dev) == 0) {
 				dev->xmit_lock_owner = -1;
 				spin_unlock(&dev->xmit_lock);
@@ -111,6 +111,8 @@
 			/* Release the driver */
 			dev->xmit_lock_owner = -1;
 			spin_unlock(&dev->xmit_lock);
+			spin_lock(&dev->queue_lock);
+			q = dev->qdisc;
 		} else {
 			/* So, someone grabbed the driver. */
 
@@ -123,7 +125,6 @@
 				kfree_skb(skb);
 				if (net_ratelimit())
 					printk(KERN_DEBUG "Dead loop on virtual %s, fix it urgently!\n", dev->name);
-				spin_lock(&dev->queue_lock);
 				return -1;
 			}
 
@@ -143,12 +144,10 @@
 		   3. device is buggy (ppp)
 		 */
 
-		spin_lock(&dev->queue_lock);
-		q = dev->qdisc;
 		q->ops->requeue(skb, q);
 		return -1;
 	}
-	return dev->qdisc->q.qlen;
+	return q->q.qlen;
 }
 
 static __inline__ void
@@ -212,19 +211,19 @@
 		qdisc_stop_run(q);
 
 		dev = q->dev;
-		spin_unlock(&qdisc_runqueue_lock);
 
 		res = -1;
 		if (spin_trylock(&dev->queue_lock)) {
+			spin_unlock(&qdisc_runqueue_lock);
 			while (!dev->tbusy && (res = qdisc_restart(dev)) < 0)
 				/* NOTHING */;
+			spin_lock(&qdisc_runqueue_lock);
 			spin_unlock(&dev->queue_lock);
 		}
 
-		spin_lock(&qdisc_runqueue_lock);
 		/* If qdisc is not empty add it to the tail of list */
 		if (res)
-			qdisc_continue_run(q);
+			qdisc_continue_run(dev->qdisc);
 	}
 out:
 	spin_unlock(&qdisc_runqueue_lock);
@@ -259,17 +258,16 @@
 		qdisc_stop_run(q);
 
 		dev = q->dev;
-		spin_unlock(&qdisc_runqueue_lock);
 
 		if (spin_trylock(&dev->queue_lock)) {
+			spin_unlock(&qdisc_runqueue_lock);
 			q = dev->qdisc;
 			if (dev->tbusy && jiffies - q->tx_last > q->tx_timeo)
 				qdisc_restart(dev);
+			spin_lock(&qdisc_runqueue_lock);
 			spin_unlock(&dev->queue_lock);
 		}
 
-		spin_lock(&qdisc_runqueue_lock);
-
 		qdisc_continue_run(dev->qdisc);
 	}
 
@@ -289,7 +287,7 @@
 noop_enqueue(struct sk_buff *skb, struct Qdisc * qdisc)
 {
 	kfree_skb(skb);
-	return 0;
+	return NET_XMIT_CN;
 }
 
 static struct sk_buff *
@@ -304,7 +302,7 @@
 	if (net_ratelimit())
 		printk(KERN_DEBUG "%s deferred output. It is buggy.\n", skb->dev->name);
 	kfree_skb(skb);
-	return 0;
+	return NET_XMIT_CN;
 }
 
 struct Qdisc_ops noop_qdisc_ops =
@@ -370,11 +368,11 @@
 	if (list->qlen <= skb->dev->tx_queue_len) {
 		__skb_queue_tail(list, skb);
 		qdisc->q.qlen++;
-		return 1;
+		return 0;
 	}
 	qdisc->stats.drops++;
 	kfree_skb(skb);
-	return 0;
+	return NET_XMIT_DROP;
 }
 
 static struct sk_buff *
@@ -404,7 +402,7 @@
 
 	__skb_queue_head(list, skb);
 	qdisc->q.qlen++;
-	return 1;
+	return 0;
 }
 
 static void
@@ -557,16 +555,18 @@
 	struct Qdisc *qdisc;
 
 	spin_lock_bh(&dev->queue_lock);
+	spin_lock(&qdisc_runqueue_lock);
 	qdisc = dev->qdisc;
 	dev->qdisc = &noop_qdisc;
 
 	qdisc_reset(qdisc);
 
-	spin_lock(&qdisc_runqueue_lock);
 	if (qdisc_on_runqueue(qdisc))
 		qdisc_stop_run(qdisc);
 	spin_unlock(&qdisc_runqueue_lock);
 	spin_unlock_bh(&dev->queue_lock);
+
+	spin_unlock_wait(&dev->xmit_lock);
 }
 
 void dev_init_scheduler(struct net_device *dev)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)