Fixing a datarace. As indicated by the following comment, a lock must be held before calling function update_stats(). This rule is followed in some cases, but not in others. For example, the lock is held when the function is called in function el3_get_stats(), but the lock is NOT held when called in el3_close(). It can cause potential data races. /* ... Caller must hold the lock for this */ static void update_stats(struct net_device *dev) { ... } Signed-off-by: Lin Tan --- --- a/drivers/net/pcmcia/3c589_cs.c 2008-09-25 11:52:42.000000000 -0500 +++ b/drivers/net/pcmcia/3c589_cs.c 2008-09-26 11:07:04.000000000 -0500 @@ -920,6 +920,7 @@ struct el3_private *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; unsigned int ioaddr = dev->base_addr; + unsigned long flags; DEBUG(1, "%s: shutting down ethercard.\n", dev->name); @@ -946,8 +947,11 @@ outw(0x0f00, ioaddr + WN0_IRQ); /* Check if the card still exists */ - if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000) + if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000) { + spin_lock_irqsave(&lp->lock, flags); update_stats(dev); + spin_unlock_irqrestore(&lp->lock, flags); + } } link->open--;