aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2014-02-24 10:40:01 -0500
committerJens Axboe <axboe@fb.com>2014-02-24 17:47:09 -0500
commitfce8ad1568c57e7f334018dec4fa1744c926c135 (patch)
tree7660f5d36efc83f90b35200f28c807423549afde /kernel
parente0a23b0628b10d25f2c178be6fcfc17c1ab49fda (diff)
smp: Remove wait argument from __smp_call_function_single()
The main point of calling __smp_call_function_single() is to send an IPI in a pure asynchronous way. By embedding a csd in an object, a caller can send the IPI without waiting for a previous one to complete as is required by smp_call_function_single() for example. As such, sending this kind of IPI can be safe even when irqs are disabled. This flexibility comes at the expense of the caller who then needs to synchronize the csd lifecycle by himself and make sure that IPIs on a single csd are serialized. This is how __smp_call_function_single() works when wait = 0 and this usecase is relevant. Now there don't seem to be any usecase with wait = 1 that can't be covered by smp_call_function_single() instead, which is safer. Lets look at the two possible scenario: 1) The user calls __smp_call_function_single(wait = 1) on a csd embedded in an object. It looks like a nice and convenient pattern at the first sight because we can then retrieve the object from the IPI handler easily. But actually it is a waste of memory space in the object since the csd can be allocated from the stack by smp_call_function_single(wait = 1) and the object can be passed an the IPI argument. Besides that, embedding the csd in an object is more error prone because the caller must take care of the serialization of the IPIs for this csd. 2) The user calls __smp_call_function_single(wait = 1) on a csd that is allocated on the stack. It's ok but smp_call_function_single() can do it as well and it already takes care of the allocation on the stack. Again it's more simple and less error prone. Therefore, using the underscore prepend API version with wait = 1 is a bad pattern and a sign that the caller can do safer and more simple. There was a single user of that which has just been converted. So lets remove this option to discourage further users. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Christoph Hellwig <hch@infradead.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jan Kara <jack@suse.cz> 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')
-rw-r--r--kernel/sched/core.c2
-rw-r--r--kernel/smp.c19
-rw-r--r--kernel/up.c3
3 files changed, 6 insertions, 18 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b46131ef6aab..eba3d84765f3 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -432,7 +432,7 @@ void hrtick_start(struct rq *rq, u64 delay)
432 if (rq == this_rq()) { 432 if (rq == this_rq()) {
433 __hrtick_restart(rq); 433 __hrtick_restart(rq);
434 } else if (!rq->hrtick_csd_pending) { 434 } else if (!rq->hrtick_csd_pending) {
435 __smp_call_function_single(cpu_of(rq), &rq->hrtick_csd, 0); 435 __smp_call_function_single(cpu_of(rq), &rq->hrtick_csd);
436 rq->hrtick_csd_pending = 1; 436 rq->hrtick_csd_pending = 1;
437 } 437 }
438} 438}
diff --git a/kernel/smp.c b/kernel/smp.c
index fa04ab938e52..b76763189752 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -241,29 +241,18 @@ EXPORT_SYMBOL(smp_call_function_single);
241 * __smp_call_function_single(): Run a function on a specific CPU 241 * __smp_call_function_single(): Run a function on a specific CPU
242 * @cpu: The CPU to run on. 242 * @cpu: The CPU to run on.
243 * @csd: Pre-allocated and setup data structure 243 * @csd: Pre-allocated and setup data structure
244 * @wait: If true, wait until function has completed on specified CPU.
245 * 244 *
246 * Like smp_call_function_single(), but allow caller to pass in a 245 * Like smp_call_function_single(), but allow caller to pass in a
247 * pre-allocated data structure. Useful for embedding @data inside 246 * pre-allocated data structure. Useful for embedding @data inside
248 * other structures, for instance. 247 * other structures, for instance.
249 */ 248 */
250int __smp_call_function_single(int cpu, struct call_single_data *csd, int wait) 249int __smp_call_function_single(int cpu, struct call_single_data *csd)
251{ 250{
252 int err = 0; 251 int err = 0;
253 int this_cpu;
254 252
255 this_cpu = get_cpu(); 253 preempt_disable();
256 /* 254 err = generic_exec_single(cpu, csd, csd->func, csd->info, 0);
257 * Can deadlock when called with interrupts disabled. 255 preempt_enable();
258 * We allow cpu's that are not yet online though, as no one else can
259 * send smp call function interrupt to this cpu and as such deadlocks
260 * can't happen.
261 */
262 WARN_ON_ONCE(cpu_online(this_cpu) && wait && irqs_disabled()
263 && !oops_in_progress);
264
265 err = generic_exec_single(cpu, csd, csd->func, csd->info, wait);
266 put_cpu();
267 256
268 return err; 257 return err;
269} 258}
diff --git a/kernel/up.c b/kernel/up.c
index cdf03d16840e..4e199d4cef8e 100644
--- a/kernel/up.c
+++ b/kernel/up.c
@@ -22,8 +22,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
22} 22}
23EXPORT_SYMBOL(smp_call_function_single); 23EXPORT_SYMBOL(smp_call_function_single);
24 24
25int __smp_call_function_single(int cpu, struct call_single_data *csd, 25int __smp_call_function_single(int cpu, struct call_single_data *csd)
26 int wait)
27{ 26{
28 unsigned long flags; 27 unsigned long flags;
29 28