All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aaron Tomlin <atomlin@atomlin.com>
To: akpm@linux-foundation.org, lance.yang@linux.dev,
	mhiramat@kernel.org, gregkh@linuxfoundation.org,
	pmladek@suse.com, joel.granados@kernel.org
Cc: sean@ashe.io, linux-kernel@vger.kernel.org
Subject: [v6 PATCH 1/2] hung_task: Convert detection count to atomic_long_t
Date: Wed, 14 Jan 2026 21:32:28 -0500	[thread overview]
Message-ID: <20260115023229.3028462-2-atomlin@atomlin.com> (raw)
In-Reply-To: <20260115023229.3028462-1-atomlin@atomlin.com>

To facilitate the future introduction of a runtime reset mechanism for
the hung task detector, it is necessary to manage
sysctl_hung_task_detect_count via atomic operations. This ensures that
concurrent modifications - specifically between the khungtaskd kernel
thread and potential future user-space writers - are handled safely
without the requirement for heavyweight locking.

Consequently, this patch converts the variable from unsigned long to
atomic_long_t. Accordingly, the increment logic within check_hung_task()
is updated to utilise atomic_long_inc_return_relaxed().

Furthermore, a custom proc_handler, proc_dohung_task_detect_count(), is
introduced to bridge the interface between the atomic variable and the
standard sysctl infrastructure. Note that as the sysctl entry retains
its read-only permission (0444) within the scope of this commit, the
handler implementation is currently restricted to read operations via a
proxy variable. The logic requisite for handling user-space writes is
reserved for a subsequent patch which will formally enable the reset
capability.

Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
 kernel/hung_task.c | 45 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 9 deletions(-)

diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index d2254c91450b..b5ad7a755eb5 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -17,6 +17,7 @@
 #include <linux/export.h>
 #include <linux/panic_notifier.h>
 #include <linux/sysctl.h>
+#include <linux/atomic.h>
 #include <linux/suspend.h>
 #include <linux/utsname.h>
 #include <linux/sched/signal.h>
@@ -36,7 +37,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.
@@ -224,9 +225,9 @@ 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)
+			    unsigned long prev_detect_count)
 {
-	unsigned long total_hung_task;
+	unsigned long total_hung_task, cur_detect_count;
 
 	if (!task_is_hung(t, timeout))
 		return;
@@ -235,9 +236,9 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout,
 	 * This counter tracks the total number of tasks detected as hung
 	 * since boot.
 	 */
-	sysctl_hung_task_detect_count++;
+	cur_detect_count = atomic_long_inc_return_relaxed(&sysctl_hung_task_detect_count);
+	total_hung_task = cur_detect_count - prev_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) {
@@ -305,10 +306,11 @@ 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 prev_detect_count;
 	int need_warning = sysctl_hung_task_warnings;
 	unsigned long si_mask = hung_task_si_mask;
 
+	prev_detect_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:
@@ -333,7 +335,8 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
  unlock:
 	rcu_read_unlock();
 
-	if (!(sysctl_hung_task_detect_count - prev_detect_count))
+	if (!(atomic_long_read(&sysctl_hung_task_detect_count) -
+				prev_detect_count))
 		return;
 
 	if (need_warning || hung_task_call_panic) {
@@ -358,6 +361,31 @@ static long hung_timeout_jiffies(unsigned long last_checked,
 }
 
 #ifdef CONFIG_SYSCTL
+
+/**
+ * proc_dohung_task_detect_count - proc handler for hung_task_detect_count
+ * @table: Pointer to the struct ctl_table definition for this proc entry
+ * @dir: Flag indicating the operation
+ * @buffer: User space buffer for data transfer
+ * @lenp: Pointer to the length of the data being transferred
+ * @ppos: Pointer to the current file offset
+ *
+ * This handler is used for reading the current hung task detection count.
+ * Returns 0 on success or a negative error code on failure.
+ */
+static int proc_dohung_task_detect_count(const struct ctl_table *table, int dir,
+					 void *buffer, size_t *lenp, loff_t *ppos)
+{
+	unsigned long detect_count;
+	struct ctl_table proxy_table;
+
+	detect_count = atomic_long_read(&sysctl_hung_task_detect_count);
+	proxy_table = *table;
+	proxy_table.data = &detect_count;
+
+	return proc_doulongvec_minmax(&proxy_table, dir, buffer, lenp, ppos);
+}
+
 /*
  * Process updating of timeout sysctl
  */
@@ -438,10 +466,9 @@ static const struct ctl_table hung_task_sysctls[] = {
 	},
 	{
 		.procname	= "hung_task_detect_count",
-		.data		= &sysctl_hung_task_detect_count,
 		.maxlen		= sizeof(unsigned long),
 		.mode		= 0444,
-		.proc_handler	= proc_doulongvec_minmax,
+		.proc_handler	= proc_dohung_task_detect_count,
 	},
 	{
 		.procname	= "hung_task_sys_info",
-- 
2.51.0


  reply	other threads:[~2026-01-15  2:32 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-15  2:32 [v6 PATCH 0/2] hung_task: Provide runtime reset interface for hung task detector Aaron Tomlin
2026-01-15  2:32 ` Aaron Tomlin [this message]
2026-01-15  2:32 ` [v6 PATCH 2/2] hung_task: Enable runtime reset of hung_task_detect_count Aaron Tomlin
2026-01-15  3:06   ` Lance Yang
2026-01-15 18:24     ` Aaron Tomlin
2026-01-16  2:10       ` Lance Yang
2026-01-15  3:24 ` [v6 PATCH 0/2] hung_task: Provide runtime reset interface for hung task detector Lance Yang
2026-01-15 18:18   ` Aaron Tomlin
2026-01-16  2:22     ` Lance Yang
2026-01-20  9:46       ` Petr Mladek
2026-01-20 11:48         ` Lance Yang
2026-01-23  0:59         ` Aaron Tomlin

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=20260115023229.3028462-2-atomlin@atomlin.com \
    --to=atomlin@atomlin.com \
    --cc=akpm@linux-foundation.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=joel.granados@kernel.org \
    --cc=lance.yang@linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=pmladek@suse.com \
    --cc=sean@ashe.io \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.