mirror of
https://github.com/torvalds/linux.git
synced 2026-08-04 22:38:46 +02:00
Lockdep reports this deadlock log:
osnoise: could not start sampling thread
============================================
WARNING: possible recursive locking detected
--------------------------------------------
CPU0
----
lock(cpu_hotplug_lock);
lock(cpu_hotplug_lock);
Call Trace:
<TASK>
print_deadlock_bug+0x282/0x3c0
__lock_acquire+0x1610/0x29a0
lock_acquire+0xcb/0x2d0
cpus_read_lock+0x49/0x120
stop_per_cpu_kthreads+0x7/0x60
start_kthread+0x103/0x120
osnoise_hotplug_workfn+0x5e/0x90
process_one_work+0x44f/0xb30
worker_thread+0x33e/0x5e0
kthread+0x206/0x3b0
ret_from_fork+0x31/0x50
ret_from_fork_asm+0x11/0x20
</TASK>
This is the deadlock scenario:
osnoise_hotplug_workfn()
guard(cpus_read_lock)(); // first lock call
start_kthread(cpu)
if (IS_ERR(kthread)) {
stop_per_cpu_kthreads(); {
cpus_read_lock(); // second lock call. Cause the AA deadlock
}
}
It is not necessary to call stop_per_cpu_kthreads() which stops osnoise
kthread for every other CPUs in the system if a failure occurs during
hotplug of a certain CPU.
For start_per_cpu_kthreads(), if the start_kthread() call fails,
this function calls stop_per_cpu_kthreads() to handle the error.
Therefore, similarly, there is no need to call stop_per_cpu_kthreads()
again within start_kthread().
So just remove stop_per_cpu_kthreads() from start_kthread to solve this issue.
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/20250321095249.2739397-1-ranxiaokai627@163.com
Fixes:
|
||
|---|---|---|
| .. | ||
| rv | ||
| blktrace.c | ||
| bpf_trace.c | ||
| bpf_trace.h | ||
| error_report-traces.c | ||
| fgraph.c | ||
| fprobe.c | ||
| ftrace_internal.h | ||
| ftrace.c | ||
| Kconfig | ||
| kprobe_event_gen_test.c | ||
| Makefile | ||
| pid_list.c | ||
| pid_list.h | ||
| power-traces.c | ||
| preemptirq_delay_test.c | ||
| rethook.c | ||
| ring_buffer_benchmark.c | ||
| ring_buffer.c | ||
| rpm-traces.c | ||
| synth_event_gen_test.c | ||
| trace_benchmark.c | ||
| trace_benchmark.h | ||
| trace_boot.c | ||
| trace_branch.c | ||
| trace_btf.c | ||
| trace_btf.h | ||
| trace_clock.c | ||
| trace_dynevent.c | ||
| trace_dynevent.h | ||
| trace_entries.h | ||
| trace_eprobe.c | ||
| trace_event_perf.c | ||
| trace_events_filter_test.h | ||
| trace_events_filter.c | ||
| trace_events_hist.c | ||
| trace_events_inject.c | ||
| trace_events_synth.c | ||
| trace_events_trigger.c | ||
| trace_events_user.c | ||
| trace_events.c | ||
| trace_export.c | ||
| trace_fprobe.c | ||
| trace_functions_graph.c | ||
| trace_functions.c | ||
| trace_hwlat.c | ||
| trace_irqsoff.c | ||
| trace_kdb.c | ||
| trace_kprobe_selftest.c | ||
| trace_kprobe_selftest.h | ||
| trace_kprobe.c | ||
| trace_mmiotrace.c | ||
| trace_nop.c | ||
| trace_osnoise.c | ||
| trace_output.c | ||
| trace_output.h | ||
| trace_preemptirq.c | ||
| trace_printk.c | ||
| trace_probe_kernel.h | ||
| trace_probe_tmpl.h | ||
| trace_probe.c | ||
| trace_probe.h | ||
| trace_recursion_record.c | ||
| trace_sched_switch.c | ||
| trace_sched_wakeup.c | ||
| trace_selftest_dynamic.c | ||
| trace_selftest.c | ||
| trace_seq.c | ||
| trace_stack.c | ||
| trace_stat.c | ||
| trace_stat.h | ||
| trace_synth.h | ||
| trace_syscalls.c | ||
| trace_uprobe.c | ||
| trace.c | ||
| trace.h | ||
| tracing_map.c | ||
| tracing_map.h | ||