aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
authorTimo Jantunen <jeti@iki.fi>2007-08-14 21:56:57 +0300
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-18 09:58:51 -0700
commit1a2b73302aacddf2543f9d7a25936e4323fa1486 (patch)
treecf69d0e212c9187696c205e9f9330e09f44c4c87 /drivers/net/forcedeth.c
parenti386: Fix a couple busy loops in mach_wakecpu.h:wait_for_init_deassert() (diff)
downloadlinux-dev-1a2b73302aacddf2543f9d7a25936e4323fa1486.tar.xz
linux-dev-1a2b73302aacddf2543f9d7a25936e4323fa1486.zip
fix random hang in forcedeth driver when using netconsole
If the forcedeth driver receives too much work in an interrupt, it assumes it has a broken hardware with stuck IRQ. It works around the problem by disabling interrupts on the nic but makes a printk while holding device spinlog - which isn't smart thing to do if you have netconsole on the same nic. This patch moves the printk's out of the spinlock protected area. Without this patch the machine hangs hard. With this patch everything still works even when there is significant increase on CPU usage while using the nic. Signed-off-by: Timo Jantunen <jeti@iki.fi> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 69f5f365239a..10f4e3b55168 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3068,8 +3068,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
np->nic_poll_irq = np->irqmask;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
spin_unlock(&np->lock);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
break;
}
@@ -3186,8 +3186,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
np->nic_poll_irq = np->irqmask;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
spin_unlock(&np->lock);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
break;
}
@@ -3233,8 +3233,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
np->nic_poll_irq |= NVREG_IRQ_TX_ALL;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
spin_unlock_irqrestore(&np->lock, flags);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
break;
}
@@ -3348,8 +3348,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
np->nic_poll_irq |= NVREG_IRQ_RX_ALL;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
spin_unlock_irqrestore(&np->lock, flags);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
break;
}
}
@@ -3421,8 +3421,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
np->nic_poll_irq |= NVREG_IRQ_OTHER;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
spin_unlock_irqrestore(&np->lock, flags);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
break;
}