patch-2.3.15 linux/include/net/pkt_sched.h

Next file: linux/include/net/protocol.h
Previous file: linux/include/net/neighbour.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.14/linux/include/net/pkt_sched.h linux/include/net/pkt_sched.h
@@ -137,16 +137,23 @@
 extern __inline__ unsigned long
 cls_set_class(struct tcf_proto *tp, unsigned long *clp, unsigned long cl)
 {
+	unsigned long old_cl;
+
 	tcf_tree_lock(tp);
-	cl = xchg(clp, cl);
+	old_cl = *clp;
+	*clp = cl;
 	tcf_tree_unlock(tp);
-	return cl;
+	return old_cl;
 }
 
 extern __inline__ unsigned long
 __cls_set_class(unsigned long *clp, unsigned long cl)
 {
-	return xchg(clp, cl);
+	unsigned long old_cl;
+
+	old_cl = *clp;
+	*clp = cl;
+	return old_cl;
 }
 
 
@@ -453,7 +460,7 @@
 extern __inline__ void qdisc_run(struct Qdisc *q)
 {
 	spin_lock(&qdisc_runqueue_lock);
-	if (!qdisc_on_runqueue(q)) {
+	if (!qdisc_on_runqueue(q) && q->dev) {
 		q->h.forw = &qdisc_head;
 		q->h.back = qdisc_head.back;
 		qdisc_head.back->forw = &q->h;
@@ -462,18 +469,27 @@
 	spin_unlock(&qdisc_runqueue_lock);
 }
 
+extern __inline__ int __qdisc_wakeup(struct net_device *dev)
+{
+	int res;
+
+	while ((res = qdisc_restart(dev))<0 && !dev->tbusy)
+		/* NOTHING */;
+
+	return res;
+}
+
+
 /* If the device is not throttled, restart it and add to run list.
- * BH must be disabled on this CPU.
+ * BH must be disabled on this CPU. Usually, it is called by timers.
  */
 
 extern __inline__ void qdisc_wakeup(struct net_device *dev)
 {
-	if (!dev->tbusy) {
-		spin_lock(&dev->queue_lock);
-		if (qdisc_restart(dev))
-			qdisc_run(dev->qdisc);
-		spin_unlock(&dev->queue_lock);
-	}
+	spin_lock(&dev->queue_lock);
+	if (dev->tbusy || __qdisc_wakeup(dev))
+		qdisc_run(dev->qdisc);
+	spin_unlock(&dev->queue_lock);
 }
 
 /* Calculate maximal size of packet seen by hard_start_xmit

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