diff options
author | Hoeun Ryu <hoeun.ryu@gmail.com> | 2017-08-16 22:24:27 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2017-08-21 13:01:04 -0400 |
commit | a88ce63b642cf8cd82cbc278429ccd9de4455a07 (patch) | |
tree | dca6db72c66d83af27733dcbca50f5d89f55e1a8 | |
parent | 8165f70648da0a4a51e5871693781b2cc29b29d6 (diff) |
arm64: kexec: have own crash_smp_send_stop() for crash dump for nonpanic cores
Commit 0ee5941 : (x86/panic: replace smp_send_stop() with kdump friendly
version in panic path) introduced crash_smp_send_stop() which is a weak
function and can be overridden by architecture codes to fix the side effect
caused by commit f06e515 : (kernel/panic.c: add "crash_kexec_post_
notifiers" option).
ARM64 architecture uses the weak version function and the problem is that
the weak function simply calls smp_send_stop() which makes other CPUs
offline and takes away the chance to save crash information for nonpanic
CPUs in machine_crash_shutdown() when crash_kexec_post_notifiers kernel
option is enabled.
Calling smp_send_crash_stop() in machine_crash_shutdown() is useless
because all nonpanic CPUs are already offline by smp_send_stop() in this
case and smp_send_crash_stop() only works against online CPUs.
The result is that secondary CPUs registers are not saved by
crash_save_cpu() and the vmcore file misreports these CPUs as being
offline.
crash_smp_send_stop() is implemented to fix this problem by replacing the
existing smp_send_crash_stop() and adding a check for multiple calling to
the function. The function (strong symbol version) saves crash information
for nonpanic CPUs and machine_crash_shutdown() tries to save crash
information for nonpanic CPUs only when crash_kexec_post_notifiers kernel
option is disabled.
* crash_kexec_post_notifiers : false
panic()
__crash_kexec()
machine_crash_shutdown()
crash_smp_send_stop() <= save crash dump for nonpanic cores
* crash_kexec_post_notifiers : true
panic()
crash_smp_send_stop() <= save crash dump for nonpanic cores
__crash_kexec()
machine_crash_shutdown()
crash_smp_send_stop() <= just return.
Signed-off-by: Hoeun Ryu <hoeun.ryu@gmail.com>
Reviewed-by: James Morse <james.morse@arm.com>
Tested-by: James Morse <james.morse@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/include/asm/smp.h | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/machine_kexec.c | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/smp.c | 12 |
3 files changed, 13 insertions, 3 deletions
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 55f08c5acfad..f82b447bd34f 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h | |||
@@ -148,7 +148,7 @@ static inline void cpu_panic_kernel(void) | |||
148 | */ | 148 | */ |
149 | bool cpus_are_stuck_in_kernel(void); | 149 | bool cpus_are_stuck_in_kernel(void); |
150 | 150 | ||
151 | extern void smp_send_crash_stop(void); | 151 | extern void crash_smp_send_stop(void); |
152 | extern bool smp_crash_stop_failed(void); | 152 | extern bool smp_crash_stop_failed(void); |
153 | 153 | ||
154 | #endif /* ifndef __ASSEMBLY__ */ | 154 | #endif /* ifndef __ASSEMBLY__ */ |
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index 481f54a866c5..11121f608eb5 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c | |||
@@ -252,7 +252,7 @@ void machine_crash_shutdown(struct pt_regs *regs) | |||
252 | local_irq_disable(); | 252 | local_irq_disable(); |
253 | 253 | ||
254 | /* shutdown non-crashing cpus */ | 254 | /* shutdown non-crashing cpus */ |
255 | smp_send_crash_stop(); | 255 | crash_smp_send_stop(); |
256 | 256 | ||
257 | /* for crashing cpu */ | 257 | /* for crashing cpu */ |
258 | crash_save_cpu(regs, smp_processor_id()); | 258 | crash_save_cpu(regs, smp_processor_id()); |
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index f13ddb2404f9..ffe089942ac4 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
@@ -977,11 +977,21 @@ void smp_send_stop(void) | |||
977 | } | 977 | } |
978 | 978 | ||
979 | #ifdef CONFIG_KEXEC_CORE | 979 | #ifdef CONFIG_KEXEC_CORE |
980 | void smp_send_crash_stop(void) | 980 | void crash_smp_send_stop(void) |
981 | { | 981 | { |
982 | static int cpus_stopped; | ||
982 | cpumask_t mask; | 983 | cpumask_t mask; |
983 | unsigned long timeout; | 984 | unsigned long timeout; |
984 | 985 | ||
986 | /* | ||
987 | * This function can be called twice in panic path, but obviously | ||
988 | * we execute this only once. | ||
989 | */ | ||
990 | if (cpus_stopped) | ||
991 | return; | ||
992 | |||
993 | cpus_stopped = 1; | ||
994 | |||
985 | if (num_online_cpus() == 1) | 995 | if (num_online_cpus() == 1) |
986 | return; | 996 | return; |
987 | 997 | ||