dmesg本身不能直接确认进程D状态,但可通过hung task报告(如“blocked for more than 120 seconds”)和I/O错误日志(如“I/O error”“controller is down”)定位D进程的阻塞原因与持续时间,需结合ps或/proc/PID/status验证。

直接看 dmesg 本身不能确认某个具体进程是否处于 D 状态,但它能提供关键佐证:当进程因底层 I/O 或驱动异常长期卡在不可中断等待时,内核会主动记录超时事件和阻塞线索。真正判断 D 状态要靠 ps 或 /proc/PID/status,而 dmesg 的作用是帮你锁定“为什么卡”以及“卡得有多久”。
dmesg 中识别 D 状态进程的典型线索
hung task 报告是最直接信号
执行dmesg -T | grep -i "blocked for more than",若看到类似:INFO: task rsync:12345 blocked for more than 120 seconds.
这说明内核已检测到 PID 12345 的进程持续处于 D 状态超 2 分钟,并主动告警。该行后通常紧跟着其内核调用栈(如nfs_wait_bit_killable、__nvme_submit_cmd),可直接定位阻塞点。-
I/O 错误日志与 D 状态高度相关
进程陷入 D 状态往往伴随设备无响应,dmesg里会出现:-
end_request: I/O error, dev sdb, sector 123456 -
nvme 0000:01:00.0: controller is down -
ata2.00: failed command: READ FPDMA QUEUED -
rejecting I/O to offline device
这些不是进程状态本身,但只要它们出现在 hung task 日志之前或同期,基本可断定 D 进程正在等这个失败的设备。
-
HBA/光纤链路中断日志指向批量 D 进程
若是存储光纤挂断,dmesg常见输出:qla2xxx 0000:04:00.0: Link downlpfc 0000:05:00.0: Loss of Signalfcp: fcp_cmd timeout
此时多个进程(尤其是访问对应 LUN 的)会集体变 D,dmesg时间戳能帮你确认故障起始时间,再反查ps当时的 D 进程列表。
如何联动 dmesg 和进程状态交叉验证
- 先用
dmesg -T | tail -50找出最近一条 hung task 或 I/O error 的时间(比如[Mon Jul 20 19:42:33 2026]) - 再执行
ps -eo pid,comm,state,etimes,wchan --sort=-etimes | awk '$3 ~ /^D$/',筛选出etimes(调度延迟秒数)大的 D 进程 - 对比两者时间是否接近:若某 D 进程的
etimes值 ≈dmesg中 hung task 的阻塞时长(如 138 秒),且wchan显示nfs_wait_event或blk_mq_do_dispatch_sched,基本闭环。
注意 dmesg 的局限性
- 它不显示进程名、PID 或当前状态码,仅反映内核视角的“异常事件”
- 没有 hung task 或 I/O error 日志,不代表没有 D 进程——可能阻塞时间尚短(<120 秒),或设备未触发内核报错(如某些 NFS 软挂载会静默重试)
- 若
dmesg干净但ps查到大量 D 进程,应立刻查/proc/PID/io的read_bytes/write_bytes是否增长,再结合iotop -o看实时 IO 流量
不复杂但容易忽略:dmesg 是诊断 D 状态的“听诊器”,不是“体温计”。它告诉你“身体某处出了问题”,而 ps 和 /proc 才告诉你“谁病了、病得多重”。

















