Skip to content

Commit 17a1a10

Browse files
committed
tracing: Replace syscall RCU pointer assignment with READ/WRITE_ONCE()
The syscall events are pseudo events that hook to the raw syscalls. The ftrace_syscall_enter/exit() callback is called by the raw_syscall enter/exit tracepoints respectively whenever any of the syscall events are enabled. The trace_array has an array of syscall "files" that correspond to the system calls based on their __NR_SYSCALL number. The array is read and if there's a pointer to a trace_event_file then it is considered enabled and if it is NULL that syscall event is considered disabled. Currently it uses an rcu_dereference_sched() to get this pointer and a rcu_assign_ptr() or RCU_INIT_POINTER() to write to it. This is unnecessary as the file pointer will not go away outside the synchronization of the tracepoint logic itself. And this code adds no extra RCU synchronization that uses this. Replace these functions with a simple READ_ONCE() and WRITE_ONCE() which is all they need. This will also allow this code to not depend on preemption being disabled as system call tracepoints are now allowed to fault. Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Takaya Saeki <takayas@google.com> Cc: Tom Zanussi <zanussi@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ian Rogers <irogers@google.com> Cc: Douglas Raillard <douglas.raillard@arm.com> Link: https://lore.kernel.org/20250923130713.594320290@kernel.org Reviewed-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 76eeb9b commit 17a1a10

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

kernel/trace/trace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,8 @@ struct trace_array {
380380
#ifdef CONFIG_FTRACE_SYSCALLS
381381
int sys_refcount_enter;
382382
int sys_refcount_exit;
383-
struct trace_event_file __rcu *enter_syscall_files[NR_syscalls];
384-
struct trace_event_file __rcu *exit_syscall_files[NR_syscalls];
383+
struct trace_event_file *enter_syscall_files[NR_syscalls];
384+
struct trace_event_file *exit_syscall_files[NR_syscalls];
385385
#endif
386386
int stop_count;
387387
int clock_id;

kernel/trace/trace_syscalls.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
310310
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
311311
return;
312312

313-
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE) */
314-
trace_file = rcu_dereference_sched(tr->enter_syscall_files[syscall_nr]);
313+
trace_file = READ_ONCE(tr->enter_syscall_files[syscall_nr]);
315314
if (!trace_file)
316315
return;
317316

@@ -356,8 +355,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
356355
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
357356
return;
358357

359-
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE()) */
360-
trace_file = rcu_dereference_sched(tr->exit_syscall_files[syscall_nr]);
358+
trace_file = READ_ONCE(tr->exit_syscall_files[syscall_nr]);
361359
if (!trace_file)
362360
return;
363361

@@ -393,7 +391,7 @@ static int reg_event_syscall_enter(struct trace_event_file *file,
393391
if (!tr->sys_refcount_enter)
394392
ret = register_trace_sys_enter(ftrace_syscall_enter, tr);
395393
if (!ret) {
396-
rcu_assign_pointer(tr->enter_syscall_files[num], file);
394+
WRITE_ONCE(tr->enter_syscall_files[num], file);
397395
tr->sys_refcount_enter++;
398396
}
399397
mutex_unlock(&syscall_trace_lock);
@@ -411,7 +409,7 @@ static void unreg_event_syscall_enter(struct trace_event_file *file,
411409
return;
412410
mutex_lock(&syscall_trace_lock);
413411
tr->sys_refcount_enter--;
414-
RCU_INIT_POINTER(tr->enter_syscall_files[num], NULL);
412+
WRITE_ONCE(tr->enter_syscall_files[num], NULL);
415413
if (!tr->sys_refcount_enter)
416414
unregister_trace_sys_enter(ftrace_syscall_enter, tr);
417415
mutex_unlock(&syscall_trace_lock);
@@ -431,7 +429,7 @@ static int reg_event_syscall_exit(struct trace_event_file *file,
431429
if (!tr->sys_refcount_exit)
432430
ret = register_trace_sys_exit(ftrace_syscall_exit, tr);
433431
if (!ret) {
434-
rcu_assign_pointer(tr->exit_syscall_files[num], file);
432+
WRITE_ONCE(tr->exit_syscall_files[num], file);
435433
tr->sys_refcount_exit++;
436434
}
437435
mutex_unlock(&syscall_trace_lock);
@@ -449,7 +447,7 @@ static void unreg_event_syscall_exit(struct trace_event_file *file,
449447
return;
450448
mutex_lock(&syscall_trace_lock);
451449
tr->sys_refcount_exit--;
452-
RCU_INIT_POINTER(tr->exit_syscall_files[num], NULL);
450+
WRITE_ONCE(tr->exit_syscall_files[num], NULL);
453451
if (!tr->sys_refcount_exit)
454452
unregister_trace_sys_exit(ftrace_syscall_exit, tr);
455453
mutex_unlock(&syscall_trace_lock);

0 commit comments

Comments
 (0)