void crash_ipi_callback(struct pt_regs *regs) { static cpumask_t cpus_state_saved = CPU_MASK_NONE; int cpu = smp_processor_id(); hard_irq_disable(); if (!cpumask_test_cpu(cpu, &cpus_state_saved)) { crash_save_cpu(regs, cpu); cpumask_set_cpu(cpu, &cpus_state_saved); } atomic_inc(&cpus_in_crash); smp_mb__after_atomic(); /* * Starting the kdump boot. * This barrier is needed to make sure that all CPUs are stopped. */ while (!time_to_dump) cpu_relax(); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 1); #ifdef CONFIG_PPC64 kexec_smp_wait(); #else for (;;); /* FIXME */ #endif /* NOTREACHED */ }
/* FIXME: we should schedule this function to be called on all cpus based * on calling the interrupts, but we would like to call it off irq level * so that the interrupt controller is clean. */ static void kexec_smp_down(void *arg) { if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 1); local_irq_disable(); kexec_smp_wait(); /* NOTREACHED */ }
void crash_ipi_callback(struct pt_regs *regs) { int cpu = smp_processor_id(); if (!cpu_online(cpu)) return; hard_irq_disable(); if (!cpu_isset(cpu, cpus_in_crash)) crash_save_cpu(regs, cpu); cpu_set(cpu, cpus_in_crash); /* * Entered via soft-reset - could be the kdump * process is invoked using soft-reset or user activated * it if some CPU did not respond to an IPI. * For soft-reset, the secondary CPU can enter this func * twice. 1 - using IPI, and 2. soft-reset. * Tell the kexec CPU that entered via soft-reset and ready * to go down. */ if (cpu_isset(cpu, cpus_in_sr)) { cpu_clear(cpu, cpus_in_sr); atomic_inc(&enter_on_soft_reset); } /* * Starting the kdump boot. * This barrier is needed to make sure that all CPUs are stopped. * If not, soft-reset will be invoked to bring other CPUs. */ while (!cpu_isset(crashing_cpu, cpus_in_crash)) cpu_relax(); if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 1); #ifdef CONFIG_PPC64 kexec_smp_wait(); #else for (;;); /* FIXME */ #endif /* NOTREACHED */ }
static void kexec_smp_down(void *arg) { local_irq_disable(); mb(); /* make sure our irqs are disabled before we say they are */ get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; while(kexec_all_irq_disabled == 0) cpu_relax(); mb(); /* make sure all irqs are disabled before this */ /* * Now every CPU has IRQs off, we can clear out any pending * IPIs and be sure that no more will come in after this. */ if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 1); kexec_smp_wait(); /* NOTREACHED */ }