diff options
Diffstat (limited to 'kernel/panic.c')
| -rw-r--r-- | kernel/panic.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/kernel/panic.c b/kernel/panic.c index 50715f14cf04..08072bfae422 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -371,8 +371,9 @@ int __weak panic_smp_redirect_cpu(int target_cpu, void *msg) * for the crash kernel to function correctly. This function redirects * panic handling to the CPU specified via the panic_force_cpu= boot parameter. * - * Returns false if panic should proceed on current CPU. - * Returns true if panic was redirected. + * Returns true when this CPU must stop: the panic was redirected or is + * already running on another CPU. + * Returns false when panic() should proceed on this CPU. */ __printf(1, 0) static bool panic_try_force_cpu(const char *fmt, va_list args) @@ -396,16 +397,20 @@ static bool panic_try_force_cpu(const char *fmt, va_list args) return false; } - /* Another panic already in progress */ + /* + * Don't redirect when a panic is already in progress. Stop this + * CPU when it's another one, proceed when it's this one. + */ if (panic_in_progress()) - return false; + return panic_on_other_cpu(); /* - * Only one CPU can do the redirect. Use atomic cmpxchg to ensure - * we don't race with another CPU also trying to redirect. + * Only one CPU can do the redirection. Others should go offline. + * Continue with panic() when we already tried the redirection + * from this CPU before, for example via nmi_panic(). */ if (!atomic_try_cmpxchg(&panic_redirect_cpu, &old_cpu, this_cpu)) - return false; + return old_cpu != this_cpu; /* * Use dynamically allocated buffer if available, otherwise |
