From 316af8739bc27a728d1b0584ef761797f05e5906 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Thu, 12 Jan 2012 17:20:18 -0800 Subject: [PATCH] --- yaml --- r: 284421 b: refs/heads/master c: 93e13a360ba331915220f82f6e9543df961ffa1f h: refs/heads/master i: 284419: c03b9e32baa42b3b5c52e294b21e01035ea1305a v: v3 --- [refs] | 2 +- trunk/kernel/panic.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index f51b0f4656fc..cf58e214afa7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bec013c40bc89671d8d457944fdf7d2b8e79d651 +refs/heads/master: 93e13a360ba331915220f82f6e9543df961ffa1f diff --git a/trunk/kernel/panic.c b/trunk/kernel/panic.c index 6fd09ed6fd90..5dce5404eeef 100644 --- a/trunk/kernel/panic.c +++ b/trunk/kernel/panic.c @@ -49,6 +49,15 @@ static long no_blink(int state) long (*panic_blink)(int state); EXPORT_SYMBOL(panic_blink); +/* + * Stop ourself in panic -- architecture code may override this + */ +void __weak panic_smp_self_stop(void) +{ + while (1) + cpu_relax(); +} + /** * panic - halt the system * @fmt: The text string to print @@ -59,6 +68,7 @@ EXPORT_SYMBOL(panic_blink); */ void panic(const char *fmt, ...) { + static DEFINE_SPINLOCK(panic_lock); static char buf[1024]; va_list args; long i, i_next = 0; @@ -68,8 +78,14 @@ void panic(const char *fmt, ...) * It's possible to come here directly from a panic-assertion and * not have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... + * + * Only one CPU is allowed to execute the panic code from here. For + * multiple parallel invocations of panic, all other CPUs either + * stop themself or will wait until they are stopped by the 1st CPU + * with smp_send_stop(). */ - preempt_disable(); + if (!spin_trylock(&panic_lock)) + panic_smp_self_stop(); console_verbose(); bust_spinlocks(1);