aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <jejb@parisc-linux.org>2005-11-17 16:24:52 -0500
committerKyle McMartin <kyle@parisc-linux.org>2005-11-17 16:24:52 -0500
commit9a8b4584065dd241d6c2bf818e349986bd900b8e (patch)
treee801bca17874bdb64aa686f32d20dce76c07473e
parent6b1de9161e973bac8c4675db608fe4f38d2689bd (diff)
[PARISC] Make sure timer and IPI execute with interrupts disabled
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>
-rw-r--r--arch/parisc/kernel/irq.c2
-rw-r--r--arch/parisc/kernel/smp.c4
2 files changed, 6 insertions, 0 deletions
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 006385dbee66..f7ae2bcd49a5 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -291,12 +291,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
291static struct irqaction timer_action = { 291static struct irqaction timer_action = {
292 .handler = timer_interrupt, 292 .handler = timer_interrupt,
293 .name = "timer", 293 .name = "timer",
294 .flags = SA_INTERRUPT,
294}; 295};
295 296
296#ifdef CONFIG_SMP 297#ifdef CONFIG_SMP
297static struct irqaction ipi_action = { 298static struct irqaction ipi_action = {
298 .handler = ipi_interrupt, 299 .handler = ipi_interrupt,
299 .name = "IPI", 300 .name = "IPI",
301 .flags = SA_INTERRUPT,
300}; 302};
301#endif 303#endif
302 304
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index a9ecf6465784..268b0f2a328e 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -338,6 +338,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
338 338
339 /* Can deadlock when called with interrupts disabled */ 339 /* Can deadlock when called with interrupts disabled */
340 WARN_ON(irqs_disabled()); 340 WARN_ON(irqs_disabled());
341
342 /* can also deadlock if IPIs are disabled */
343 WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
344
341 345
342 data.func = func; 346 data.func = func;
343 data.info = info; 347 data.info = info;