summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRasesh Mody <rmody@brocade.com>2011-08-30 17:27:45 +0200
committerDavid S. Miller <davem@davemloft.net>2011-09-15 21:36:33 +0200
commitdfee325ad23ff4714981c9d2a4df6386493a4475 (patch)
tree744b2abe6cde55f5049f8eafe75c3bfa93dd2f82
parentbna: Async Mode Tx Rx Init Fix (diff)
downloadlinux-dfee325ad23ff4714981c9d2a4df6386493a4475.tar.xz
linux-dfee325ad23ff4714981c9d2a4df6386493a4475.zip
bna: MBOX IRQ Flag Check after Locking
Change details: - Check the BNAD_RF_MBOX_IRQ_DISABLED flag after acquiring the bna_lock, since checking the flag and executing bna_mbox_handler needs to be atomic. If not, it opens up window where flag is reset when it was checked, but got set while spinning on the lock by the other thread which is actually holding the lock Signed-off-by: Gurunatha Karaje <gkaraje@brocade.com> Signed-off-by: Rasesh Mody <rmody@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index c81550b076ad..11990cf0a265 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -586,10 +586,11 @@ bnad_msix_mbox_handler(int irq, void *data)
unsigned long flags;
struct bnad *bnad = (struct bnad *)data;
- if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)))
- return IRQ_HANDLED;
-
spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ return IRQ_HANDLED;
+ }
bna_intr_status_get(&bnad->bna, intr_status);
@@ -612,15 +613,18 @@ bnad_isr(int irq, void *data)
struct bnad_rx_ctrl *rx_ctrl;
struct bna_tcb *tcb = NULL;
- if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)))
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
return IRQ_NONE;
+ }
bna_intr_status_get(&bnad->bna, intr_status);
- if (unlikely(!intr_status))
+ if (unlikely(!intr_status)) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
return IRQ_NONE;
-
- spin_lock_irqsave(&bnad->bna_lock, flags);
+ }
if (BNA_IS_MBOX_ERR_INTR(&bnad->bna, intr_status))
bna_mbox_handler(&bnad->bna, intr_status);