Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=553af56775b3f23bf64f87090ab81a62bef2837b
Commit:     553af56775b3f23bf64f87090ab81a62bef2837b
Parent:     10764889c6355cbb335cf0578ce12427475d1a65
Author:     Chris Lalancette <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 16 16:41:44 2007 -0500
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Thu Jan 18 11:47:22 2007 -0500

    8139cp: Don't blindly enable interrupts
    
    Similar to this commit:
    
    
http://kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=d15e9c4d9a75702b30e00cdf95c71c88e3f3f51e
    
    It's not safe in cp_start_xmit to blindly call spin_lock_irq and then
    spin_unlock_irq, since it may very well be the case that cp_start_xmit
    was called with interrupts already disabled (I came across this bug in
    the context of netdump in RedHat kernels, but the same issue holds, for
    example, in netconsole). Therefore, replace all instances of
    spin_lock_irq and spin_unlock_irq with spin_lock_irqsave and
    spin_unlock_irqrestore, respectively, in cp_start_xmit(). I tested this
    against a fully-virtualized Xen guest using netdump, which happens to
    use the 8139cp driver to talk to the emulated hardware. I don't have a
    real piece of 8139cp hardware to test on, so someone else will have to
    do that.
    
    Signed-off-by: Chris Lalancette <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/8139cp.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index e2cb19b..6f93a76 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -765,17 +765,18 @@ static int cp_start_xmit (struct sk_buff *skb, struct 
net_device *dev)
        struct cp_private *cp = netdev_priv(dev);
        unsigned entry;
        u32 eor, flags;
+       unsigned long intr_flags;
 #if CP_VLAN_TAG_USED
        u32 vlan_tag = 0;
 #endif
        int mss = 0;
 
-       spin_lock_irq(&cp->lock);
+       spin_lock_irqsave(&cp->lock, intr_flags);
 
        /* This is a hard error, log it. */
        if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
                netif_stop_queue(dev);
-               spin_unlock_irq(&cp->lock);
+               spin_unlock_irqrestore(&cp->lock, intr_flags);
                printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
                       dev->name);
                return 1;
@@ -908,7 +909,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct 
net_device *dev)
        if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
                netif_stop_queue(dev);
 
-       spin_unlock_irq(&cp->lock);
+       spin_unlock_irqrestore(&cp->lock, intr_flags);
 
        cpw8(TxPoll, NormalTxPoll);
        dev->trans_start = jiffies;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to