aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShyam Iyer <shyam.iyer.t@gmail.com>2011-07-14 11:00:32 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-15 11:08:26 -0400
commit8279171a5fe95902be12f4018907f246d51616d4 (patch)
treeeac25a78502e3949fbe97c5e7bd6ed80fc9324ed /drivers
parentecae42d37045ec71831d0e0e493e00b0e0732edd (diff)
Separate handling of irq type flags variable from the irq_flags request_irq variable
Commit 5f77898de17ff983ff0e2988b73a6bdf4b6f9f8b does not completely fix the problem of handling allocations with irqs disabled.. The below patch on top of it fixes the problem completely. Based on review by "Ivan Vecera" <ivecera@redhat.com>.. " Small note, the root of the problem was that non-atomic allocation was requested with IRQs disabled. Your patch description does not contain wwhy were the IRQs disabled. The function bnad_mbox_irq_alloc incorrectly uses 'flags' var for two different things, 1) to save current CPU flags and 2) for request_irq call. First the spin_lock_irqsave disables the IRQs and saves _all_ CPU flags (including one that enables/disables interrupts) to 'flags'. Then the 'flags' is overwritten by 0 or 0x80 (IRQF_SHARED). Finally the spin_unlock_irqrestore should restore saved flags, but these flags are now either 0x00 or 0x80. The interrupt bit value in flags register on x86 arch is 0x100. This means that the interrupt bit is zero (IRQs disabled) after spin_unlock_irqrestore so the request_irq function is called with disabled interrupts. " Signed-off-by: Shyam Iyer <shyam_iyer@dell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bna/bnad.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 795b93b73b12..fa997bfc2e53 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -1109,7 +1109,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
1109 struct bna_intr_info *intr_info) 1109 struct bna_intr_info *intr_info)
1110{ 1110{
1111 int err = 0; 1111 int err = 0;
1112 unsigned long irq_flags = 0, flags; 1112 unsigned long irq_flags, flags;
1113 u32 irq; 1113 u32 irq;
1114 irq_handler_t irq_handler; 1114 irq_handler_t irq_handler;
1115 1115
@@ -1123,6 +1123,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
1123 if (bnad->cfg_flags & BNAD_CF_MSIX) { 1123 if (bnad->cfg_flags & BNAD_CF_MSIX) {
1124 irq_handler = (irq_handler_t)bnad_msix_mbox_handler; 1124 irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
1125 irq = bnad->msix_table[bnad->msix_num - 1].vector; 1125 irq = bnad->msix_table[bnad->msix_num - 1].vector;
1126 irq_flags = 0;
1126 intr_info->intr_type = BNA_INTR_T_MSIX; 1127 intr_info->intr_type = BNA_INTR_T_MSIX;
1127 intr_info->idl[0].vector = bnad->msix_num - 1; 1128 intr_info->idl[0].vector = bnad->msix_num - 1;
1128 } else { 1129 } else {
@@ -1133,7 +1134,6 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
1133 /* intr_info->idl.vector = 0 ? */ 1134 /* intr_info->idl.vector = 0 ? */
1134 } 1135 }
1135 spin_unlock_irqrestore(&bnad->bna_lock, flags); 1136 spin_unlock_irqrestore(&bnad->bna_lock, flags);
1136 flags = irq_flags;
1137 sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); 1137 sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
1138 1138
1139 /* 1139 /*
@@ -1144,7 +1144,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
1144 1144
1145 BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); 1145 BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
1146 1146
1147 err = request_irq(irq, irq_handler, flags, 1147 err = request_irq(irq, irq_handler, irq_flags,
1148 bnad->mbox_irq_name, bnad); 1148 bnad->mbox_irq_name, bnad);
1149 1149
1150 if (err) { 1150 if (err) {