Pae*_*els 20 linux drivers kernel sata
我在 VHDL 中实现了我自己的串行 ATA 主机总线适配器 (HBA) 并将其编程到 FPGA 上。FPGA是可以用任何数字电路编程的芯片。它还配备了串行收发器,可为 SATA 或 PCIe 生成高速信号。
此 SATA 控制器支持 SATA 6 Gb/s 线速,并使用 ATA-8 DMA-IN/OUT 命令以高达 32 MiB 的数据块与设备传输数据。该设计已被证明可以以最大速度运行(例如三星 SSD 840 Pro -> 超过 550 MiB/s)。
在对几个 SSD 和 HDD 设备进行了一些测试之后,我购买了一个新的希捷 6 TB Archive HDD ( ST6000AS0002 )。这款硬盘的读取性能高达 190 MiB/s,但写入性能只有 30 到 40 MiB/s!
所以我深入挖掘并测量了传输的帧(是的,FPGA 设计可以实现)。据我所知,希捷硬盘已准备好一次性接收传输的前 32 MiB。此传输以 580 MiB/s 的最大线路速度进行。之后,硬盘将剩余字节停止超过800 毫秒!然后 HDD 准备好接收下一个 32 MiB 并再次停止 800 毫秒。总而言之,1 GiB 传输需要超过 30 秒,相当于大约 35 MiB/s。
我假设这个 HDD 有一个 32 MiB 的写缓存,它在突发周期之间被刷新。小于 32 MiB 的数据传输不会显示此行为。
我的控制器使用 DMA-IN 和 DMA-OUT 命令来传输数据。我没有使用 QUEUED-DMA-IN 和 QUEUED-DMA-OUT 命令,它们由支持 NCQ 的 AHCI 控制器使用。在 FPGA 平台上实现 AHCI 和 NCQ 非常复杂,我的应用层不需要。
我想在我的 Linux PC 上重现这个场景,但 Linux AHCI 驱动程序默认启用了 NCQ。我需要禁用 NCQ,所以我发现这个网站描述了如何禁用 NCQ,但它不起作用。
Linux PC 仍然达到 190 MiB/s 的写入性能。
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
1073741824 bytes (1.1 GB) copied, 5.46148 s, 197 MB/s
Run Code Online (Sandbox Code Playgroud)
我认为上面的文章有一个错误:将NCQ队列深度减少到1并没有禁用NCQ。它只允许操作系统使用一个队列。它仍然可以使用 QUEUED-DMA-** 命令进行传输。我需要真正禁用 NCQ,以便驱动程序向设备发出 DMA-IN/OUT 命令。
所以这里是我的问题:
/sys/block/sdX/device/queue_depth中未报告更改dmesg?Pae*_*els 17
感谢@frostschutz,我可以在没有 NCQ 功能的情况下测量 Linux 中的写入性能。内核引导参数libata.force=noncq完全禁用了 NCQ。
关于我的希捷 6TB 写入性能问题,速度没有变化。Linux 仍然达到 180 MiB/s。
但后来我有了另一个想法:
Linux 驱动程序不使用 32 MiB 块的传输。内核缓冲区要小得多,特别是如果启用了 32 个队列的 NCQ(32 个队列 * 32 MiB => 1 GiB AHCI 缓冲区)。
所以我用 256 KiB 传输测试了我的 SATA 控制器,瞧,它有可能达到 185 MiB/s。
所以我猜希捷 ST6000AS0002 固件不能处理大 ATA 突发传输。ATA 标准允许多达 65.536 个逻辑块,相当于 32 MiB。
SMR - 瓦片式磁记录
写入性能不佳的另一种可能是叠瓦式磁记录技术,希捷在这些存档设备中使用了这种技术。显然,我用我的 FPGA 实现触发了一个罕见的效果。
将队列深度设置为 1 ( /sys/block/sd*/device/queue_depth) 会禁用 NCQ,不需要使用内核参数libata.force=noncq(只能在启动时设置)。
提交360f654e7cda850034f3f6252a7a7cff3fa77356
Date: Sat Sep 30 19:45:00 2006 +0900
[PATCH] libata: turn off NCQ if queue depth is adjusted to 1
Turn off NCQ if queue depth is adjusted to 1.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19912 次 |
| 最近记录: |