Commit 368a1d6e authored by Ran Xiaokai's avatar Ran Xiaokai Committed by Xiaomeng Zhang
Browse files

tracing/osnoise: Fix possible recursive locking for cpus_read_lock()

mainline inclusion
from mainline-v6.15-rc1
commit 7e6b3fcc9c5294aeafed0dbe1a09a1bc899bd0f2
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBY77F

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7e6b3fcc9c5294aeafed0dbe1a09a1bc899bd0f2

--------------------------------

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: c8895e27 ("trace/osnoise: Support hotplug operations")
Signed-off-by: default avatarRan Xiaokai <ran.xiaokai@zte.com.cn>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
Conflicts:
	kernel/trace/trace_osnoise.c
[The conflicts were due to some minor issue.]
Signed-off-by: default avatarXiaomeng Zhang <zhangxiaomeng13@huawei.com>
parent 3e1e5bde
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -2038,7 +2038,6 @@ static int start_kthread(unsigned int cpu)

	if (IS_ERR(kthread)) {
		pr_err(BANNER "could not start sampling thread\n");
		stop_per_cpu_kthreads();
		return -ENOMEM;
	}