]> err.no Git - linux-2.6/commitdiff
[PARISC] Make sure timer and IPI execute with interrupts disabled
authorJames Bottomley <jejb@parisc-linux.org>
Thu, 17 Nov 2005 21:24:52 +0000 (16:24 -0500)
committerKyle McMartin <kyle@parisc-linux.org>
Thu, 17 Nov 2005 21:24:52 +0000 (16:24 -0500)
Fix a longstanding smp bug

The problem is that both the timer and ipi interrupts are being called
with interrupts enabled, which isn't what anyone is expecting.

The IPI issue has just started to show up by causing a BUG_ON in the
slab debugging code.  The timer issue never shows up because there's an
eiem work around in our irq.c

The fix is to label both these as SA_INTERRUPT which causes the generic
irq code not to enable interrupts.

I also suspect the smp_call_function timeouts we're seeing might be
connected with the fact that we disable IPIs when handling any other
type of interrupt.  I've put a WARN_ON in the code for executing
smp_call_function() with IPIs disabled.

Signed-off-by: James Bottomley <jejb@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
arch/parisc/kernel/irq.c
arch/parisc/kernel/smp.c

index 006385dbee6600a147c9ebeb3c827a23e0777118..f7ae2bcd49a5731a0d4b88f2b73f547bb44ecba5 100644 (file)
@@ -291,12 +291,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
 static struct irqaction timer_action = {
        .handler = timer_interrupt,
        .name = "timer",
+       .flags = SA_INTERRUPT,
 };
 
 #ifdef CONFIG_SMP
 static struct irqaction ipi_action = {
        .handler = ipi_interrupt,
        .name = "IPI",
+       .flags = SA_INTERRUPT,
 };
 #endif
 
index a9ecf6465784eb0272518d648e39c2814d31dc02..268b0f2a328ebe1df852a1b6318fb7dd39be182f 100644 (file)
@@ -338,6 +338,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
 
        /* Can deadlock when called with interrupts disabled */
        WARN_ON(irqs_disabled());
+
+       /* can also deadlock if IPIs are disabled */
+       WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
+
        
        data.func = func;
        data.info = info;