CPU 如何知道有 IO 挂起?

Alc*_*ist 17 linux cpu top load-average

我一直iowait在研究顶部实用程序输出中显示的属性,如下所示。

top - 07:30:58 up  3:37,   1 user,  load average: 0.00, 0.01, 0.05
Tasks:  86 total,   1 running,   85 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
Run Code Online (Sandbox Code Playgroud)

iowait 一般定义如下:

“这是 CPU 空闲且有一些 IO 待处理的时间。”

我的理解是一个进程在单个 CPU 上运行。在它因为已用完时隙或被阻塞而被取消调度后,它最终可以再次在任何一个 CPU 上再次调度。

在 IO 请求的情况下,将进程置于不间断睡眠状态的 CPU 负责跟踪iowait时间。其他 CPU 将报告与它们的空闲时间相同的时间,因为它们确实处于空闲状态。这个假设正确吗?

此外,假设有一个很长的 IO 请求(意味着进程有几次被调度的机会,但由于 IO 未完成而没有被调度),CPU 怎么知道有“待处理的 IO”?这种信息是从哪里获取的?CPU 怎么能简单地发现某个进程在一段时间内进入睡眠状态以完成 IO,因为任何 CPU 都可以使该进程进入睡眠状态。“待处理 IO”的状态是如何确认的?

Ste*_*itt 33

CPU 不知道这些,任务调度程序知道。

你引用的定义有点误导;当前的procfs(5)联机帮助页有更准确的定义,但有警告:

iowait (自 Linux 2.5.41 起)

(5) 等待 I/O 完成的时间。该值不可靠,原因如下:

  1. CPU 不会等待 I/O 完成;iowait是任务等待 I/O 完成的时间。当 CPU 因未完成的任务 I/O 进入空闲状态时,另一个任务将在该 CPU 上调度。

  2. 在多核 CPU 上,等待 I/O 完成的任务不在任何 CPU 上运行,因此iowait每个 CPU 的 难以计算。

  3. 在某些情况下,此字段中的值可能会减少。

iowait通常,尝试测量等待 I/O 所花费的时间。它不会特定的 CPU跟踪,也不会被跟踪(上面的第 2 点 - 这也与您想知道的内容相符)。但是,它尽可能CPU测量。

任务调度程序“知道”有挂起的 I/O,因为它知道它挂起给定的任务,因为它正在等待 I/O。这是跟踪in_iowait领域中的每个任务task_struct;您可以in_iowait调度程序核心中查找以查看它是如何设置、跟踪和清除的。Brendan Gregg 最近关于 Linux 平均负载的文章包括有用的背景信息。中的iowait条目/proc/stat,即结束于的条目,top每当考虑到计时器滴答时就会递增,并且 CPU 上的当前进程处于空闲状态;您可以通过account_idle_time调度程序的 CPU 时间跟踪代码中查找来查看这一点。

所以更准确的定义是“当没有更好的事情可做时,花在这个 CPU 上等待 I/O 的时间”......