.. _debug_d_process:
==============================
排查Linux D住进程原因
==============================
查询僵尸和D进程
==================
僵尸进程 ``zombie`` 是虽然不占用资源,但是表明系统有不正常的资源回收问题。
根据经验,我们知道Linux中有一种状态为 ``D`` 的进程,会阻塞CPU使用(因为CPU需要等待设备返回,例如等待磁盘),所以我们检查一下系统是否存在 ``D`` 进程::
ps r -A
可以看到如下进程::
PID TTY STAT TIME COMMAND
...
932 ? D 78:08 [load_calc]
32180 ? Dl 49:37 /opt/taobao/java/bin/java -classpath /opt/flink/conf:/opt/flink/lib/blink-launcher-blink-3.4.3-SNAPSHOT.jar:/opt/flink/lib/blink-metrics-ceresdb-blink-3.4.3-SNAPSHOT.jar:/opt/flink/lib/blink-pangu-fs-blink-3.4.3-SNAPSHOT.jar:/opt/flink/lib/blink-statebackend-antkv_2.11-blink-3.4.3-SNAPSHOT.jar:/opt/flink/lib/blink-statebackend-gemini-2.1.19-20210307.140847-1.jar:/opt/flink/lib/
...
184543 ? Dl 444:32 /opt/taobao/java/bin/java -classpath /opt/flink/conf:/opt/flink/lib/blink-launcher-blink-3.4.2-SNAPSHOT.jar:/opt/flink/lib/blink-metrics-ceresdb-blink-3.4.2-SNAPSHOT.jar:/opt/flink/lib/blink-pangu-fs-blink-3.4.2-SNAPSHOT.jar:/opt/flink/lib/blink-statebackend-antkv_2.11-blink-3.4.2-SNAPSHOT.jar:/opt/flink/lib/blink-statebackend-gemini-2.1.19-20210307.140847-1.jar:/opt/flink/lib/
...
- 检查 ``D`` 住进程的堆栈:
.. literalinclude:: d_process_stack
:language: bash
:linenos:
:caption:
可以看到:
- ``[load_calc]`` 系统进程在 ``ret_from_fork+0x1f/0x30`` 出现异常阻塞
- ``blink`` 进程在 ``entry_SYSCALL_64_after_hwframe+0x44/0xa9`` 出现异常阻塞
进程信息排查
=============
:ref:`sysrq` 的提供了 ``t`` 指令dump出当前任务的信息,所以我在服务器上执行以下命令,打开进程信息::
echo t > /proc/sysrq-trigger
- 此时, ``dmesg -T`` 可以看到大量的系统调用被记录下来,其中有非常值得注意的 :ref:`bad_rip_value`
可以看到 :ref:`bad_rip_value` 同样集中在系统调用 ``entry_SYSCALL_64_after_hwframe+0x44/0xa9`` ,也就是阻塞进程的调用。
.. literalinclude:: dump_tasks_info
:language: bash
:linenos:
:caption:
再次出现 ``[load_calc]`` 系统进程D
====================================
我在 :ref:`amd_cpu_c-state` ,调整了内核参数( ``processor.max_cstate=1 intel_idle.max_cstate=0`` )关闭海光CPU的电源管理,禁止进入idle状态( :ref:`cpu_c-state` )。但是,服务器重启,再次出现 ``[load_calc]`` 进程D。检查进程堆栈,也和上文相同。
- 我尝试上文方法 :ref:`sysrq` 的提供了 ``t`` 指令dump出当前任务的信息::
echo t > /proc/sysrq-trigger
结果发现这次命令卡住没有返回,同时系统一下子出现了更多的D进程::
$ps r -A | grep D
PID TTY STAT TIME COMMAND
1016 ? D 0:06 [load_calc]
13693 ? D 0:00 runc init
13806 ? D 0:00 runc init
13895 ? D 0:00 runc init
14020 ? D 0:00 runc init
14073 ? D 0:00 runc init
14095 ? D 0:00 runc init
16303 ? Dl 0:00 runsc --version
18678 ? Dl 0:00 runsc --version
458475 ? D 0:01 [kworker/u256:0+]
重复出现如下调用 :
.. literalinclude:: debug_d_process/dump_tasks_syscall
:language: bash
:caption: 重复出现大量 entry_SYSCALL_64_after_hwframe D住
.. literalinclude:: debug_d_process/dump_tasks_syscall_exit_usermode
:language: bash
:caption: 退出用户态也卡住
- 系统大量的内核进程开始运行,异常缓慢::
#ps r -A
PID TTY STAT TIME COMMAND
26 ? R 0:00 [migration/3]
27 ? R 0:11 [ksoftirqd/3]
77 ? R 0:00 [migration/13]
78 ? R 0:00 [ksoftirqd/13]
226 ? R 1:18 [migration/42]
313 ? R 0:00 [migration/59]
314 ? R 0:00 [ksoftirqd/59]
498 ? R 0:00 [migration/96]
499 ? R 0:00 [ksoftirqd/96]
518 ? R 0:00 [migration/100]
519 ? R 0:00 [ksoftirqd/100]
578 ? R 0:00 [migration/112]
579 ? R 0:00 [ksoftirqd/112]
653 ? R 0:00 [migration/127]
654 ? R 0:00 [ksoftirqd/127]
742 ? R 0:01 [kworker/42:1-mm]
1016 ? D 0:06 [load_calc]
- 采用 :ref:`kernel_crash_dump` 强制core dump,重启服务器
重启后 ``[load_calc]`` 系统进程依然 ``D`` 但是看不出其他异常,系统运行应用完全正常。这个问题后续再想办法排查...
参考
=======
- `How To Diagnose High Sys CPU On Linux `_
- `Debugging High CPU Usage Using Perf Tool and vmcore Analysis `_