![为什么新的 Linux IO“压力失速信息”不显示为 100%?](https://linux22.com/image/156236/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%96%B0%E7%9A%84%20Linux%20IO%E2%80%9C%E5%8E%8B%E5%8A%9B%E5%A4%B1%E9%80%9F%E4%BF%A1%E6%81%AF%E2%80%9D%E4%B8%8D%E6%98%BE%E7%A4%BA%E4%B8%BA%20100%25%EF%BC%9F.png)
atop
我注意到(在我的 Fedora 30 安装上)有一条闪亮的新行。
PSI - 压力失速信息。
此行包含每个类别的三个百分比:过去 10、60 和 300 秒的平均压力百分比(用斜线分隔)。这些类别是:“某些”的 CPU (
cs
)、“某些”的内存 (ms
)、“完整”的内存 (mf
)、“某些”的 I/O (is
) 和“完整”的 I/O (if
)。
欲了解更多详情,请参阅“跟踪压力失速信息“[LWN.net,2018]。
我跑步dd if=/dev/zero bs=1M of=test
并观看了 5 个十秒的间隔。最高is
值为if
63%。我必须等待几次才能达到那么高的值。
我预计这个指标是“所有 IO 延迟造成的 CPU 潜力损失”[1]/“任务正在等待 io 完成”[2]将等于 100%...
我最初的期望并不真实。因为atop
我的作者在传统进程列表中dd
使用了 15-20% 的 CPU。然而,将这些数字加起来仍然不等于 100% :-)。
相反,读取文件(不使用 O_DIRECT)dd
会增加到is
大约 43%,并且显示使用大约 9% 的 CPU。它至少看起来就像这里有一个很大的差距:-)。
运行一个dd
writer oflag=direct
,IO 压力达到 51%,CPU 使用率 6%。
运行dd
阅读器iflag=direct
,IO压力达到47%,CPU使用率3%。
我们如何理解这种明显的差异?
IO调度器是mq-deadline
.存储设备是机械硬盘。我的内核是v5.2-rc5-290-g4ae004a9bca8
,加上 3 个 ext4 补丁,希望这些补丁无关紧要。
答案1
我对这个问题的第一个回答是“IO压力”与“CPU IO等待时间”的概念密切相关。我看到的 CPU IO 等待时间也显得太短了。所以我不应该希望“IO压力”有任何意义。
不过,我现在至少拥有了CPU iowait 时间问题的解决方法。也就是说,启动 withnohz=off
给出了我预期的 iowait 时间。或者,我可以通过强制轮询而不是 cpu 空闲来达到相同的效果 - 这也确保调度程序滴答永远不会停止:
cd /sys/devices/system/cpu
# Disable all cpuidle states, including C1 ("halt"), but not POLL
for i in cpu*/cpuidle/state[1-9]*/disable; do echo 1 | sudo tee $i; done
# Reset to default (C-states enabled)
for i in cpu*/cpuidle/state*/disable; do echo 0 | sudo tee $i; done
启动nohz=off
似乎也会增加“IO 压力”值。我还没有被新的价值观所说服。他们似乎更接近我的预期......
nohz=off
虽然如果我正确理解代码的话,像iowait一样增加IO压力是没有意义的!至少压力失速信息的原始补丁似乎完全是事件驱动的。我没有看到它依赖于调度程序勾选!
以下atop
几行是在运行时拍摄的dd if=test iflag=direct bs=1M of=/dev/null
(至少六十秒):
CPU | sys 2% | user 1% | irq 1% | idle 300% | wait 96%
cpu | sys 1% | user 0% | irq 0% | idle 89% | cpu003 w 10%
cpu | sys 1% | user 0% | irq 0% | idle 23% | cpu001 w 76%
cpu | sys 0% | user 0% | irq 0% | idle 98% | cpu000 w 1%
cpu | sys 0% | user 0% | irq 0% | idle 90% | cpu002 w 9%
CPL | avg1 0.76 | avg5 0.92 | avg15 0.84 | | numcpu 4
PSI | cs 0/0/0 | ms 0/0/0 | mf 0/0/0 | is 83/57/44 | if 83/57/44
- cpu3 有 11% 的非空闲时间 (100-89)。 10%被算作“iowait”。
- cpu1 有 77% 的非空闲时间 (100-23)。 76%被算作“iowait”。
- cpu2+cpu0 有 12% 的非空闲时间。 10%被算作“iowait”。
ms
是 0。因此,我们不可能将某些(不可忽略的)iowait 时间计算为“停止竞争内存”而不是“停止等待 IO”。 (不过我不确定这是否更普遍)。
psi 跟踪与每个 CPU 相关的任务状态,并对它们在停顿状态下花费的时间进行采样。每 2 秒,对 CPU 上的样本进行平均(根据 CPU 的非空闲时间进行加权,以消除未使用的 CPU 中的伪影),并转换为挂起时间的百分比。
例如 cpu1 有 76/77 = 98.7% IO 压力(满)。这应该是加权平均值中最大的一项。所以我仍然认为报告的价值比预期低很多。
在上面的测试中,“完整”值与“部分”值基本相同。因此,我预计这些神秘的差异同样适用于“IO 压力(某些)”。
重要的是,用于加权平均值的“非空闲”时间仅排除纯粹的空闲时间。所以“非空闲”时间不仅仅是CPU使用率。 “非空闲”时间还包括“CPU IO等待时间”。
结构 psi_group_cpu { /* 属于该组的任务的状态 */ 无符号整型任务[NR_PSI_TASK_COUNTS]; /* 有可运行的或 D 状态任务 */ int 非空闲;
groupc->nonidle = 任务[NR_RUNNING] || 任务[NR_IOWAIT] ||任务[NR_MEMSTALL];
注意:PSI 并不真正使用报告的每个 CPU“iowait”。它自己做会计。同样,我的链接问题表明“iowait”可能被严重低估,但我思考PSI 相当于“iowait”的目的是为了避免这个问题。
使用将该命令固定dd
到单个 cpu ,如果被抑制,taskset -c 0
我会达到 96% 的 IO 压力,否则会达到 90%。NO_IDLE_HZ
这些数字对我来说似乎更可信。