由于 I/O 操作繁重,软中断延迟

由于 I/O 操作繁重,软中断延迟

我正在尝试将 1 GB ISO 文件(存储在 USB 中)的内容复制到我的内部存储中。作为测试的一部分,当我连续执行从 USB 到硬盘驱动器的重复复制操作时,我有时会观察到 CPU 停顿,这使我的系统错过一些重要的网络数据包或干扰其他关键操作。

我遵循的步骤:

  1. 将 ISO (ISO-9660) 挂载到 HDD 中的文件夹之一
  2. 然后开始从Mounted文件夹复制到HDD中的其他文件夹
  3. 复制完成后。删除复制的文件夹。
  4. 等待 10 秒,然后重新开始该过程。

我已经尝试过copy, rsync,dd命令。并copy没有rsync取得成果。但dd直接使用命令可以更好地提高性能。但不幸的是,我无法在安装的目录上直接使用它,因为它是只读文件系统。

我探索了几种使我的 iso 成为读写文件系统的方法,但似乎 ISO-9660 文件格式被设计为只读文件系统。

由于直接选项避免了缓存并直接访问 I/O。我试图通过将 /proc/sys/vm/dirty_backgroud_bytes 和 /proc/sys/vm/dirty_bytes 分别设置为 500000 和 550000 来模仿相同的行为。但几个小时后失败了。

然后我尝试使用 hdparam 工具禁用硬盘上的缓存后进行复制。但这也导致了失败。

使用的命令:

Rsync:  rsync --recursive --bwlimit=1024 <src dir>  <target dir>
Copy : cp -a <src dir> <target dir>
find the folders the in the directory and copy it one by one 
dd: dd if=<src file>  of=<target file> conv=notruc iflag=direct oflag=direct

我如何测量我的 CPU 停顿?

我捕获前往目标计算机的网络,并且我有一个应用程序(在用户空间以最高优先级运行),它将在特定时间期待这些网络数据包并引发软中断。因此,如果网络数据包已到达我的系统和应用程序没有生成中断,那么我将检查当时的内核跟踪,我可以看到收到的网络数据包尚未到达我的应用程序,因为下面排队的内核调用

kmem_cache_alloc

Kmem_K_alloc

rcu_利用率

kmem_kfree

kmem_cache_free

ext4_ind_map_blocks_exit

ext4_da_保留空间

kmem_mm_page_free_direct

kmem_mm_page_alloc --> 连续调用14次

kmem_mm_page_alloc_zone_locked --> 连续调用12次

再次kmem_mm_page_alloc -->连续调用8次

ext3_get_blocks_enter

ext3_get_blocks_exit

ext4_da_write_begin --> 频繁但不连续 ext4_da_write_end --> 频繁但不连续 ext4_ind_map_blocks_enter --> 频繁但不连续 ext4_mark_inode_dirty --> 频繁但不连续

您能分享一下您对这个问题和以下问题的见解吗?

那么什么会导致像这样的停顿(缓存)呢?有什么办法可以避免它

那么有没有办法使用直接标志从我安装的文件夹(只读)复制到目标文件夹?

请注意我想要复制的目标目录具有读写权限,但由于某种原因 oflag=direct 也不起作用。

有没有办法准备具有读写权限的iso?

答案1

您可以尝试采取多种措施来减少网络进程的 I/O 延迟。根据用例,您唯一的选择可能是切换到实时内核,例如Linux 的 PREEMPT_RT 补丁。请参阅下文了解原因。但这是一个相当极端的措施,所以我建议您首先尝试其他一些方法:

  • 使用以下命令调整网络进程和复制进程的 I/O 优先级伊奥尼斯
  • 挂载文件系统以mount -o sync禁用任何缓存。
  • 使用directsyncI/O 时,请尝试在使用该命令时改变块大小dd。可以想象,非常大或非常小的块可能是一个不错的选择,或者例如与您的页面大小相匹配的块大小......但这只是一个疯狂的猜测。

实时内核

根据您的要求,这可能是唯一真正可行的选择。让我解释。你写:

我捕获前往目标计算机的网络,并且我有一个应用程序(在用户空间以最高优先级运行),它将在特定时间期待这些网络数据包。

为了诊断问题,我们需要一些东西。例如:您认为包裹“丢失”的时间窗口有多大?多少丢包是可以接受的?无论我们谈论的是 500 µs 还是 500 ms 的截止时间,以及是否允许 5% 或 0.05% 的数据包延迟或“丢失”,这都会产生巨大的差异。

但是,无论时间窗口如何,除非您运行的是实时 (RT) 内核,否则在 100% 的情况下都不可能满足此要求。 “实时”一词意味着它可以具体保证对特定事件(例如您的情况下传入的网络数据包)做出反应所需的时间。

普通(非实时)Linux 内核使得没有这样的保证,因此甚至允许它在执行当前认为重要的操作(例如缓存或任何它喜欢的操作)时阻塞整个用户空间几秒钟。无论用户空间优先级如何。因此,无论您做什么,如果您的计算机除了等待网络数据包之外还执行其他操作,那么在不切换到 RT 内核的情况下,您总是面临随机、无限期延迟的风险。即使这是唯一正在运行的进程,某些驱动程序也可能每隔几分钟/几小时/几天随机决定必须花费几毫秒来清理一些缓冲区现在

所以你隐含问题的答案“为什么 I/O 会使其他进程对网络数据包的反应速度变慢?”是:“因为内核被允许这样做”

因此,使 ISO 文件系统可读写(我认为这是不可能的)或使用directI/O,或除使用 RT 内核之外的任何其他措施,都不会解决问题。它只会降低这种情况发生的可能性。

相关内容