SMP deadlock in drivers/net/tulip.c kernel ver 2.3.47 -- here's a patch.

Jon Plews jon@plews.co.uk
Wed Feb 23 20:51:59 2000


There are some spin-lock problems in tulip.c that ships with
2.3.47 source.  IIRC the module wouldn't compile at all for an
SMP system.

The SMP box that exibited the problem boots from the network
and mounts /, /usr and /home from an NFS box.  An RPC portmap
lookup is made *before* the NIC negotiates a pukka link.

I hesitate to post an Oops trace because I only bothered to dig
out a serial cable after fixing the init problem.  I don't hack
kernel that much ;-)

I've posted this to c.o.l.d.s and copied linux-tulip.

Here's the patch:

jplews@sardine:/build/src$ diff -uN linux/drivers/net/tulip.c
linux-2.3.47/drivers/net/tulip.c
--- linux/drivers/net/tulip.c   Thu Feb 24 01:18:17 2000
+++ linux-2.3.47/drivers/net/tulip.c    Tue Feb 22 21:52:40 2000
@@ -945,7 +945,7 @@
        /* now it is safe to change csr6 */
        outl (newcsr6, ioaddr + CSR6);

-       spin_unlock_irqrestore (&tp->lock, flags);
+       spin_unlock_irqrestore (&tp->tx_lock, flags);
 }


@@ -2235,10 +2235,12 @@
                                        printk(KERN_WARNING "%s: The
transmitter stopped."
                                                   "  CSR5 is %x, CSR6 %x,
new CSR6 %x.\n",
                                                   dev->name, csr5,
inl(ioaddr + CSR6), tp->csr6);
+                               spin_unlock(&tp->tx_lock);
                                outl_CSR6(tp, tp->csr6 | 0x0002);
                                outl_CSR6(tp, tp->csr6 | 0x2002);
                        }
-                       spin_unlock(&tp->tx_lock);
+                       else
+                               spin_unlock(&tp->tx_lock);
                }

                /* Log errors. */
@@ -2810,6 +2812,9 @@
        printk(KERN_INFO "%s: %s rev %d at %#3lx,",
                   dev->name, tulip_tbl[chip_idx].chip_name, chip_rev,
ioaddr);

+       /* JPLEWS - Init the spin lock before using it */
+       spin_lock_init (&tp->tx_lock);
+
        /* Stop the chip's Tx and Rx processes. */
        outl_CSR6(tp, inl(ioaddr + CSR6) & ~0x2002);
        /* Clear the missed-packet counter. */
@@ -2932,8 +2937,9 @@
 #ifdef TULIP_NO_MEDIA_SWITCH
        tp->medialock = 1;
 #endif
+#if 0
        tp->tx_lock = SPIN_LOCK_UNLOCKED;
-
+#endif
        /* The lower four bits are the media type. */
        if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
                tp->default_port = options[board_idx] & 15;
jplews@sardine:/build/src$

Jon Plews.

-------------------------------------------------------------------
To unsubscribe send a message body containing "unsubscribe"
to linux-tulip-request@beowulf.org