hardlockup && softlockup && hungtask
这三者是 Linux 内核在不同层面上的 "卡死"检测机制 ,主要区别在于 故障表现、影响范围和检测手段 :
1. Soft Lockup(软死锁)
核心特征:CPU 在"干活"但"不调度"
| 维度 | 说明 |
|---|---|
| 状态 | 某个 CPU 长时间(默认 20s)执行内核代码,不调用 schedule() 释放 CPU |
| 中断 | ✅ 正常响应(timer tick 仍能触发) |
| 抢占 | ❌ 可能禁用了抢占,或陷入死循环 |
| 症状 | 系统部分卡顿,其他 CPU 可能正常,SSH 可能能连接但响应慢 |
典型场景:
// 1. 长时间关闭抢占
preempt_disable();
while (1); // 死循环,但不会触发硬死锁
// 2. 计算密集型内核操作(如过大的 hash table 遍历)
// 3. spin_lock 持有者被抢占(CONFIG_PREEMPT 关闭时)
检测原理:
每个 CPU 有一个高优先级的 watchdog/x 线程,定期(每秒)更新时间戳。如果某个 CPU 的 watchdog 线程超过 watchdog_thresh(默认 20s)未运行,则触发 soft lockup。
# 日志特征
softlockup: hung tasks: 123
Watchdog detected hard LOCKUP on cpu 0 # 注意:这里实际指 soft lockup
2. Hard Lockup(硬死锁)
核心特征:CPU 连中断都不响应了
| 维度 | 说明 |
|---|---|
| 状态 | CPU 长时间(默认 20-40s)关闭中断,定时器中断无法处理 |
| 中断 | ❌ 被屏蔽(local_irq_disable() 或 spin_lock_irq) |
| 抢占 | 通常也禁用 |
| 症状 | 该 CPU 完全冻结,系统时钟停止,网络中断(若在该 CPU),可能触发 NMI panic |
典型场景:
// 1. 长时间持有关中断锁
spin_lock_irq(&lock);
msleep(100000); // 在 atomic 上下文睡眠(严重 bug)
spin_unlock_irq(&lock);
// 2. 中断处理程序死循环
irq_handler() {
while (1); // 永远出不去
}
检测原理:
必须使用 NMI(不可屏蔽中断),因为普通 timer 中断已被屏蔽。NMI watchdog(perf 硬件或 lapic)定期检查每个 CPU 的 hrtimer_interrupts 计数,若长时间未增加则判定为 hard lockup。
# 日志特征
Watchdog detected hard LOCKUP on cpu 2
RIP: 0010:buggy_function+0x45/0x80 # 显示卡死的指令地址
3. Hung Task(任务挂起)
核心特征:进程卡在不可中断睡眠(D 状态)
| 维度 | 说明 |
|---|---|
| 范围 | 进程级别(非 CPU 级别) |
| 状态 | 进程长时间(默认 120s)处于 TASK_UNINTERRUPTIBLE(D 状态) |
| 中断 | ✅ CPU 正常,中断正常,调度正常 |
| 症状 | 单个进程无法 kill(包括 kill -9),ps 看到 STAT 为 D,系统可能仍可用 |
典型场景:
// 1. I/O 死锁:等待磁盘响应但控制器已挂
vfs_read() -> ... -> scsi_execute() -> wait_for_completion(D状态)
// 2. 网络文件系统(NFS)故障,服务器不可达
// 3. 驱动 bug:忘记 wake_up() 等待队列
检测原理:
内核线程 khungtaskd 定期(每 2 秒)扫描所有 D 状态进程,检查 task->timestamp(进入 D 状态的时间)。若超过 hung_task_timeout_secs(默认 120s),则打印警告。
# 日志特征
INFO: task kworker/u16:2:12345 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
kworker/u16:2 D 0 12345 2 0x80000000
Call Trace:
__schedule+0x2a1/0x850
schedule+0x46/0xb0
...
对比总结
| 特性 | Soft Lockup | Hard Lockup | Hung Task |
|---|---|---|---|
| 检测对象 | CPU 核心 | CPU 核心 | 单个进程 |
| 中断状态 | 开启 | 关闭 | 开启 |
| 调度状态 | 不调度 | 不调度 | 被调度但睡眠 |
| 能否 kill -9 | N/A(CPU 问题) | N/A | 不能(D 状态) |
| 检测器 | watchdog/x 线程 |
NMI 硬件 | khungtaskd 线程 |
| 默认超时 | 20s | 20-40s(2×soft) | 120s |
| 触发 panic | 可选 | 可选(建议开启) | 可选(通常不开启) |
| 典型原因 | 死循环、大锁、算法复杂度过高 | 关中断锁死循环、中断 handler bug | I/O 死锁、驱动 wait_event 未唤醒 |
配置参数
# /etc/sysctl.conf 或 /proc/sys/kernel/
# Soft lockup
kernel.watchdog = 1 # 总开关(同时控制 soft/hard)
kernel.watchdog_thresh = 20 # 超时秒数
# Hard lockup(依赖 soft lockup 开启)
kernel.nmi_watchdog = 1 # 1=启用, 0=禁用
kernel.hardlockup_panic = 1 # 检测到时是否 panic(建议生产环境开启)
# Hung task
kernel.hung_task_timeout_secs = 120 # 0=禁用检测
kernel.hung_task_panic = 0 # 是否 panic(通常保持 0,仅记录)
kernel.hung_task_check_count = 4194304 # 每次检查的最大进程数
调试建议
-
Soft Lockup:
- 查看
RIP(指令指针)定位死循环位置 - 检查是否禁用抢占过久或算法复杂度问题
- 查看
-
Hard Lockup:
- 必须依赖 NMI,确保 BIOS 未禁用 perf/NMI
- 通常是
spin_lock_irq滥用或中断 handler 问题 - 若看到
RIP: _raw_spin_lock_irq+...说明关中断锁导致
-
Hung Task:
- 查看 Call Trace 中的
wait_for_completion或schedule_timeout - 通常是块设备、网络存储或自定义驱动的问题
- 可尝试
echo > /sys/block/sda/device/delete强制删除设备(可能恢复)
- 查看 Call Trace 中的
严重程度:Hard Lockup > Soft Lockup > Hung Task,但 Hung Task 最隐蔽(系统看似正常)。

浙公网安备 33010602011771号