On Wed, Jan 22, 2025 at 01:42:28PM +0100, Peter Zijlstra wrote: > So I'm a little confused, isn't something like this sufficient? > > If we hit before schedule(), all just works as expected, if we hit after > schedule(), the task will already have the TIF flag set, and we'll hit > the return to user path once it gets scheduled again. > > --- > diff --git a/kernel/task_work.c b/kernel/task_work.c > index c969f1f26be5..155549c017b2 100644 > --- a/kernel/task_work.c > +++ b/kernel/task_work.c > @@ -9,7 +9,12 @@ 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) > { > - test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); > + /* > + * no-op IPI > + * > + * TWA_NMI_CURRENT will already have set the TIF flag, all > + * this interrupt does it tickle the return-to-user path. > + */ > } > static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = > IRQ_WORK_INIT_HARD(task_work_set_notify_irq); > @@ -98,6 +103,7 @@ int task_work_add(struct task_struct *task, struct > callback_head *work, > break; > #ifdef CONFIG_IRQ_WORK > case TWA_NMI_CURRENT: > + set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); > irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); > break; > #endif
Yeah, that looks so much better... The self-IPI is only needed when the NMI happened in user space, right? Would it make sense to have an optimized version of that? -- Josh