diff options
author | Marin Mitov <mitov@issp.bas.bg> | 2008-03-23 10:20:09 +0200 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-03-25 23:42:06 -0400 |
commit | 6ef2977d414cc196baba0fb53509c5f8cd9154b4 (patch) | |
tree | 5cff016cfe15fcf79c169d6fa105093ee8972539 | |
parent | 9f5e60dd5ffca938da4cabc197af8b9405b5512e (diff) | |
download | op-kernel-dev-6ef2977d414cc196baba0fb53509c5f8cd9154b4.zip op-kernel-dev-6ef2977d414cc196baba0fb53509c5f8cd9154b4.tar.gz |
skge napi->poll() locking bug
According to: Documentation/networking/netdevices.txt:
<cite>
napi->poll:
..........
Context: softirq
will be called with interrupts disabled by netconsole.
</cite>
napi->poll() could be called either with interrupts enabled
(in softirq context) or disabled (by netconsole), so the irq flag
should be preserved.
Inspired by Ingo's resent forcedeth patch :-)
Signed-off-by: Marin Mitov <mitov@issp.bas.bg>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/skge.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 186eb8e..ae52cba 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3199,12 +3199,14 @@ static int skge_poll(struct napi_struct *napi, int to_do) skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START); if (work_done < to_do) { - spin_lock_irq(&hw->hw_lock); + unsigned long flags; + + spin_lock_irqsave(&hw->hw_lock, flags); __netif_rx_complete(dev, napi); hw->intr_mask |= napimask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); skge_read32(hw, B0_IMSK); - spin_unlock_irq(&hw->hw_lock); + spin_unlock_irqrestore(&hw->hw_lock, flags); } return work_done; |