/* * The caller of this wants the passed function to run on every cpu. If wait * is set, wait until all cpus have finished the function before returning. * The lock is here to protect the call structure. * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) { unsigned int nr_cpus = atomic_read(&cpus_booted); int i; if (nr_cpus < 2) return 0; /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); spin_lock(&smp_fn_call.lock); atomic_set(&smp_fn_call.finished, 0); smp_fn_call.fn = func; smp_fn_call.data = info; for (i = 0; i < nr_cpus; i++) if (i != smp_processor_id()) __smp_call_function(i); if (wait) while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); spin_unlock(&smp_fn_call.lock); return 0; }
int smp_call_function(void (*func) (void *info), void *info, int nonatomic, int wait) { /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); return __smp_call_function(func, info, nonatomic, wait); }
/* * smp_call_function - run a function on all other CPUs. * @func: The function to run. This must be fast and non-blocking. * @info: An arbitrary pointer to pass to the function. * @nonatomic: currently unused. * @wait: If true, wait (atomically) until function has completed on other * CPUs. * * Returns 0 on success, else a negative status code. Does not return until * remote CPUs are nearly ready to execute func or are or have executed. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. * Actually there are a few legal cases, like panic. */ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait) { spin_lock(&call_lock); __smp_call_function(func,info,nonatomic,wait); spin_unlock(&call_lock); return 0; }
static void native_smp_send_stop(void) { /* Don't deadlock on the call lock in panic */ int nolock = !spin_trylock(&call_lock); unsigned long flags; local_irq_save(flags); __smp_call_function(stop_this_cpu, NULL, 0, 0); if (!nolock) spin_unlock(&call_lock); disable_local_APIC(); local_irq_restore(flags); }
void smp_send_stop(void) { int nolock = 0; /* Don't deadlock on the call lock in panic */ if (!spin_trylock(&call_lock)) { /* ignore locking because we have paniced anyways */ nolock = 1; } __smp_call_function(smp_really_stop_cpu, NULL, 0, 0); if (!nolock) spin_unlock(&call_lock); smp_stop_cpu(); }
void smp_send_stop(void) { int nolock = 0; /* Don't deadlock on the call lock in panic */ if (!spin_trylock(&call_lock)) { udelay(100); /* ignore locking because we have paniced anyways */ nolock = 1; } __smp_call_function(smp_really_stop_cpu, NULL, 1, 0); if (!nolock) spin_unlock(&call_lock); local_irq_disable(); #ifndef CONFIG_XEN disable_local_APIC(); #endif local_irq_enable(); }
void smp_send_stop(void) { int nolock = 0; if (reboot_force) return; /* Don't deadlock on the call lock in panic */ if (!spin_trylock(&call_lock)) { /* ignore locking because we have paniced anyways */ nolock = 1; } __smp_call_function(smp_really_stop_cpu, NULL, 0, 0); if (!nolock) spin_unlock(&call_lock); local_irq_disable(); disable_local_APIC(); local_irq_enable(); }
int smp_call_function(void (*func) (void *info), void *info, int nonatomic, int wait) /* * [SUMMARY] Run a function on all other CPUs. * <func> The function to run. This must be fast and non-blocking. * <info> An arbitrary pointer to pass to the function. * <nonatomic> currently unused. * <wait> If true, wait (atomically) until function has completed on other CPUs. * [RETURNS] 0 on success, else a negative status code. Does not return until * remote CPUs are nearly ready to execute <<func>> or are or have executed. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ { /* FIXME: get cpu lock with hotplug cpus, or change this to bitmask. --RR */ if (num_online_cpus() <= 1) return 0; /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); return __smp_call_function(func, info, wait, MSG_ALL_BUT_SELF); }