static void crash_kexec_prepare_cpus(int cpu) { unsigned int msecs; unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ crash_send_ipi(crash_ipi_callback); smp_wmb(); printk(KERN_EMERG "Sending IPI to other cpus...\n"); msecs = 10000; while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { cpu_relax(); mdelay(1); } /* Would it be better to replace the trap vector here? */ if (cpus_weight(cpus_in_crash) < ncpus) { printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", ncpus - cpus_weight(cpus_in_crash)); printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); cpus_in_sr = CPU_MASK_NONE; atomic_set(&enter_on_soft_reset, 0); while (cpus_weight(cpus_in_crash) < ncpus) cpu_relax(); } /* * Make sure all CPUs are entered via soft-reset if the kdump is * invoked using soft-reset. */ if (cpu_isset(cpu, cpus_in_sr)) crash_soft_reset_check(cpu); /* Leave the IPI callback set */ }
static void crash_kexec_prepare_cpus(int cpu) { unsigned int msecs; unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ crash_send_ipi(crash_ipi_callback); smp_wmb(); /* * FIXME: Until we will have the way to stop other CPUSs reliabally, * the crash CPU will send an IPI and wait for other CPUs to * respond. * Delay of at least 10 seconds. */ printk(KERN_EMERG "Sending IPI to other cpus...\n"); msecs = 10000; while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { cpu_relax(); mdelay(1); } /* Would it be better to replace the trap vector here? */ /* * FIXME: In case if we do not get all CPUs, one possibility: ask the * user to do soft reset such that we get all. * Soft-reset will be used until better mechanism is implemented. */ if (cpus_weight(cpus_in_crash) < ncpus) { printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", ncpus - cpus_weight(cpus_in_crash)); printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); cpus_in_sr = CPU_MASK_NONE; atomic_set(&enter_on_soft_reset, 0); while (cpus_weight(cpus_in_crash) < ncpus) cpu_relax(); } /* * Make sure all CPUs are entered via soft-reset if the kdump is * invoked using soft-reset. */ if (cpu_isset(cpu, cpus_in_sr)) crash_soft_reset_check(cpu); /* Leave the IPI callback set */ }
/* * This function will be called by secondary cpus or by kexec cpu * if soft-reset is activated to stop some CPUs. */ void crash_kexec_secondary(struct pt_regs *regs) { int cpu = smp_processor_id(); unsigned long flags; int msecs = 5; local_irq_save(flags); /* Wait 5ms if the kexec CPU is not entered yet. */ while (crashing_cpu < 0) { if (--msecs < 0) { /* * Either kdump image is not loaded or * kdump process is not started - Probably xmon * exited using 'x'(exit and recover) or * kexec_should_crash() failed for all running tasks. */ cpu_clear(cpu, cpus_in_sr); local_irq_restore(flags); return; } mdelay(1); cpu_relax(); } if (cpu == crashing_cpu) { /* * Panic CPU will enter this func only via soft-reset. * Wait until all secondary CPUs entered and * then start kexec boot. */ crash_soft_reset_check(cpu); cpu_set(crashing_cpu, cpus_in_crash); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); machine_kexec(kexec_crash_image); /* NOTREACHED */ } crash_ipi_callback(regs); }