From Sashiko: 
https://sashiko.dev/#/patchset/20260724184250.357e91f1%40gandalf.local.home

> --- Patch [1]: [PATCH] tracing: perf: Fix stale head for perf syscall tracing 
> ---
> commit c99950733eb63d5661f5e4d25f82dff506833b49
> Author: Steven Rostedt <[email protected]>
> 
> tracing: perf: Fix stale head for perf syscall tracing
> 
> This commit delays capturing the head of the per CPU perf events list until
> after the faulting code completes. This prevents the head pointer from 
> pointing
> to the wrong CPU event if the syscall data read enables preemption and 
> migrates.
> 
> Link: 
> https://sashiko.dev/#/patchset/20260717173252.3431565-1-usama.arif%40linux.dev
> 
> > diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
> > index e98ee7e1e66f4..e541e964d1930 100644
> > --- a/kernel/trace/trace_syscalls.c
> > +++ b/kernel/trace/trace_syscalls.c
> > @@ -1440,19 +1440,20 @@ static void perf_syscall_enter(void *ignore, struct 
> > pt_regs *regs, long id)
> 
> [ ... ]
> 
> >     guard(preempt_notrace)();
> >  
> > -   head = this_cpu_ptr(sys_data->enter_event->perf_events);
> > -   if (hlist_empty(head))
> > -           return;
> > -
> >     /* Check if this syscall event faults in user space memory */
> >     mayfault = sys_data->user_mask != 0;
> >  
> >     if (mayfault) {
> > +           /* Enables preemption and may migrate */
> >             if (syscall_get_data(sys_data, args, &user_ptr,
> >                                  &size, user_sizes, &uargs, buf_size) < 0)
> >                     return;
> >     }
> >  
> > +   head = this_cpu_ptr(sys_data->enter_event->perf_events);
> > +   if (hlist_empty(head))
> > +           return;
> 
> Will moving this early check below syscall_get_data() cause a severe
> performance regression for untraced CPUs?

I was thinking this might be the case. I originally thought it wouldn't be
too much of an issue, but I can see that the reading of user space when you
don't need to would be a regression in performance.

I'll change the above to be:

        guard(preempt_notrace)();

        head = this_cpu_ptr(sys_data->enter_event->perf_events);
        if (hlist_empty(head))
                return;

        /* Check if this syscall event faults in user space memory */
        mayfault = sys_data->user_mask != 0;

        if (mayfault) {
                if (syscall_get_data(sys_data, args, &user_ptr,
                                     &size, user_sizes, &uargs, buf_size) < 0)
                        return;

                /* The above may have caused a migration */
                head = this_cpu_ptr(sys_data->enter_event->perf_events);
                if (hlist_empty(head))
                        return;
        }

-- Steve



> 
> Because the enabled_perf_enter_syscalls bitmap is global, enabling a perf
> syscall trace on one CPU causes perf_syscall_enter() to be invoked on all
> CPUs executing that syscall.
> 
> Previously, the early hlist_empty() check allowed CPUs not actively tracing
> the event to return immediately.
> 
> By moving this check until after syscall_get_data(), doesn't this force all
> untraced CPUs to unconditionally execute expensive user-space memory copies
> and preemption toggling before discarding the data?

Reply via email to