WADA-DEV(7) $ /ja/blog/home-server-random-freeze-part3-memtest-verdict/

NAME

home-server-random-freeze-part3-memtest-verdict — 自宅サーバがランダムフリーズした話 (3) ─ memtest、1 分で答えが出る

SYNOPSIS

memtest86+ は開始 1 分で Errors 705 を叩き出し、26 分後には自分自身がフリーズした。journal で見えた化けビットと memtest の実測が一致する答え合わせ、そして全症状が 1 つの故障で説明できるまで。

DESCRIPTION

前回までのあらすじ

数日おきに完全フリーズする自宅 AI サーバ。journal の法医学で「DRAM のビット化け」仮説に到達し、前回は「OC が原因」という思い込みが実測で崩れ、容疑がハードウェア個体(不良 DIMM か IMC か)に絞られました。ポータブルモニタも届いた。いよいよ物証を取りに行きます。

BIOS で最後の確認

memtest の前に、BIOS 画面で前回の推定を目視で確定させておきます。

  • EXPO: Disabled ─ 推定どおり。OC は一度も効いていなかった
  • DIMM_A2 / DIMM_B2 に 32GB × 2、5600MHz ─ スロット位置もマニュアル指定どおり

「設定は出荷状態のまま、挿し位置も正規」。これで残る容疑はハードウェアだけになりました。

memtest 起動(と、小さな事故)

ブートメニューから Memtest86+ を選択。ところが画面に何も映らない。数分待っても真っ黒のままで、一瞬「メモリが悪すぎて memtest すら起動できないのか?」と本気で考えました。結論としては再起動してもう一度選び直したら普通に表示されたのですが(GPU 2 系統構成での映像出力先の問題だったようです)、心臓に悪い。

そして表示された画面は、1 分でこうなりました。

Memtest86+ v8.00 AMD Ryzen 9 9950X 16-Core Processor
Pass 3% #
Test 45% ##################
IMC: DDR5-5600 / CAS 46-45-45-90
Time: 0:01:00 Status: Failed!
Pass: 0 Errors: 705
pCPU Pass Test Failing Address Expected Found
22 0 3 000cac773148 (50.6GB) 0000000000000000 2000000020000000
1 0 3 000c82264140 (50GB) ffffffffffffffff dfffffffdfffffff
24 0 3 000cb037a540 (50.7GB) ffffffffffffffff dfffffffdfffffff

開始 1 分で Errors 705。 数時間に 1 回の間欠エラーを一晩かけて狙う覚悟だったのに、拍子抜けするほど即答でした。

エラーの中身も雄弁です。全部ゼロを書いたのに 2000000020000000 が返る ─ bit 61 と bit 29 が勝手に立つ。全部 1 を書いたのに dfffffffdfffffff が返る ─ 同じ位置が勝手に落ちる。同じビットが両方向に化ける、物理欠陥の教科書的な姿です。

「Pass が 0 なんだが、俺のやり方が間違ってる?」

ここで白状すると、私はこの画面を見て一瞬不安になりました。Pass: 0 ─ 1 回も合格していない? やり方を間違えた?

これは読み方の問題で、Pass:完走した周回数です。64GB の 1 周には 30 分以上かかるので、開始 1 分なら 0 で当然。画面上部の Pass 3% の行が現在の周回の進捗です。そして Status: Failed! はテスト操作の失敗ではなく「メモリが検査に落ちた」という意味 ─ つまり求めていた診断結果そのものです。健康診断で病気が見つかったのであって、診断のやり方を間違えたわけではない。

26 分後、診断医が倒れる

放置して観察を続けると、エラーは増え続けます。

Time: 0:26:23 Status: Failed!
Pass: 0 Errors: 5823

そして Pass 88%、1 周目の完走を目前にして ─ memtest 自身がフリーズしました。キー入力にも反応しない。

考えてみれば当然で、memtest も自分のコードとワークデータを RAM に置いて動いています。検査対象の RAM が壊れていれば、検査ツールの管理データも化ける。診断医が患者と同じ病気で倒れた形です。ここまで来ればもう疑いの余地はありません(なお memtest 中は OS がいないので、せっかく仕込んだ hardware watchdog も効きません。電源長押しで復帰しました。最後にもう一度だけ)。

答え合わせ ─ journal と memtest のビットが一致する

この調査で一番気持ちよかった瞬間がここです。エラー行を眺めていると、こんなペアが出てきます。

Expected Found
3118348ee32ae000 3318348ee32ae000 ← bit 57 が立った
3118348ee32ae000 3518348ee32ae000 ← bit 58 が立った

見覚えのあるビットです。第 1 回で journal から拾った化けは:

  • GPF: 0xffff...0xfdff...bit 57 が落ちた
  • Bad page state: 0400000000000000bit 58 が立った

独立に記録されたカーネルクラッシュの化けビットが、memtest の実測にそのまま現れました。 アドレスのインターリーブまで解いた厳密な証明ではありませんが、偶然にしては出来すぎです。1 か月弱アプリの顔をして暴れていた犯人と、いま検査室で捕まえた犯人が、同じ指紋を持っていた。

全部つながる

物証が揃ったので、これまでの症状を一枚絵にできます。

物理欠陥(bit 57/58/61/29/26 系、おおむね 43〜56GB 帯 ※掲載外のエラー行も含めた分布)
│ 化けたビットがどこに乗ったかで顔が変わる
├─ カーネルポインタの上位ビット → GPF 非カノニカル(第1回・2回目)
├─ ページ管理の台帳 → Bad page state(第1回・3回目)
├─ 連結リストのポインタ → list_del corruption(第2回)
├─ ロック変数 → spinlock デッドロック → 全フリーズ(第1回・1回目)
├─ ページキャッシュ → BTRFS が「corruption」を誤検出(第2回の濡れ衣)
└─ memtest 自身のワーク領域 → 診断ツールごとフリーズ(今回)

そして「なぜ LLM を回した日だけ落ちるのか」の答えもここにありました。故障番地が 50GB 前後に集中しているのです。idle 時のメモリ使用量は数 GB で、この帯域には届かない。数十 GB のモデルをロードしたときだけ地雷原に踏み込む。発症条件の謎は、故障の物理的な位置がそのまま説明してくれました。

結末と教訓

このマシンは BTO で、納品 5 日後に最初のフリーズが起きていました。典型的な初期不良です。出荷前の動作テストは通過していたそうですが、故障域が 50GB 帯なら不思議はありません ─ 通常の検査ワークロードは 64GB の高位アドレスまで埋めない。同じ理由で、Windows デスクトップ用途なら何か月も気づかなかった可能性が高い。LLM サーバという「メモリを使い切る」用途だからこそ 3 週間で炙り出せた、とも言えます。

証拠一式(journal のクラッシュ署名、BIOS 画面、memtest の写真)を添えてベンダーに連絡し、現在保証対応の手続き中です。

このシリーズの教訓をまとめると:

  1. ハードウェア故障はソフトウェアの顔でやってくる。ランダムな場所で毎回違う顔のクラッシュを見たら、ビット化けを容疑者に入れる
  2. 非 ECC メモリは黙って壊れる。検出も訂正も記録もされない。サーバ用途なら ECC は真剣に検討する価値がある
  3. journal の永続化は法医学の宝Storage=persistent にしておくだけで、電源断をまたいだ調査ができる
  4. 測ってから動く。「どうせ OC でしょ」で BIOS をいじり始めていたら、時間を溶かすか、偽の解決に騙されていた
  5. memtest が緑でも安心はできないが、赤なら一発で確定。そして今回のように、一晩どころか 1 分で答えが出ることもある

次回は番外編。この故障機を修理に送り出す準備をしたら、304GB のディスクのうち守る価値があるのはログ 2.8GB だけだったという、GitOps 運用の答え合わせの話です。

SEE ALSO

COMMENTS