On Fri, Feb 21, 2025 at 11:30:01PM +0900, Masami Hiramatsu (Google) wrote:
+static void debug_show_blocker(struct task_struct *task)- that for_each_process_thread() scope needs { }
+{
+ struct task_struct *g, *t;
+ unsigned long owner;
+ struct mutex *lock;
+
+ lock = READ_ONCE(task->blocker_mutex);
+ if (!lock)
+ return;
+
+ owner = mutex_get_owner(lock);
+ if (likely(owner)) {
+ /* Ensure the owner information is correct. */
+ for_each_process_thread(g, t)
+ if ((unsigned long)t == owner) {
+ pr_err("INFO: task %s:%d is blocked on a mutex owned by task %s:%d.\n",
+ task->comm, task->pid, t->comm, t->pid);
+ sched_show_task(t);
+ return;
+ }
- that for_each_process_thread() loop needs RCU or tasklist_lock
- there is no saying that the owner you read with mutex_get_owner() is
still the owner by the time you do the compare, there can have been
owner changes.