diff options
author | Peter Zijlstra <peterz@infradead.org> | 2019-07-18 05:20:09 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2019-07-20 05:27:16 -0400 |
commit | 19dbdcb8039cff16669a05136a29180778d16d0a (patch) | |
tree | a03d0d84fb3a5ff58df3c4da7bbd16acca5518a0 | |
parent | 22051d9c4a57d3b4a8b5a7407efc80c71c7bfb16 (diff) |
smp: Warn on function calls from softirq context
It's clearly documented that smp function calls cannot be invoked from
softirq handling context. Unfortunately nothing enforces that or emits a
warning.
A single function call can be invoked from softirq context only via
smp_call_function_single_async().
The only legit context is task context, so add a warning to that effect.
Reported-by: luferry <luferry@163.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190718160601.GP3402@hirez.programming.kicks-ass.net
-rw-r--r-- | kernel/smp.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/smp.c b/kernel/smp.c index 616d4d114847..7dbcb402c2fc 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -291,6 +291,14 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info, | |||
291 | WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() | 291 | WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() |
292 | && !oops_in_progress); | 292 | && !oops_in_progress); |
293 | 293 | ||
294 | /* | ||
295 | * When @wait we can deadlock when we interrupt between llist_add() and | ||
296 | * arch_send_call_function_ipi*(); when !@wait we can deadlock due to | ||
297 | * csd_lock() on because the interrupt context uses the same csd | ||
298 | * storage. | ||
299 | */ | ||
300 | WARN_ON_ONCE(!in_task()); | ||
301 | |||
294 | csd = &csd_stack; | 302 | csd = &csd_stack; |
295 | if (!wait) { | 303 | if (!wait) { |
296 | csd = this_cpu_ptr(&csd_data); | 304 | csd = this_cpu_ptr(&csd_data); |
@@ -416,6 +424,14 @@ void smp_call_function_many(const struct cpumask *mask, | |||
416 | WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() | 424 | WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() |
417 | && !oops_in_progress && !early_boot_irqs_disabled); | 425 | && !oops_in_progress && !early_boot_irqs_disabled); |
418 | 426 | ||
427 | /* | ||
428 | * When @wait we can deadlock when we interrupt between llist_add() and | ||
429 | * arch_send_call_function_ipi*(); when !@wait we can deadlock due to | ||
430 | * csd_lock() on because the interrupt context uses the same csd | ||
431 | * storage. | ||
432 | */ | ||
433 | WARN_ON_ONCE(!in_task()); | ||
434 | |||
419 | /* Try to fastpath. So, what's a CPU they want? Ignoring this one. */ | 435 | /* Try to fastpath. So, what's a CPU they want? Ignoring this one. */ |
420 | cpu = cpumask_first_and(mask, cpu_online_mask); | 436 | cpu = cpumask_first_and(mask, cpu_online_mask); |
421 | if (cpu == this_cpu) | 437 | if (cpu == this_cpu) |