读取缓慢或写入缓慢会影响所有驱动器

读取缓慢或写入缓慢会影响所有驱动器

我正在运行Ubuntu 16.04RocketRaid 2720SGL HBA board已经更新了固件,取出 RAID 处理器并只使用端口。

主板上有两个端口,每个端口可连接 4 个驱动器,总共可连接 8 个驱动器。我每个端口连接了 2 个驱动器。

系统启动时,主板会将所有四个驱动器视为第一个端口的 0、1 和第二个端口的 4、5。这很好。

列出驱动器时,我看到它们是 sdb、sdc、sdd 和 sde。在/dev/disk/by-path我将它们视为 0、1、4、5。我用它来了解哪个实际驱动器端口与哪个设备 ID 绑定。

使用四块 500 GB 的磁盘,我可以在大约 70 - 80 分钟内擦除所有四个驱动器,而这正好是擦除一个驱动器所需的时间。我使用

if((RetVal = pthread_create(&DIptr->DI_ThreadFD, NULL, WipeTheDrive, DIptr)) != 0)
{
     printf("WIPESINGLEDRIVE: ERROR: return code from pthread_create() is %d errno: [%d]\n", RetVal, errno);
}

独立执行四个线程。如果驱动器没有任何坏扇区或任何异常,则擦除操作会顺利进行。我使用O_RDWR|O_DIRECT并且我已经将缓冲区设置在正确的边界上,以便我可以使用 DMAWipeBuffer[1048576] __attribute__ ((__aligned__ (1048576)));

这一切都运行正常,我通过这种逻辑以每次四个驱动器的方式运行了 240 个驱动器,从来没有出现过问题。

但情况确实如此。如果四个驱动器中的一个有坏扇区或写入速度慢或读取速度慢,那么它会影响所有其他驱动器的时序。换句话说,如果驱动器 1 有坏扇区并等待读取或写入返回,那么其他驱动器也会等待。它就像它们共享某种类型的队列或缓冲区,并且都在排队等待轮到它们。我有根据读写性能对驱动器进行评级的例程,如果一个驱动器出现问题,我会得到一个假故障。

综上所述,首先我不知道是什么原因造成的,是操作系统将任务排队到内核,还是驱动程序,尽管我不认为是驱动程序。我给 Marvell 技术支持人员(固件开发人员)发了一封电子邮件,他们告诉我,主板上的每个通道都是独立的,每四个驱动器有一个 DMA 通道。我已将驱动器拆分到两个 DMA 通道之间,如果其中一个驱动器速度慢,则所有驱动器的速度仍然会变慢。

我应该进行哪些改变才能获得四个独立通道,且彼此之间不互相影响?

=========================================================================

在听取了使用 blktrace 的建议后,我安装了它,并在四个驱动器同时写入时运行它。跟踪看起来不错,似乎很好地共享了写入。

然后我拔出其中一个驱动器,跟踪结果如下

8,48 2 422 0.542202510 12017 Q WS 581826560 + 2048 [客户端]

8,48 2 423 0.542207566 12017 Q WS 581827584 + 1024 [客户端]

8,48 2 424 0.542208902 12017 G WS 581826560 + 1024 [客户端]

8,48 2 425 0.542213507 12017 G WS 581827584 + 1024 [客户端]

8,48 2 426 0.542214337 12017 I WS 581826560 + 1024 [客户端]

8,48 2 427 0.542214854 12017 I WS 581827584 + 1024 [客户端]

8,48 2 428 0.542221516 289 D WS 581826560 + 1024 [kworker/2:1H]

8,48 2 429 0.542228504 289 R WS 581826560 + 1024 [0]

8,48 2 430 0.542228808 289 我 WS 581826560 + 1024 [kworker/2:1H]

8,48 2 431 0.542572302 289 D WS 581826560 + 1024 [kworker/2:1H]

8,48 2 432 0.542572979 289 R WS 581826560 + 1024 [0]

8,48 2 433 0.542573279 289 我 WS 581826560 + 1024 [kworker/2:1H]

8,48 2 434 0.546583088 289 D WS 581826560 + 1024 [kworker/2:1H]

8,48 2 435 0.546583892 289 R WS 581826560 + 1024 [0]

8,48 2 436 0.546584227 289 我 WS 581826560 + 1024 [kworker/2:1H]

8,48 2 437 0.550587702 289 D WS 581826560 + 1024 [kworker/2:1H]

8,48 2 438 0.550588397 289 R WS 581826560 + 1024 [0]

8,48 2 439 0.550588711 289 我 WS 581826560 + 1024 [kworker/2:1H]

8,48 2 440 0.554580452 289 D WS 581826560 + 1024 [kworker/2:1H]

8,48 2 441 0.554581354 289 R WS 581826560 + 1024 [0]

8,48 2 442 0.554581664 289 我 WS 581826560 + 1024 [kworker/2:1H]

您可以看到“客户端”(可执行文件的名称)正在排队写入,然后“kworker”进程就停留并敲打我拉出的驱动器。这只是一个小例子,但它运行了好几页,客户端根本没有机会对其他三个驱动器发出任何新的写入。据我了解,“kworker”进程是一个处理设备 I/O 的内核进程。

所以我现在的问题是,当驱动器离线或者写入或读取速度很慢时,如何让“kworker”进程不垄断整个 I/O 进程并与其他设备共享通道。

答案1

听起来驱动程序一次不会发出多个请求。您可以查看该blktrace工具来分析 IO 堆栈中发生的情况。如果驱动程序正常工作,您应该同时看到多个处于 D(ispatch)状态的请求。如果只有一个,那么这就是问题所在。

相关内容