Esempio n. 1
0
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 */
}
Esempio n. 2
0
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 */
}
Esempio n. 3
0
/*
 * 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);
}