From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F9BC2F25F5 for ; Mon, 2 Feb 2026 06:10:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770012616; cv=none; b=AX7JppuU4Szz8Nq78W4UQCV5O++3x0nU7IHUVR1cgcIfBUjZqTr6xoAtErS8uo0ENcvo1jtnWUmmsfHG6vbWucDf9rexedSKmwt7zrLzCn5GDcZ6imj7T5O3bW9mDHNBnncxQb219qIwBQ1IRjf4p24KNLT881MjUK2mT4lf/ys= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770012616; c=relaxed/simple; bh=YvG9lhPD8bK9UVhnjYWGVNNB3z9Q8Yl1H/JwnCGZ3KY=; h=Date:From:To:Cc:Subject:Message-Id:In-Reply-To:References: Mime-Version:Content-Type; b=NjFS8yTvZeg2GnvebP+D8YW1zrOARs7PBna/GLNKWrcsL6DwPxTKBEYMdHrD1ru+bZ62fH543yAH6P20Blf1oQEha6ToPPbOLxOg/VB9yb4HqpC6sSpbXp9hkQ7XblMrMNj52+kmovfPAdfAiix5zqk/I2lQu3KKGOFa22H49RE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qcQ01/nl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qcQ01/nl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B13AAC19421; Mon, 2 Feb 2026 06:10:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770012616; bh=YvG9lhPD8bK9UVhnjYWGVNNB3z9Q8Yl1H/JwnCGZ3KY=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=qcQ01/nlgDw3mGKfIOSB8x5ovDHF55BtjZ6wMXmtWRqXW8/e8YKMEDQt3HrfKE5se ffW+gereBUMo6+gzNsu+grUUmTsVMtfgSteIFqmZFvh4fDduHpdNpXX/O1L5njMVvo h5dxmKfBvBorpiPEk3wPgNVnQJUQrG6t9YxbO+pM/Uq8FZpf9YTHk9K6es+Hj3gSoQ XdAcXTV9zVxNTw6d9yl4zhnGfwLcqqkUYTzEVSaWxVu5nRjN3uBtDfKa3OzZf9Fcjg XAnIDY20Ka1Qi8pAZ8Ah3dsF5wT2iVg6WDvEPNO/70TwtmagDK5PfbmHOO9UvSa+3+ xz4V3zvMiiYQA== Date: Mon, 2 Feb 2026 15:10:11 +0900 From: Masami Hiramatsu (Google) To: Aaron Tomlin Cc: akpm@linux-foundation.org, lance.yang@linux.dev, gregkh@linuxfoundation.org, pmladek@suse.com, joel.granados@kernel.org, neelx@suse.com, sean@ashe.io, mproche@gmail.com, chjohnst@gmail.com, nick.lange@gmail.com, linux-kernel@vger.kernel.org Subject: Re: [v7 PATCH 1/2] hung_task: Refactor detection logic and atomicise detection count Message-Id: <20260202151011.92cee5b0f8356a90c09a4992@kernel.org> In-Reply-To: <20260125135848.3356585-2-atomlin@atomlin.com> References: <20260125135848.3356585-1-atomlin@atomlin.com> <20260125135848.3356585-2-atomlin@atomlin.com> X-Mailer: Sylpheed 3.8.0beta1 (GTK+ 2.24.33; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Sun, 25 Jan 2026 08:58:47 -0500 Aaron Tomlin wrote: > The check_hung_task() function currently conflates two distinct > responsibilities: validating whether a task is hung and handling the > subsequent reporting (printing warnings, triggering panics, or > tracepoints). > > This patch refactors the logic by introducing hung_task_info(), a > function dedicated solely to reporting. The actual detection check, > task_is_hung(), is hoisted into the primary loop within > check_hung_uninterruptible_tasks(). This separation clearly decouples > the mechanism of detection from the policy of reporting. > > Furthermore, to facilitate future support for concurrent hung task > detection, the global sysctl_hung_task_detect_count variable is > converted from unsigned long to atomic_long_t. Consequently, the > counting logic is updated to accumulate the number of hung tasks locally > (this_round_count) during the iteration. The global counter is then > updated atomically via atomic_long_cmpxchg_relaxed() once the loop > concludes, rather than incrementally during the scan. > > These changes are strictly preparatory and introduce no functional > change to the system's runtime behaviour. > > Signed-off-by: Aaron Tomlin Looks good to me. Reviewed-by: Masami Hiramatsu (Google) Thanks, > --- > kernel/hung_task.c | 58 ++++++++++++++++++++++++++-------------------- > 1 file changed, 33 insertions(+), 25 deletions(-) > > diff --git a/kernel/hung_task.c b/kernel/hung_task.c > index d2254c91450b..df10830ed9ef 100644 > --- a/kernel/hung_task.c > +++ b/kernel/hung_task.c > @@ -36,7 +36,7 @@ static int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; > /* > * Total number of tasks detected as hung since boot: > */ > -static unsigned long __read_mostly sysctl_hung_task_detect_count; > +static atomic_long_t sysctl_hung_task_detect_count = ATOMIC_LONG_INIT(0); > > /* > * Limit number of tasks checked in a batch. > @@ -223,31 +223,29 @@ static inline void debug_show_blocker(struct task_struct *task, unsigned long ti > } > #endif > > -static void check_hung_task(struct task_struct *t, unsigned long timeout, > - unsigned long prev_detect_count) > +/** > + * hung_task_info - Print diagnostic details for a hung task > + * @t: Pointer to the detected hung task. > + * @timeout: Timeout threshold for detecting hung tasks > + * @this_round_count: Count of hung tasks detected in the current iteration > + * > + * Print structured information about the specified hung task, if warnings > + * are enabled or if the panic batch threshold is exceeded. > + */ > +static void hung_task_info(struct task_struct *t, unsigned long timeout, > + unsigned long this_round_count) > { > - unsigned long total_hung_task; > - > - if (!task_is_hung(t, timeout)) > - return; > - > - /* > - * This counter tracks the total number of tasks detected as hung > - * since boot. > - */ > - sysctl_hung_task_detect_count++; > - > - total_hung_task = sysctl_hung_task_detect_count - prev_detect_count; > trace_sched_process_hang(t); > > - if (sysctl_hung_task_panic && total_hung_task >= sysctl_hung_task_panic) { > + if (sysctl_hung_task_panic && this_round_count >= sysctl_hung_task_panic) { > console_verbose(); > hung_task_call_panic = true; > } > > /* > - * Ok, the task did not get scheduled for more than 2 minutes, > - * complain: > + * The given task did not get scheduled for more than > + * CONFIG_DEFAULT_HUNG_TASK_TIMEOUT. Therefore, complain > + * accordingly > */ > if (sysctl_hung_task_warnings || hung_task_call_panic) { > if (sysctl_hung_task_warnings > 0) > @@ -297,18 +295,18 @@ static bool rcu_lock_break(struct task_struct *g, struct task_struct *t) > > /* > * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for > - * a really long time (120 seconds). If that happens, print out > - * a warning. > + * a really long time. If that happens, print out a warning. > */ > static void check_hung_uninterruptible_tasks(unsigned long timeout) > { > int max_count = sysctl_hung_task_check_count; > unsigned long last_break = jiffies; > struct task_struct *g, *t; > - unsigned long prev_detect_count = sysctl_hung_task_detect_count; > + unsigned long total_count, this_round_count; > int need_warning = sysctl_hung_task_warnings; > unsigned long si_mask = hung_task_si_mask; > > + total_count = atomic_long_read(&sysctl_hung_task_detect_count); > /* > * If the system crashed already then all bets are off, > * do not report extra hung tasks: > @@ -316,10 +314,9 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) > if (test_taint(TAINT_DIE) || did_panic) > return; > > - > + this_round_count = 0; > rcu_read_lock(); > for_each_process_thread(g, t) { > - > if (!max_count--) > goto unlock; > if (time_after(jiffies, last_break + HUNG_TASK_LOCK_BREAK)) { > @@ -328,14 +325,25 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) > last_break = jiffies; > } > > - check_hung_task(t, timeout, prev_detect_count); > + if (task_is_hung(t, timeout)) { > + this_round_count++; > + hung_task_info(t, timeout, this_round_count); > + } > } > unlock: > rcu_read_unlock(); > > - if (!(sysctl_hung_task_detect_count - prev_detect_count)) > + if (!this_round_count) > return; > > + /* > + * This counter tracks the total number of tasks detected as hung > + * since boot. > + */ > + atomic_long_cmpxchg_relaxed(&sysctl_hung_task_detect_count, > + total_count, total_count + > + this_round_count); > + > if (need_warning || hung_task_call_panic) { > si_mask |= SYS_INFO_LOCKS; > > -- > 2.51.0 > -- Masami Hiramatsu (Google)