summaryrefslogtreecommitdiffstats
path: root/kernel/smp.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-10-12 21:38:02 -0600
committerGrant Likely <grant.likely@secretlab.ca>2010-10-12 21:38:02 -0600
commit492c032beccd53f807811b6c14909630d409dd8c (patch)
tree208550c6ccecb8f1b4f85edb91702ca2bdef855e /kernel/smp.c
parentf9d629c737cb6687216a0c540b5466a4bd8b070a (diff)
parentcb655d0f3d57c23db51b981648e452988c0223f9 (diff)
Merge commit 'v2.6.36-rc7' into spi/next
Diffstat (limited to 'kernel/smp.c')
-rw-r--r--kernel/smp.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/kernel/smp.c b/kernel/smp.c
index 75c970c715d..ed6aacfcb7e 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -365,9 +365,10 @@ call:
EXPORT_SYMBOL_GPL(smp_call_function_any);
/**
- * __smp_call_function_single(): Run a function on another CPU
+ * __smp_call_function_single(): Run a function on a specific CPU
* @cpu: The CPU to run on.
* @data: Pre-allocated and setup data structure
+ * @wait: If true, wait until function has completed on specified CPU.
*
* Like smp_call_function_single(), but allow caller to pass in a
* pre-allocated data structure. Useful for embedding @data inside
@@ -376,8 +377,10 @@ EXPORT_SYMBOL_GPL(smp_call_function_any);
void __smp_call_function_single(int cpu, struct call_single_data *data,
int wait)
{
- csd_lock(data);
+ unsigned int this_cpu;
+ unsigned long flags;
+ this_cpu = get_cpu();
/*
* Can deadlock when called with interrupts disabled.
* We allow cpu's that are not yet online though, as no one else can
@@ -387,7 +390,15 @@ void __smp_call_function_single(int cpu, struct call_single_data *data,
WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled()
&& !oops_in_progress);
- generic_exec_single(cpu, data, wait);
+ if (cpu == this_cpu) {
+ local_irq_save(flags);
+ data->func(data->info);
+ local_irq_restore(flags);
+ } else {
+ csd_lock(data);
+ generic_exec_single(cpu, data, wait);
+ }
+ put_cpu();
}
/**