`cat /proc/$pid/cmdline` 怎么能花几秒钟的时间?

Hai*_*ong 7 ps swap proc

我昨天在我们的一台服务器上遇到了这种奇怪的行为。pspgrep并且htop(在启动时)非常慢。strace ps表明read('/proc/$pid/cmdline) 在某些进程上花费了几秒钟。为什么会这样?

一些观察:

  • 进程可执行文件在 NFS 上
  • 进程(大约 20 多个)同时在 NFS 上执行unlinksymlink操作文件
  • 它们是从同一个父进程分叉出来的
  • 有 80GB 的 RAM 可用(主要是缓存),但交换(仅 4GB)已被充分使用
  • 我运行while true; do cat /proc/$pid/status; sleep .1; donecat如果StateS或 则立即返回R,但是当State是时需要几秒钟D

我做了一些谷歌搜索,发现了一些 SO 答案,表明当State是时D,阅读/proc/$pid/cmdline会停滞。真的吗?这是如何运作的?为什么/proc/$pid/cmdline在程序开始之前设置的 会受到之后它所做的事情的影响?

小智 1

同样在这里,读取 /proc/$pid/cmdline 以获得特殊的 $pid 非常慢,即使 State 为 R 也是如此。感谢上面的链接指出它可能与 NUMA 有关,我发现它是由 numad 移动进程引起的从节点到节点,这是来自 /var/log/numad.log :

Thu Jul 18 20:06:41 2019: Advising pid 9565 ($name) move from nodes (0-1) to nodes (1)
Thu Jul 18 20:06:45 2019: PID 9565 moved to node(s) 1 in 3.91 seconds
Thu Jul 18 20:11:50 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:12:00 2019: PID 9565 moved to node(s) 1 in 9.72 seconds
Thu Jul 18 20:17:05 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:17:23 2019: PID 9565 moved to node(s) 1 in 17.85 seconds
Thu Jul 18 20:22:28 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:22:51 2019: PID 9565 moved to node(s) 1 in 22.73 seconds
Thu Jul 18 20:27:56 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:28:23 2019: PID 9565 moved to node(s) 1 in 26.88 seconds
Thu Jul 18 20:33:28 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:33:44 2019: PID 9565 moved to node(s) 1 in 15.49 seconds
Run Code Online (Sandbox Code Playgroud)

当移动进程时,读取cmdline很慢,因为cmdline来自用户空间,而内核需要锁定(?)页面并读取。

我猜想稍后需要从同一节点1移动到节点1,因为进程9565位于节点1上,但它可能使用远程内存。

% numactl -s
policy: default
preferred node: current
physcpubind: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
cpubind: 0 1
nodebind: 0 1
membind: 0 1

Run Code Online (Sandbox Code Playgroud)

谢谢。