メルマガ配信

メールアドレス:
メールアドレス:
LinuxでEDACを使いECCエラーを検出する 印刷
メモリに記録されるデータというのは意外と誤ってしまうものです。
誤ったデータが記録されるにはいくつかの要因があり、メモリモジュールの物理的な経年劣化や、宇宙線によるビットの反転など、通常の手段では防ぐことが難しい、あるいは事実上不可能なものが多いです。

そこでそういった誤りを防ぐために、ECCという仕組みが開発されました。メモリアクセスに冗長性を持たせることにより、エラーを検出、可能ならば訂正まで行ってくれる心強い仕組みです(参照:http://e-words.jp/w/ECCE383A1E383A2E383AA.html)。


LinuxでECCを利用し、メモリエラーを検出するにはEDACというモジュールを用います。
EDACはかつてはbluesmokeという名前のLinuxカーネルそのものからは独立したカーネルモジュールでしたが、2.6.16以降のカーネルソースツリーにはデフォルトで組み込まれています。menuconfigで有効にするには、Device Drivers -> EDAC - error detection and reporting 以下で使用しているチップセット用のモジュールを選択すればOKです。
訂正可能なエラーはCorrectable Error、略してCEといい、訂正不可能なエラーはUncorrectable Error、略してUEと呼ばれます。

UEが起こった場合は、エラーが起こった、ということ自体は知ることが出来ますが、
本来あるべき値は分からないため、そのままシステムを走らせることは極めて危険です。そのエラーによる影響は予測不可能だからです。
そのためUEが検出された場合はカーネルパニックを発生させ、即座にシステムを停止させることが出来るようになっています。

Intel i3000用のモジュールはそのままではエラーを検出することができませんでしたが、今回Intel i3000用モジュールの不具合を修正子、きちんと動作するようにしました。
以下のパッチを適用すると、きちんとメモリエラーを検出することが出来ます。

diff -Naur linux.orig/drivers/edac/i3000_edac.c linux/drivers/edac/i3000_edac.c
--- linux.orig/drivers/edac/i3000_edac.c    2007-12-19 06:55:57.000000000 +0900
+++ linux/drivers/edac/i3000_edac.c    2007-12-19 20:04:17.000000000 +0900
@@ -14,6 +14,7 @@
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/slab.h>
+#include <linux/edac.h>
 #include "edac_core.h"
 
 #define I3000_REVISION        "1.1"
@@ -288,6 +289,15 @@
         return -ENODEV;
     }
 
+    switch (edac_op_state) {
+    case EDAC_OPSTATE_POLL:
+    case EDAC_OPSTATE_NMI:
+        break;
+    default:
+        edac_op_state = EDAC_OPSTATE_POLL;
+        break;
+    }
+
     c0dra[0] = readb(window + I3000_C0DRA + 0);    /* ranks 0,1 */
     c0dra[1] = readb(window + I3000_C0DRA + 1);    /* ranks 2,3 */
     c1dra[0] = readb(window + I3000_C1DRA + 0);    /* ranks 0,1 */
@@ -504,3 +514,6 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Akamai Technologies Arthur Ulfeldt/Jason Uhlenkott");
 MODULE_DESCRIPTION("MC support for Intel 3000 memory hub controllers");
+
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");

写真の様にメモリのピンを削り、CEを検出してみました。
Image
実際に検出されると、以下のようなメッセージがカーネルから出力されます。
EDAC MC0: CE page 0x3e9, offset 0x380, grain 128, syndrome 0x91, row 0, channel 0, label "": i3000 CE
EDAC MC0: CE page 0x3e9, offset 0x380, grain 128, syndrome 0x91, row 0, channel 0, label "": i3000 CE
EDAC MC0: CE page 0x1f5db, offset 0x80, grain 128, syndrome 0x91, row 0, channel 0, label "": i3000 CE
この様なメッセージが頻繁に見られるようになったら、メモリモジュールが壊れかけていると考えられます。タイミングを見て新しいモジュールに交換した方が良いでしょう。

EDACを用いればメモリエラーを検出することが出きるようになり、深刻なトラブルを未然に防ぐことが可能になります。

追記:このパッチをEDACプロジェクトのメーリングリストに投稿したところ、近くLinuxカーネルのソースツリー自体に取り込まれるとのことです。

最終更新 2008年 12月 13日(土曜日) 02:52