summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2012-12-18 03:57:00 +0000
committerDavid S. Miller <davem@davemloft.net>2012-12-19 12:44:45 -0800
commit4945106d21926eadaaa1c5465d26d9a0d26a2420 (patch)
treef0ed2f5271c33a59e227b92360ecfe0fffdba727 /drivers/scsi/sd.c
parent341abdbe38ca22f351c9db68a69382fa57350066 (diff)
downloadblackbird-op-linux-4945106d21926eadaaa1c5465d26d9a0d26a2420.tar.gz
blackbird-op-linux-4945106d21926eadaaa1c5465d26d9a0d26a2420.zip
ksz884x: fix receive polling race condition
The ksz884x driver does receive processing in a custom tasklet, and seems to be assuming that since it takes its private interface spinlock with spin_lock_irq(), it won't be running concurrently with its own interrupt handler, as it cannot be preempted by it, but since its interrupt handler doesn't do any locking whatsoever, the receive processing tasklet and interrupt handler can end up running concurrently on different CPUs. As a result of this, the ksz884x receive path ends up locking up fairly easily, when the receive processing tasklet's reenabling of receive interrupts (due to it being done with polling the receive ring) races with the interrupt handler's disabling of receive interrupts (due to a new receive interrupt coming in) resulting in the receive interrupt being masked but the receive processing tasklet not being scheduled. Fix this by making the ksz884x interrupt handler take its private interface spinlock. This requires upgrading the spin_lock() in the transmit cleanup tasklet to a spin_lock_irq(), as otherwise the IRQ handler can preempt transmit cleanup and deadlock the system, but with those two changes, no more receive lockups have been observed. Reported-by: Chris Healy <cphealy@gmail.com> Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org> ---- Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/scsi/sd.c')
0 files changed, 0 insertions, 0 deletions
OpenPOWER on IntegriCloud