概要
「VIAのVT6421チップを使ったSATAカードとWDの新しめのHDDの間には相性問題が存在します。でもパッチを当ててカーネルをコンパイルすれば直ります。」と書いた話です。最新のカーネルなら直ります。
解説
Western Digital の新しいドライブとVIA VT6421の組み合わせではディスクのリードが非常に遅くなることがあります。以下はLinuxカーネル 2.6.36.1ツリーのdrivers/ata/sata_via.cのコメントと対策部分のコードです:
/* * vt6421 has problems talking to some drives. The following * is the fix from Joseph Chan. * * When host issues HOLD, device may send up to 20DW of data * before acknowledging it with HOLDA and the host should be * able to buffer them in FIFO. Unfortunately, some WD drives * send upto 40DW before acknowledging HOLD and, in the * default configuration, this ends up overflowing vt6421's * FIFO, making the controller abort the transaction with * R_ERR. * * Rx52[2] is the internal 128DW FIFO Flow control watermark * adjusting mechanism enable bit and the default value 0 * means host will issue HOLD to device when the left FIFO * size goes below 32DW. Setting it to 1 makes the watermark * 64DW. * * https://bugzilla.kernel.org/show_bug.cgi?id=15173 * http://article.gmane.org/gmane.linux.ide/46352 */ if (pdev->device == 0x3249) { pci_read_config_byte(pdev, 0x52, &tmp8); tmp8 |= 1 << 2; pci_write_config_byte(pdev, 0x52, tmp8); }
訳:
vt6421は一部のドライブとのやり取りに問題がある。以下はJoseph Chan
による修正。 ホストがHOLDを発行するとき、ドライブはこれを了解するまでに20DWまでのデータを送り得るため、ホストはこのデータをFIFOに蓄積できるべきである。困ったことにWDの一部のドライブはHOLDを了解するまでに40DWほど送る場合があり、デフォルト設定のVT6421のFIFOをオーバーフローさせるため、VT6421はR_ERRを出して処理を中断することになる。
Rx52[2]は内部の128DW FIFOのフロー制御の基準値調整機構のイネーブルビットで、デフォルト値の0は、ホストはFIFOサイズが32DW未満になったときにデバイスにHOLDを発行する、という意味である。これを1にすると基準値は64DWになる。
このパッチはもともと linux-ide メーリングリストに投稿されたものです(http://www.spinics.net/lists/linux-ide/msg37898.html)。カーネル2.6.22.9のvia_sata.cに入れてもきちんと動作しました。最新カーネルの2.6.36.1では既に取り込まれているので、パッチを当てる必要はありません。
パッチは、サーバのコンソールに出ていたエラーメッセージについて調べていて見つけました:
ata4.00: exception Emask 0x12 SAct 0x0 SErr 0x1000500 action 0x6 ata4.00: BMDMA stat 0x5 ata3: SError: { UnrecovData Proto TrStaTrns } ata4.00: cmd 25/00:60:05:7a:41/00:00:1a:00:00/e0 tag 0 dma 49152 in res 51/84:3f:26:7a:41/84:00:1a:00:00/e0 Emask 0x12 (ATA bus error) ata4.00: status: { DRDY ERR } ata4.00: error: { ICRC ABRT }
これを検索してUbuntuのフォーラムのBug #422994 in linux (Ubuntu): “sata_via hard resetting link / freeze: exception Emask 0x12 SAct 0x0 SErr 0x1000500 action 0x6”という記事を見つけ、そこから上記のメーリングリストのパッチに辿り着きました。
よく「WDの低速病」などと言われている症状の一部も、これに該当するような気がします。高速化のために投機的にデータを送ることで低速になってしまっているように見えるので、皮肉なことです。6421はもともと高速なチップではないので、これを機会に更新してもよいでしょう。