aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2006-12-06 20:38:16 -0800
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 08:39:39 -0800
commita38a44c1a93078fc5fadc4ac2df8dea4697069e2 (patch)
tree03ad860836722b803a02a58d5e988fb9f9b883fc /arch
parent83df8db9e62129975fab6d800fb381faf0dfee74 (diff)
[PATCH] smp_call_function_single() check that local interrupts are enabled
smp_call_function_single() can deadlock if the caller disabled local interrupts (the target CPU could be spinning on call_lock). Check for that. Why on earth do these functions use spin_lock_bh()?? Cc: "Randy.Dunlap" <rdunlap@xenotime.net> Cc: Andi Kleen <ak@suse.de> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/smp.c4
-rw-r--r--arch/x86_64/kernel/smp.c4
2 files changed, 8 insertions, 0 deletions
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 31e5c6573aa..9827cf927ec 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -699,6 +699,10 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
put_cpu();
return -EBUSY;
}
+
+ /* Can deadlock when called with interrupts disabled */
+ WARN_ON(irqs_disabled());
+
spin_lock_bh(&call_lock);
__smp_call_function_single(cpu, func, info, nonatomic, wait);
spin_unlock_bh(&call_lock);
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 9f74c883568..32f4d7e2a06 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -379,6 +379,10 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
put_cpu();
return 0;
}
+
+ /* Can deadlock when called with interrupts disabled */
+ WARN_ON(irqs_disabled());
+
spin_lock_bh(&call_lock);
__smp_call_function_single(cpu, func, info, nonatomic, wait);
spin_unlock_bh(&call_lock);