diff options
author | Jan Kara <jack@suse.cz> | 2014-02-24 10:39:57 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-02-24 17:46:55 -0500 |
commit | 08eed44c7249d381a099bc55577e55c6bb533160 (patch) | |
tree | f4d2467cd82c40e10ec0e360398891632edf6a48 /kernel/smp.c | |
parent | 0ebeb79ce920bed3a4a55113534951d95a444fbb (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.c | 11 |
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 | */ |
286 | void __smp_call_function_single(int cpu, struct call_single_data *csd, | 286 | int __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 | } |
312 | EXPORT_SYMBOL_GPL(__smp_call_function_single); | 315 | EXPORT_SYMBOL_GPL(__smp_call_function_single); |
313 | 316 | ||