Re: [RESEND][PATCH v15 0/4] perf: Support the deferred unwinding infrastructure
From: Peter Zijlstra <peterz@infradead.org>
Date: 2025-09-18 17:24:31
Also in:
bpf, lkml
On Thu, Sep 18, 2025 at 11:18:53AM -0400, Steven Rostedt wrote:
On Thu, 18 Sep 2025 13:46:10 +0200 Peter Zijlstra [off-list ref] wrote:quoted
So I started looking at this, but given I never seen the deferred unwind bits that got merged I have to look at that first. Headers want something like so.. Let me read the rest. --- include/linux/unwind_deferred.h | 38 +++++++++++++++++++---------------- include/linux/unwind_deferred_types.h | 2 ++ 2 files changed, 23 insertions(+), 17 deletions(-)Would you like to send a formal patch with this? I'd actually break it into two patches. One to clean up the long lines, and the other to change the logic.
Sure, I'll collect the lot while I go through it and whip something up
when I'm done. For now, I'll just shoot a few questions your way.
So we have:
do_syscall_64()
... do stuff ...
syscall_exit_to_user_mode(regs)
syscall_exit_to_user_mode_work(regs)
syscall_exit_work()
exit_to_user_mode_prepare()
exit_to_user_mode_loop()
retume_user_mode_work()
task_work_run()
exit_to_user_mode()
unwind_reset_info();
user_enter_irqoff();
arch_exit_to_user_mode();
lockdep_hardirqs_on();
SYSRET/IRET
and
DEFINE_IDTENTRY*()
irqentry_enter();
... stuff ...
irqentry_exit()
irqentry_exit_to_user_mode()
exit_to_user_mode_prepare()
exit_to_user_mode_loop();
retume_user_mode_work()
task_work_run()
exit_to_user_mode()
unwind_reset_info();
...
IRET
Now, task_work_run() is in the exit_to_user_mode_loop() which is notably
*before* exit_to_user_mode() which does the unwind_reset_info().
What happens if we get an NMI requesting an unwind after
unwind_reset_info() while still very much being in the kernel on the way
out?
What is the purpose of unwind_deferred_task_exit()? This is called from
do_exit(), only slightly before it does exit_task_work(), which runs all
pending task_work. Is there something that justifies the manual run and
cancel instead of just leaving it sit in task_work an having it run
naturally? If so, that most certainly deserves a comment.
A similar question for unwind_task_free(), where exactly is it relevant?
Where does it acquire a task_work that is not otherwise already ran on
exit?