Commit 8279171a authored by Shyam Iyer's avatar Shyam Iyer Committed by David S. Miller

Separate handling of irq type flags variable from the irq_flags request_irq variable

Commit 5f77898d 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: default avatarShyam Iyer <shyam_iyer@dell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ecae42d3
...@@ -1109,7 +1109,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, ...@@ -1109,7 +1109,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
struct bna_intr_info *intr_info) struct bna_intr_info *intr_info)
{ {
int err = 0; int err = 0;
unsigned long irq_flags = 0, flags; unsigned long irq_flags, flags;
u32 irq; u32 irq;
irq_handler_t irq_handler; irq_handler_t irq_handler;
...@@ -1123,6 +1123,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, ...@@ -1123,6 +1123,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
if (bnad->cfg_flags & BNAD_CF_MSIX) { if (bnad->cfg_flags & BNAD_CF_MSIX) {
irq_handler = (irq_handler_t)bnad_msix_mbox_handler; irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
irq = bnad->msix_table[bnad->msix_num - 1].vector; irq = bnad->msix_table[bnad->msix_num - 1].vector;
irq_flags = 0;
intr_info->intr_type = BNA_INTR_T_MSIX; intr_info->intr_type = BNA_INTR_T_MSIX;
intr_info->idl[0].vector = bnad->msix_num - 1; intr_info->idl[0].vector = bnad->msix_num - 1;
} else { } else {
...@@ -1133,7 +1134,6 @@ bnad_mbox_irq_alloc(struct bnad *bnad, ...@@ -1133,7 +1134,6 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
/* intr_info->idl.vector = 0 ? */ /* intr_info->idl.vector = 0 ? */
} }
spin_unlock_irqrestore(&bnad->bna_lock, flags); spin_unlock_irqrestore(&bnad->bna_lock, flags);
flags = irq_flags;
sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
/* /*
...@@ -1144,7 +1144,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, ...@@ -1144,7 +1144,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
err = request_irq(irq, irq_handler, flags, err = request_irq(irq, irq_handler, irq_flags,
bnad->mbox_irq_name, bnad); bnad->mbox_irq_name, bnad);
if (err) { if (err) {
......
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