diff options
| author | Luo Gengkun <[email protected]> | 2025-08-19 10:51:52 +0000 |
|---|---|---|
| committer | Steven Rostedt (Google) <[email protected]> | 2025-09-02 16:02:42 +0000 |
| commit | 3d62ab32df065e4a7797204a918f6489ddb8a237 (patch) | |
| tree | 813042c6413e7d76df03c5758a4e58deb263c3a6 /lib/raid6/algos.c | |
| parent | trace: Remove redundant __GFP_NOWARN (diff) | |
| download | kernel-3d62ab32df065e4a7797204a918f6489ddb8a237.tar.gz kernel-3d62ab32df065e4a7797204a918f6489ddb8a237.zip | |
tracing: Fix tracing_marker may trigger page fault during preempt_disable
Both tracing_mark_write and tracing_mark_raw_write call
__copy_from_user_inatomic during preempt_disable. But in some case,
__copy_from_user_inatomic may trigger page fault, and will call schedule()
subtly. And if a task is migrated to other cpu, the following warning will
be trigger:
if (RB_WARN_ON(cpu_buffer,
!local_read(&cpu_buffer->committing)))
An example can illustrate this issue:
process flow CPU
---------------------------------------------------------------------
tracing_mark_raw_write(): cpu:0
...
ring_buffer_lock_reserve(): cpu:0
...
cpu = raw_smp_processor_id() cpu:0
cpu_buffer = buffer->buffers[cpu] cpu:0
...
...
__copy_from_user_inatomic(): cpu:0
...
# page fault
do_mem_abort(): cpu:0
...
# Call schedule
schedule() cpu:0
...
# the task schedule to cpu1
__buffer_unlock_commit(): cpu:1
...
ring_buffer_unlock_commit(): cpu:1
...
cpu = raw_smp_processor_id() cpu:1
cpu_buffer = buffer->buffers[cpu] cpu:1
As shown above, the process will acquire cpuid twice and the return values
are not the same.
To fix this problem using copy_from_user_nofault instead of
__copy_from_user_inatomic, as the former performs 'access_ok' before
copying.
Link: https://lore.kernel.org/[email protected]
Fixes: 656c7f0d2d2b ("tracing: Replace kmap with copy_from_user() in trace_marker writing")
Signed-off-by: Luo Gengkun <[email protected]>
Reviewed-by: Masami Hiramatsu (Google) <[email protected]>
Signed-off-by: Steven Rostedt (Google) <[email protected]>
Diffstat (limited to 'lib/raid6/algos.c')
0 files changed, 0 insertions, 0 deletions
