Commit cec6937d authored by Linus Torvalds's avatar Linus Torvalds

task_work: make TWA_NMI_CURRENT handling conditional on IRQ_WORK

The TWA_NMI_CURRENT handling very much depends on IRQ_WORK, but that
isn't universally enabled everywhere.

Maybe the IRQ_WORK infrastructure should just be unconditional - x86
ends up indirectly enabling it through unconditionally enabling
PERF_EVENTS, for example.  But it also gets enabled by having SMP
support, or even if you just have PRINTK enabled.

But in the meantime TWA_NMI_CURRENT causes tons of build failures on
various odd minimal configs.  Which did show up in linux-next, but
despite that nobody bothered to fix it or even inform me until -rc1 was
out.

Fixes: 466e4d80 ("task_work: Add TWA_NMI_CURRENT as an additional notify mode")
Reported-by: default avatarNaresh Kamboju <naresh.kamboju@linaro.org>
Reported-by: default avatarkernelci.org bot <bot@kernelci.org>
Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2accfdb7
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
static struct callback_head work_exited; /* all we need is ->next == NULL */ static struct callback_head work_exited; /* all we need is ->next == NULL */
#ifdef CONFIG_IRQ_WORK
static void task_work_set_notify_irq(struct irq_work *entry) static void task_work_set_notify_irq(struct irq_work *entry)
{ {
test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME);
} }
static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) =
IRQ_WORK_INIT_HARD(task_work_set_notify_irq); IRQ_WORK_INIT_HARD(task_work_set_notify_irq);
#endif
/** /**
* task_work_add - ask the @task to execute @work->func() * task_work_add - ask the @task to execute @work->func()
...@@ -57,6 +59,8 @@ int task_work_add(struct task_struct *task, struct callback_head *work, ...@@ -57,6 +59,8 @@ int task_work_add(struct task_struct *task, struct callback_head *work,
if (notify == TWA_NMI_CURRENT) { if (notify == TWA_NMI_CURRENT) {
if (WARN_ON_ONCE(task != current)) if (WARN_ON_ONCE(task != current))
return -EINVAL; return -EINVAL;
if (!IS_ENABLED(CONFIG_IRQ_WORK))
return -EINVAL;
} else { } else {
/* record the work call stack in order to print it in KASAN reports */ /* record the work call stack in order to print it in KASAN reports */
kasan_record_aux_stack(work); kasan_record_aux_stack(work);
...@@ -81,9 +85,11 @@ int task_work_add(struct task_struct *task, struct callback_head *work, ...@@ -81,9 +85,11 @@ int task_work_add(struct task_struct *task, struct callback_head *work,
case TWA_SIGNAL_NO_IPI: case TWA_SIGNAL_NO_IPI:
__set_notify_signal(task); __set_notify_signal(task);
break; break;
#ifdef CONFIG_IRQ_WORK
case TWA_NMI_CURRENT: case TWA_NMI_CURRENT:
irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume));
break; break;
#endif
default: default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment