I don't expect it to cure the problem but I think you can give it a try ;).
BTW, are you shutting down ethernet at runtime and you have more than one
netdevice?
--- 2.2.13pre14/net/core/dev.c Tue Sep 28 18:32:40 1999
+++ /tmp/dev.c Sun Oct 3 21:00:07 1999
@@ -57,6 +57,8 @@
* A network device unload needs to purge
* the backlog queue.
* Paul Rusty Russel : SIOCSIFNAME
+ * Andrea Arcangeli : dev_clear_backlog() needs the
+ * skb_queue_lock held.
*/
#include <asm/uaccess.h>
@@ -712,6 +714,7 @@
static void dev_clear_backlog(struct device *dev)
{
struct sk_buff *prev, *curr;
+ unsigned long flags;
/*
*
@@ -719,27 +722,22 @@
*
* We are competing here both with netif_rx() and net_bh().
* We don't want either of those to mess with skb ptrs
- * while we work on them, thus cli()/sti().
- *
- * It looks better to use net_bh trick, at least
- * to be sure, that we keep interrupt latency really low. --ANK (980727)
+ * while we work on them, thus we must grab the
+ * skb_queue_lock.
*/
+
+ spin_lock_irqsave(&skb_queue_lock, flags);
if (backlog.qlen) {
- start_bh_atomic();
curr = backlog.next;
while ( curr != (struct sk_buff *)(&backlog) ) {
- unsigned long flags;
curr=curr->next;
if ( curr->prev->dev == dev ) {
prev = curr->prev;
- spin_lock_irqsave(&skb_queue_lock, flags);
__skb_unlink(prev, &backlog);
- spin_unlock_irqrestore(&skb_queue_lock, flags);
kfree_skb(prev);
}
}
- end_bh_atomic();
#ifdef CONFIG_NET_HW_FLOWCONTROL
if (netdev_dropping)
netdev_wakeup();
@@ -747,6 +745,7 @@
netdev_dropping = 0;
#endif
}
+ spin_unlock_irqrestore(&skb_queue_lock, flags);
}
/*
Andrea
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/