【Linux 维测专栏 1 -- Hung Task 分析与验证】

发布于:2025-03-23 ⋅ 阅读:(24) ⋅ 点赞:(0)

Linux Hung Task 简介

1. Hung Task 概述

Hung Task 是 Linux 内核中的一个检测机制,用于监控长时间处于 D 状态(不可中断睡眠状态) 的任务(进程或线程)。如果某个任务在 D 状态停留时间过长,内核会认为该任务可能已经“挂起”(Hung),并触发相应的警告或调试信息,帮助开发者定位问题。

2. D 状态与 Hung Task

  • D 状态(不可中断睡眠状态)
    任务在等待某些内核资源(如 I/O 操作、锁等)时进入 D 状态。
    在 D 状态的任务不会响应信号(如 SIGKILL),因此无法被强制终止。
    如果任务长时间处于 D 状态,可能会导致系统性能下降或死锁。

  • Hung Task 检测
    Hung Task 机制会定期扫描系统中的任务,检查是否有任务在 D 状态停留时间超过预设阈值。
    如果检测到 Hung Task,内核会记录相关信息(如任务名称、PID、堆栈跟踪等),并触发警告。

3. Hung Task 的工作原理

  • 初始化
    在内核启动时,Hung Task 检测机制会初始化一个内核线程(khungtaskd),用于定期扫描系统中的任务。

  • 任务扫描
    khungtaskd 线程会定期(默认每 120 秒)遍历所有任务,检查其状态和处于 D 状态的时间。

  • 阈值判断
    如果某个任务在 D 状态的时间超过预设阈值(默认 120 秒),则判定为 Hung Task。

  • 触发警告
    内核会记录 Hung Task 的详细信息,包括:

    • 任务名称和 PID。
    • 任务的堆栈跟踪。

这些信息会通过内核日志(dmesg)输出,便于开发者分析。

4. Hung Task 的配置

Hung Task 的行为可以通过以下内核参数进行配置:

  • hung_task_timeout_secs
    定义任务在 D 状态的最大允许时间(单位:秒)。
    默认值:120 秒。
    示例:hung_task_timeout_secs=60。

  • hung_task_panic
    如果设置为 1,当检测到 Hung Task 时,内核会直接触发 panic。
    默认值:0(仅记录警告,不触发 panic)。
    示例:hung_task_panic=1。

  • hung_task_check_count
    定义每次扫描时检查的任务数量。
    默认值:1024。
    示例hung_task_check_count=2048

  • hung_task_warnings
    定义最大警告次数。超过该次数后,不再记录 Hung Task 警告。
    默认值:10。
    示例hung_task_warnings=5

5. Hung Task 的典型输出

当检测到 Hung Task 时,内核日志中会输出类似以下信息:

INFO: task mytask:1234 blocked for more than 120 seconds.
      Tainted: G           OE
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
mytask      D ffffffff810a3b80     0  1234   1233 0x00000000
Call Trace:
 [<ffffffff810a3b80>] ? __schedule+0x320/0x8c0
 [<ffffffff810a3b80>] ? __schedule+0x320/0x8c0
 [<ffffffff810a3b80>] ? __schedule+0x320/0x8c0
  • 任务名称:mytask。
  • PID:1234。
  • 阻塞时间:超过 120 秒。
  • 堆栈跟踪:显示任务在内核中的调用路径。

6. Hung Task 的应用场景

  • 调试死锁
    当任务因竞争锁资源而进入 D 状态时,Hung Task 可以帮助定位死锁问题。

  • 分析 I/O 问题:
    如果任务因等待 I/O 操作而挂起,Hung Task 可以提供堆栈信息,帮助分析 I/O 瓶颈。

  • 系统性能监控:
    通过 Hung Task 检测,可以及时发现系统中的异常任务,避免系统性能下降。

7. kernel 配置

7.1 编译选项

# hung task
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=30
CONFIG_TEST_LOCKUP=m

7.2 参数控制

hung_task参数控制节点:/proc/sys/kernel/

hung_task_all_cpu_backtrace       // 打印所有core的调用栈
hung_task_panic                   // hung task触发panic
hung_task_check_count             //一次check 多少进程
hung_task_timeout_secs            // hung task 判断标准
hung_task_check_interval_secs     // khungd隔多久检查一次,取 和 hung_task_timeout_secs    比较的最小值
hung_task_warnings                // warnings 次数

7.3 验证方法

验证命令

echo 1 > /proc/sys/kernel/hung_task_all_cpu_backtrace
echo 20 > /proc/sys/kernel/hung_task_timeout_secs
modprobe test_lockup time_secs=100 iterations=40 state=D

在这里插入图片描述

4. 扩展接口

编译打开:CONFIG_DETECT_HUNG_TASK_EXT

echo on > /sys/kernel/hung_task/enable      // 打开ext
echo "whitelist,xxx" > /sys/kernel/hung_task/monitorlist   // 添加白名单程序,格式:whitelist,xxx,yyy,zzz

8. 注意事项

  • 性能开销:
    Hung Task 检测会定期扫描任务列表,可能对系统性能产生一定影响。在高负载系统中,建议根据实际情况调整检测频率。

  • 误报问题:
    某些任务可能因长时间等待合法资源而处于 D 状态,导致误报。需要结合具体场景分析。

通过 Hung Task 机制,Linux 内核能够有效监控系统中的异常任务,帮助开发者快速定位和解决系统挂起问题。