WD20EARSとVIA6421AとソフトRAID(md)のはまりどころ(3) VIA VT6421AとWestern Digitalドライブの相性問題

概要

「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はもともと高速なチップではないので、これを機会に更新してもよいでしょう。