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
- Lines: 169
- Date:
Mon Aug 23 10:01:02 1999
- Orig file:
v2.3.14/linux/net/sched/sch_generic.c
- Orig date:
Wed Aug 18 11:38:49 1999
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)