How to (really) disable NCQ in Linux
Thanks to @frostschutz, I could measure the write performance in Linux without NCQ feature. The kernel boot parameter libata.force=noncq
disabled NCQ completely.
Regarding my Seagate 6TB write performance problem, there was no change in speed. Linux still reaches 180 MiB/s.
But then I had another idea:
The Linux driver does not use transfers of 32 MiB chunks. The kernel buffer is much smaller, especially if NCQ with 32 queues is enabled (32 queues * 32 MiB => 1 GiB AHCI buffer).
So I tested my SATA controller with 256 KiB transfers and voilà, it's possible to reach 185 MiB/s.
So I guess the Seagate ST6000AS0002 firmware is not capable of handling big ATA burst transfers. The ATA standard allows up to 65.536 logical blocks, which equals 32 MiB.
SMR - Shingled Magnetic Recording
Another possibility for the bad write performance could be the shingled magnetic recording technique, which is used by Seagate in these archive devices. Obviously, I triggered a rare effect with my FPGA implementation.
Setting the queue depth to 1 (/sys/block/sd*/device/queue_depth
) disables NCQ, it is not necessary to use the kernel parameter libata.force=noncq
(which can only be set at boot).
commit 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.