summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/fadump.c
diff options
context:
space:
mode:
authorTony Lindgren2017-03-06 17:37:53 +0100
committerTony Lindgren2017-03-06 17:37:53 +0100
commite24bce8fb4c26bd0d8eca74cbbee1ad049246be3 (patch)
treec219c2ec183633aa15841fca5b055a09d2d0b980 /arch/powerpc/kernel/fadump.c
parentARM: OMAP2+: Release device node after it is no longer needed. (diff)
parentLinux 4.11-rc1 (diff)
downloadkernel-qcow2-linux-e24bce8fb4c26bd0d8eca74cbbee1ad049246be3.tar.gz
kernel-qcow2-linux-e24bce8fb4c26bd0d8eca74cbbee1ad049246be3.tar.xz
kernel-qcow2-linux-e24bce8fb4c26bd0d8eca74cbbee1ad049246be3.zip
Merge tag 'v4.11-rc1' into omap-for-v4.11/fixes
Linux 4.11-rc1
Diffstat (limited to 'arch/powerpc/kernel/fadump.c')
-rw-r--r--arch/powerpc/kernel/fadump.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 8f0c7c5d93f2..8ff0dd4e77a7 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -406,12 +406,35 @@ static void register_fw_dump(struct fadump_mem_struct *fdm)
void crash_fadump(struct pt_regs *regs, const char *str)
{
struct fadump_crash_info_header *fdh = NULL;
+ int old_cpu, this_cpu;
if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr)
return;
+ /*
+ * old_cpu == -1 means this is the first CPU which has come here,
+ * go ahead and trigger fadump.
+ *
+ * old_cpu != -1 means some other CPU has already on it's way
+ * to trigger fadump, just keep looping here.
+ */
+ this_cpu = smp_processor_id();
+ old_cpu = cmpxchg(&crashing_cpu, -1, this_cpu);
+
+ if (old_cpu != -1) {
+ /*
+ * We can't loop here indefinitely. Wait as long as fadump
+ * is in force. If we race with fadump un-registration this
+ * loop will break and then we go down to normal panic path
+ * and reboot. If fadump is in force the first crashing
+ * cpu will definitely trigger fadump.
+ */
+ while (fw_dump.dump_registered)
+ cpu_relax();
+ return;
+ }
+
fdh = __va(fw_dump.fadumphdr_addr);
- crashing_cpu = smp_processor_id();
fdh->crashing_cpu = crashing_cpu;
crash_save_vmcoreinfo();