Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hung_task: add hung_task_sys_info sysctl to dump sys info on task-hung

When task-hung happens, developers may need different kinds of system
information (call-stacks, memory info, locks, etc.) to help debugging.

Add 'hung_task_sys_info' sysctl knob to take human readable string like
"tasks,mem,timers,locks,ftrace,...", and when task-hung happens, all
requested information will be dumped. (refer kernel/sys_info.c for more
details).

Meanwhile, the newly introduced sys_info() call is used to unify some
existing info-dumping knobs.

[feng.tang@linux.alibaba.com: maintain consistecy established behavior, per Lance and Petr]
Link: https://lkml.kernel.org/r/aRncJo1mA5Zk77Hr@U-2FWC9VHC-2323.local
Link: https://lkml.kernel.org/r/20251113111039.22701-3-feng.tang@linux.alibaba.com
Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
Suggested-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: "Paul E . McKenney" <paulmck@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Feng Tang and committed by
Andrew Morton
8b2b9b4f 5f264c00

+33 -12
+5
Documentation/admin-guide/sysctl/kernel.rst
··· 422 422 423 423 This file shows up if ``CONFIG_DETECT_HUNG_TASK`` is enabled. 424 424 425 + hung_task_sys_info 426 + ================== 427 + A comma separated list of extra system information to be dumped when 428 + hung task is detected, for example, "tasks,mem,timers,locks,...". 429 + Refer 'panic_sys_info' section below for more details. 425 430 426 431 hung_task_timeout_secs 427 432 ======================
+28 -12
kernel/hung_task.c
··· 24 24 #include <linux/sched/sysctl.h> 25 25 #include <linux/hung_task.h> 26 26 #include <linux/rwsem.h> 27 + #include <linux/sys_info.h> 27 28 28 29 #include <trace/events/sched.h> 29 30 ··· 60 59 static int __read_mostly sysctl_hung_task_warnings = 10; 61 60 62 61 static int __read_mostly did_panic; 63 - static bool hung_task_show_lock; 64 62 static bool hung_task_call_panic; 65 - static bool hung_task_show_all_bt; 66 63 67 64 static struct task_struct *watchdog_task; 65 + 66 + /* 67 + * A bitmask to control what kinds of system info to be printed when 68 + * a hung task is detected, it could be task, memory, lock etc. Refer 69 + * include/linux/sys_info.h for detailed bit definition. 70 + */ 71 + static unsigned long hung_task_si_mask; 68 72 69 73 #ifdef CONFIG_SMP 70 74 /* ··· 242 236 243 237 if (sysctl_hung_task_panic && total_hung_task >= sysctl_hung_task_panic) { 244 238 console_verbose(); 245 - hung_task_show_lock = true; 246 239 hung_task_call_panic = true; 247 240 } 248 241 ··· 264 259 " disables this message.\n"); 265 260 sched_show_task(t); 266 261 debug_show_blocker(t, timeout); 267 - hung_task_show_lock = true; 268 262 269 - if (sysctl_hung_task_all_cpu_backtrace) 270 - hung_task_show_all_bt = true; 271 263 if (!sysctl_hung_task_warnings) 272 264 pr_info("Future hung task reports are suppressed, see sysctl kernel.hung_task_warnings\n"); 273 265 } ··· 306 304 unsigned long last_break = jiffies; 307 305 struct task_struct *g, *t; 308 306 unsigned long prev_detect_count = sysctl_hung_task_detect_count; 307 + int need_warning = sysctl_hung_task_warnings; 308 + unsigned long si_mask = hung_task_si_mask; 309 309 310 310 /* 311 311 * If the system crashed already then all bets are off, ··· 316 312 if (test_taint(TAINT_DIE) || did_panic) 317 313 return; 318 314 319 - hung_task_show_lock = false; 315 + 320 316 rcu_read_lock(); 321 317 for_each_process_thread(g, t) { 322 318 ··· 332 328 } 333 329 unlock: 334 330 rcu_read_unlock(); 335 - if (hung_task_show_lock) 336 - debug_show_all_locks(); 337 331 338 - if (hung_task_show_all_bt) { 339 - hung_task_show_all_bt = false; 340 - trigger_all_cpu_backtrace(); 332 + if (!(sysctl_hung_task_detect_count - prev_detect_count)) 333 + return; 334 + 335 + if (need_warning || hung_task_call_panic) { 336 + si_mask |= SYS_INFO_LOCKS; 337 + 338 + if (sysctl_hung_task_all_cpu_backtrace) 339 + si_mask |= SYS_INFO_ALL_BT; 341 340 } 341 + 342 + sys_info(si_mask); 342 343 343 344 if (hung_task_call_panic) 344 345 panic("hung_task: blocked tasks"); ··· 442 433 .maxlen = sizeof(unsigned long), 443 434 .mode = 0444, 444 435 .proc_handler = proc_doulongvec_minmax, 436 + }, 437 + { 438 + .procname = "hung_task_sys_info", 439 + .data = &hung_task_si_mask, 440 + .maxlen = sizeof(hung_task_si_mask), 441 + .mode = 0644, 442 + .proc_handler = sysctl_sys_info_handler, 445 443 }, 446 444 }; 447 445