Commit 1a2b7330 authored by Timo Jantunen's avatar Timo Jantunen Committed by Linus Torvalds

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: default avatarTimo Jantunen <jeti@iki.fi>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 62be9001
...@@ -3068,8 +3068,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) ...@@ -3068,8 +3068,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
np->nic_poll_irq = np->irqmask; np->nic_poll_irq = np->irqmask;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 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); spin_unlock(&np->lock);
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
break; break;
} }
...@@ -3186,8 +3186,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) ...@@ -3186,8 +3186,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
np->nic_poll_irq = np->irqmask; np->nic_poll_irq = np->irqmask;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 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); spin_unlock(&np->lock);
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
break; break;
} }
...@@ -3233,8 +3233,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) ...@@ -3233,8 +3233,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
np->nic_poll_irq |= NVREG_IRQ_TX_ALL; np->nic_poll_irq |= NVREG_IRQ_TX_ALL;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 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); spin_unlock_irqrestore(&np->lock, flags);
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
break; break;
} }
...@@ -3348,8 +3348,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) ...@@ -3348,8 +3348,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
np->nic_poll_irq |= NVREG_IRQ_RX_ALL; np->nic_poll_irq |= NVREG_IRQ_RX_ALL;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 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); spin_unlock_irqrestore(&np->lock, flags);
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
break; break;
} }
} }
...@@ -3421,8 +3421,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) ...@@ -3421,8 +3421,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
np->nic_poll_irq |= NVREG_IRQ_OTHER; np->nic_poll_irq |= NVREG_IRQ_OTHER;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 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); spin_unlock_irqrestore(&np->lock, flags);
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment