On Tue, 24 Mar 2026 15:06:16 +0800 (CST) <[email protected]> wrote:
> From: luohaiyang10243395 <[email protected]> > > The following sequence may leads deadlock in cpu hotplug: > > CPU0 | CPU1 > | schedule_work_on > | > _cpu_down//set CPU1 offline | > cpus_write_lock | > | osnoise_hotplug_workfn > | mutex_lock(&interface_lock); > | cpus_read_lock(); //wait cpu_hotplug_lock > | > | cpuhp/1 > | osnoise_cpu_die > | kthread_stop > | wait_for_completion //wait osnoise/1 > exit > | > | osnoise/1 > | osnoise_sleep > | mutex_lock(&interface_lock); //deadlock > > Fix by swap the order of cpus_read_lock() and mutex_lock(&interface_lock). So the deadlock is due to the "wait_for_completion"? How did you find this bug? Inspection, AI, triggered? Thanks, -- Steve > > Signed-off-by: Luo Haiyang <[email protected]> > --- > kernel/trace/trace_osnoise.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c > index dee610e465b9..be6cf0bb3c03 100644 > --- a/kernel/trace/trace_osnoise.c > +++ b/kernel/trace/trace_osnoise.c > @@ -2073,8 +2073,8 @@ static void osnoise_hotplug_workfn(struct work_struct > *dummy) > if (!osnoise_has_registered_instances()) > return; > > - guard(mutex)(&interface_lock); > guard(cpus_read_lock)(); > + guard(mutex)(&interface_lock); > > if (!cpu_online(cpu)) > return; > @@ -2237,11 +2237,11 @@ static ssize_t osnoise_options_write(struct file > *filp, const char __user *ubuf, > if (running) > stop_per_cpu_kthreads(); > > - mutex_lock(&interface_lock); > /* > * avoid CPU hotplug operations that might read options. > */ > cpus_read_lock(); > + mutex_lock(&interface_lock); > > retval = cnt; > > @@ -2257,8 +2257,8 @@ static ssize_t osnoise_options_write(struct file *filp, > const char __user *ubuf, > clear_bit(option, &osnoise_options); > } > > - cpus_read_unlock(); > mutex_unlock(&interface_lock); > + cpus_read_unlock(); > > if (running) > start_per_cpu_kthreads(); > @@ -2345,16 +2345,16 @@ osnoise_cpus_write(struct file *filp, const char > __user *ubuf, size_t count, > if (running) > stop_per_cpu_kthreads(); > > - mutex_lock(&interface_lock); > /* > * osnoise_cpumask is read by CPU hotplug operations. > */ > cpus_read_lock(); > + mutex_lock(&interface_lock); > > cpumask_copy(&osnoise_cpumask, osnoise_cpumask_new); > > - cpus_read_unlock(); > mutex_unlock(&interface_lock); > + cpus_read_unlock(); > > if (running) > start_per_cpu_kthreads();
