mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
To: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>, Will Deacon <will@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Boqun Feng <boqun.feng@gmail.com>,
	Waiman Long <longman@redhat.com>,
	Joel Granados <joel.granados@kernel.org>,
	Anna Schumaker <anna.schumaker@oracle.com>,
	Lance Yang <ioworker0@gmail.com>,
	Kent Overstreet <kent.overstreet@linux.dev>,
	Yongliang Gao <leonylgao@tencent.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Tomasz Figa <tfiga@chromium.org>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH] hung_task: Dump blocker task if it is not hung
Date: Wed, 30 Jul 2025 18:53:42 +0900	[thread overview]
Message-ID: <175386922226.617855.4016966678697742834.stgit@devnote2> (raw)
In-Reply-To: <20250730175150.af61caf3be97ef4cfbcc4da3@kernel.org>

From: Masami Hiramatsu (Google) <mhiramat@kernel.org>

Dump the lock blocker task if it is not hung because if the blocker
task is also hung, it should be dumped by the detector. This will
de-duplicate the same stackdumps if the blocker task is also blocked
by another task (and hung).

Suggested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
 kernel/hung_task.c |   86 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 49 insertions(+), 37 deletions(-)

diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index d2432df2b905..52d72beb2233 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -94,9 +94,49 @@ static struct notifier_block panic_block = {
 	.notifier_call = hung_task_panic,
 };
 
+static bool task_is_hung(struct task_struct *t, unsigned long timeout)
+{
+	unsigned long switch_count = t->nvcsw + t->nivcsw;
+	unsigned int state;
+
+	/*
+	 * skip the TASK_KILLABLE tasks -- these can be killed
+	 * skip the TASK_IDLE tasks -- those are genuinely idle
+	 */
+	state = READ_ONCE(t->__state);
+	if (!(state & TASK_UNINTERRUPTIBLE) ||
+		(state & TASK_WAKEKILL) ||
+		(state & TASK_NOLOAD))
+		return false;
+
+	/*
+	 * Ensure the task is not frozen.
+	 * Also, skip vfork and any other user process that freezer should skip.
+	 */
+	if (unlikely(READ_ONCE(t->__state) & TASK_FROZEN))
+		return false;
+
+	/*
+	 * When a freshly created task is scheduled once, changes its state to
+	 * TASK_UNINTERRUPTIBLE without having ever been switched out once, it
+	 * musn't be checked.
+	 */
+	if (unlikely(!switch_count))
+		return false;
+
+	if (switch_count != t->last_switch_count) {
+		t->last_switch_count = switch_count;
+		t->last_switch_time = jiffies;
+		return false;
+	}
+	if (time_is_after_jiffies(t->last_switch_time + timeout * HZ))
+		return false;
+
+	return true;
+}
 
 #ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER
-static void debug_show_blocker(struct task_struct *task)
+static void debug_show_blocker(struct task_struct *task, unsigned long timeout)
 {
 	struct task_struct *g, *t;
 	unsigned long owner, blocker, blocker_type;
@@ -153,41 +193,21 @@ static void debug_show_blocker(struct task_struct *task)
 			       task->comm, task->pid, t->comm, t->pid);
 			break;
 		}
-		sched_show_task(t);
+		/* Avoid duplicated task dump, skip if the task is also hung. */
+		if (!task_is_hung(t, timeout))
+			sched_show_task(t);
 		return;
 	}
 }
 #else
-static inline void debug_show_blocker(struct task_struct *task)
+static inline void debug_show_blocker(struct task_struct *task, unsigned long timeout)
 {
 }
 #endif
 
 static void check_hung_task(struct task_struct *t, unsigned long timeout)
 {
-	unsigned long switch_count = t->nvcsw + t->nivcsw;
-
-	/*
-	 * Ensure the task is not frozen.
-	 * Also, skip vfork and any other user process that freezer should skip.
-	 */
-	if (unlikely(READ_ONCE(t->__state) & TASK_FROZEN))
-		return;
-
-	/*
-	 * When a freshly created task is scheduled once, changes its state to
-	 * TASK_UNINTERRUPTIBLE without having ever been switched out once, it
-	 * musn't be checked.
-	 */
-	if (unlikely(!switch_count))
-		return;
-
-	if (switch_count != t->last_switch_count) {
-		t->last_switch_count = switch_count;
-		t->last_switch_time = jiffies;
-		return;
-	}
-	if (time_is_after_jiffies(t->last_switch_time + timeout * HZ))
+	if (!task_is_hung(t, timeout))
 		return;
 
 	/*
@@ -222,7 +242,7 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
 		pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\""
 			" disables this message.\n");
 		sched_show_task(t);
-		debug_show_blocker(t);
+		debug_show_blocker(t, timeout);
 		hung_task_show_lock = true;
 
 		if (sysctl_hung_task_all_cpu_backtrace)
@@ -278,7 +298,6 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
 	hung_task_show_lock = false;
 	rcu_read_lock();
 	for_each_process_thread(g, t) {
-		unsigned int state;
 
 		if (!max_count--)
 			goto unlock;
@@ -287,15 +306,8 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
 				goto unlock;
 			last_break = jiffies;
 		}
-		/*
-		 * skip the TASK_KILLABLE tasks -- these can be killed
-		 * skip the TASK_IDLE tasks -- those are genuinely idle
-		 */
-		state = READ_ONCE(t->__state);
-		if ((state & TASK_UNINTERRUPTIBLE) &&
-		    !(state & TASK_WAKEKILL) &&
-		    !(state & TASK_NOLOAD))
-			check_hung_task(t, timeout);
+
+		check_hung_task(t, timeout);
 	}
  unlock:
 	rcu_read_unlock();


  parent reply	other threads:[~2025-07-30  9:53 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-25  7:02 [PATCH v4 0/2] hung_task: Dump the blocking task stacktrace Masami Hiramatsu (Google)
2025-02-25  7:02 ` [PATCH v4 1/2] hung_task: Show the blocker task if the task is hung on mutex Masami Hiramatsu (Google)
2025-02-26  1:23   ` Waiman Long
2025-03-06  2:32     ` Masami Hiramatsu
     [not found]       ` <5f7bc403-be75-4ae3-b6ff-5ff0673847f9@redhat.com>
2025-03-06  3:10         ` Waiman Long
2025-03-13  3:55           ` Masami Hiramatsu
2025-02-26  1:44   ` Lance Yang
2025-02-26  4:38   ` Sergey Senozhatsky
2025-02-26 15:07     ` Steven Rostedt
2025-03-13 22:29   ` Andrew Morton
2025-03-14  3:57     ` Masami Hiramatsu
2025-07-30  7:59   ` Sergey Senozhatsky
2025-07-30  8:51     ` Masami Hiramatsu
2025-07-30  9:36       ` Lance Yang
2025-07-30 10:01         ` Masami Hiramatsu
2025-07-30 10:42           ` Lance Yang
2025-07-30 10:16         ` Sergey Senozhatsky
2025-07-30 10:40           ` Lance Yang
2025-07-30  9:53       ` Masami Hiramatsu (Google) [this message]
2025-07-30 13:28         ` [RFC PATCH] hung_task: Dump blocker task if it is not hung Sergey Senozhatsky
2025-07-30 13:55           ` Masami Hiramatsu
2025-07-30 13:46         ` Lance Yang
2025-07-30 21:50           ` Masami Hiramatsu
2025-07-30  9:56       ` [PATCH v4 1/2] hung_task: Show the blocker task if the task is hung on mutex Sergey Senozhatsky
2025-07-30  9:22     ` Lance Yang
2025-07-30  9:46       ` Sergey Senozhatsky
2025-02-25  7:02 ` [PATCH v4 2/2] samples: Add hung_task detector mutex blocking sample Masami Hiramatsu (Google)
2025-02-26  1:50   ` Lance Yang
2025-02-26  7:04     ` Masami Hiramatsu
2025-02-26 11:58       ` Lance Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=175386922226.617855.4016966678697742834.stgit@devnote2 \
    --to=mhiramat@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=anna.schumaker@oracle.com \
    --cc=boqun.feng@gmail.com \
    --cc=ioworker0@gmail.com \
    --cc=joel.granados@kernel.org \
    --cc=kent.overstreet@linux.dev \
    --cc=leonylgao@tencent.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=senozhatsky@chromium.org \
    --cc=tfiga@chromium.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®