aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/smp.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-02-24 10:39:57 -0500
committerJens Axboe <axboe@fb.com>2014-02-24 17:46:55 -0500
commit08eed44c7249d381a099bc55577e55c6bb533160 (patch)
treef4d2467cd82c40e10ec0e360398891632edf6a48 /kernel/smp.c
parent0ebeb79ce920bed3a4a55113534951d95a444fbb (diff)
smp: Teach __smp_call_function_single() to check for offline cpus
Align __smp_call_function_single() with smp_call_function_single() so that it also checks whether requested cpu is still online. Signed-off-by: Jan Kara <jack@suse.cz> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Christoph Hellwig <hch@infradead.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jens Axboe <axboe@fb.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'kernel/smp.c')
-rw-r--r--kernel/smp.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/kernel/smp.c b/kernel/smp.c
index e3852de042a6..5ff14e3739ca 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -276,18 +276,18 @@ EXPORT_SYMBOL_GPL(smp_call_function_any);
276/** 276/**
277 * __smp_call_function_single(): Run a function on a specific CPU 277 * __smp_call_function_single(): Run a function on a specific CPU
278 * @cpu: The CPU to run on. 278 * @cpu: The CPU to run on.
279 * @data: Pre-allocated and setup data structure 279 * @csd: Pre-allocated and setup data structure
280 * @wait: If true, wait until function has completed on specified CPU. 280 * @wait: If true, wait until function has completed on specified CPU.
281 * 281 *
282 * Like smp_call_function_single(), but allow caller to pass in a 282 * Like smp_call_function_single(), but allow caller to pass in a
283 * pre-allocated data structure. Useful for embedding @data inside 283 * pre-allocated data structure. Useful for embedding @data inside
284 * other structures, for instance. 284 * other structures, for instance.
285 */ 285 */
286void __smp_call_function_single(int cpu, struct call_single_data *csd, 286int __smp_call_function_single(int cpu, struct call_single_data *csd, int wait)
287 int wait)
288{ 287{
289 unsigned int this_cpu; 288 unsigned int this_cpu;
290 unsigned long flags; 289 unsigned long flags;
290 int err = 0;
291 291
292 this_cpu = get_cpu(); 292 this_cpu = get_cpu();
293 /* 293 /*
@@ -303,11 +303,14 @@ void __smp_call_function_single(int cpu, struct call_single_data *csd,
303 local_irq_save(flags); 303 local_irq_save(flags);
304 csd->func(csd->info); 304 csd->func(csd->info);
305 local_irq_restore(flags); 305 local_irq_restore(flags);
306 } else { 306 } else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
307 csd_lock(csd); 307 csd_lock(csd);
308 generic_exec_single(cpu, csd, wait); 308 generic_exec_single(cpu, csd, wait);
309 } else {
310 err = -ENXIO; /* CPU not online */
309 } 311 }
310 put_cpu(); 312 put_cpu();
313 return err;
311} 314}
312EXPORT_SYMBOL_GPL(__smp_call_function_single); 315EXPORT_SYMBOL_GPL(__smp_call_function_single);
313 316