直接从dmesg提取soft lockup日志,定位cpu编号、卡死时长及对应进程pid;若进程为swapper/0等内核线程,则问题在内核调度或内存管理;结合top、ps、/proc/interrupts交叉验证是否因cpu满载或irq失衡导致;临时调高watchdog_thresh可辅助判断是否误报,但持续触发需深入查硬件或内核。

怎么看日志定位具体卡在哪颗 CPU 和哪个进程
直接从 dmesg 里捞出最新几条 soft lockup 记录,重点看三块信息:CPU#X、stuck for Ys、[xxx:pid]。比如 kernel: BUG: soft lockup - CPU#3 stuck for 24s! [java:1289] 就说明是第 3 号逻辑 CPU 被 PID 1289 的 java 进程卡了 24 秒。
执行命令快速提取:
dmesg -T | grep "soft lockup" -A 1 -B 1 | tail -20
注意:如果 [xxx:pid] 显示的是 swapper/0:1 或 migration/X 这类内核线程,说明问题不在用户进程,而是内核调度或内存管理机制本身出了状况(比如 stop_machine 在内存压力下卡住)。
怎么确认是不是 CPU 长期满载导致的假性卡死
soft lockup 不一定代表硬件故障,90% 的线上案例是 CPU 持续 100% 占用 + 内核调度响应延迟叠加触发的。先别急着调参,用这几个命令交叉验证:
-
top -c -b -n 1 | head -20:看有没有单个进程长期占满某个 CPU 核心(不是平均负载高,而是某核持续 99%+) -
ps -eo pid,ppid,comm,%cpu,psr --sort=-%cpu | head -10:按 CPU 占用倒序列出前 10 进程,并显示它绑定在哪个 CPU 上(psr列) -
cat /proc/interrupts | head -20:检查中断是否集中在某颗 CPU(如IO-APIC-fasteoi行数值远高于其他行),说明 IRQ 不平衡,可能压垮单核
如果发现 Java 或 MySQL 进程长期绑定在 CPU#3 且占用率 99%,而 /proc/interrupts 里 CPU#3 的中断数也异常高,基本可以锁定是资源争抢而非内核 bug。
怎么临时缓解并验证是不是 watchdog_thresh 太敏感
默认 watchdog_thresh 是 10,对应 soft lockup 触发阈值为 20 秒。在低配环境(比如 2 核虚拟机跑 Docker+SpringBoot+MySQL)下,这个值太激进,容易误报。
临时调高阈值验证(不重启):
echo 30 > /proc/sys/kernel/watchdog_thresh
这会让 soft lockup 触发门槛变成 60 秒,给内核调度更多喘息空间。但注意:
- 这只是诊断手段,不是修复方案——如果调到 30 后还报,说明真有问题;如果不再报,大概率是负载压垮了调度器
- 该设置重启失效,要永久生效需写入
/etc/sysctl.conf:添加kernel.watchdog_thresh = 30,再运行sysctl -p - 别设成 60 以上,否则可能掩盖真实死循环或自旋锁卡死
哪些情况不能只靠调阈值,必须深入查硬件或内核
当出现以下任一现象时,说明已超出配置调整范畴,得往下挖:
-
[swapper/0:1]或[kthreadd:2]这类纯内核线程被卡住,且伴随oom-killer日志同时出现 → 很可能是内存 cgroup 压力触发stop_machine死锁 - 同一台机器反复在不同 CPU 上报 soft lockup,且
smartctl -a /dev/sda显示重映射扇区增长、lm_sensors显示 CPU 温度 >95°C → 硬件级不稳定 - 调高
watchdog_thresh后仍频繁报错,且perf top -e 'syscalls:sys_enter_*'显示大量sys_enter_futex或sys_enter_epoll_wait→ 应用层存在高频锁竞争或阻塞式系统调用
真正棘手的点往往藏在「软锁死」和「硬中断失效」之间的灰色地带:比如某块 NVMe SSD 固件缺陷导致 DMA 完成中断延迟,既没触发 hard lockup,又让 watchdog 反复报警。这时候看 /proc/sys/kernel/nmi_watchdog 是否为 1,再配合 perf record -e irq:irq_handler_entry -a sleep 30 抓中断延迟,才能逼近真相。











