~/home

Битая память, одна общая DLL и badmemorylist

· windows, железо

TL;DR: Случайные синие экраны Windows без единой ошибки WHEA оказались одним битым чипом на DDR4 без ECC. Одинаковые падения ILLEGAL_INSTRUCTION в одной общей DLL в разных процессах указали на плохую физическую страницу, MemTest86 это подтвердил, а bcdedit /set {badmemory} badmemorylist исключил эти страницы.

Два месяца случайных синих экранов, и у каждого свой stop-код: битые PTE, CRITICAL_PROCESS_DIED, порча LIST_ENTRY, page fault'ы. Плюс несколько жёстких перезагрузок вообще без bugcheck. И ни одной ошибки WHEA.

Два неверных предположения

  • «Событий WHEA нет — значит, не память». У обычной памяти без ECC нет обнаружения ошибок. Перевёрнутый бит до WHEA просто не доходит.
  • «Падения идут пачками, а не нарастают постепенно — значит, не железо». Одна битая ячейка даёт пачку падений, как только на неё попадает активно используемая страница, и затихает, когда страница переезжает.

Что выдало проблему

Три не связанных между собой сервиса упали с ILLEGAL_INSTRUCTION по одному и тому же смещению в одной и той же общей DLL, а хэш DLL на диске сходился. Windows отображает одну физическую копию кода DLL во все процессы. Если этот фрейм битый, каждый процесс декодирует один и тот же мусор. После перезагрузки страница переехала, и падения прекратились.

Подтверждение

Windows Memory Diagnostic (mdsched) нашёл ошибки уже на первом проходе. MemTest86 насчитал 3278 ошибок за 4 прохода даже на медленной штатной частоте. На тест row hammer пришлось только 12%, так что дело не в пограничных таймингах. 148 битых адресов легли в 16 страниц тремя кластерами, и сбоили всегда одни и те же два бита. Это один чип.

Огораживаем битые страницы

Windows умеет не использовать конкретные номера физических страниц (PFN):

bcdedit /set {badmemory} badmemorylist 0x5EF3E0 0x5EF3E1 ...
bcdedit /enum {badmemory}

Каждый кластер я расширил до блока в 16 страниц, всего вышло 48. Потеря, которую не заметишь. Две вещи, которые надо знать:

  • /set заменяет список целиком. Чтобы потом добавить страницы, заново перечислите и все старые.
  • Запишите, где лежат кластеры. Если следующее падение придётся на адрес вне их, чип деградирует, и одного списка уже мало. У меня так и вышло через два месяца, так что новая планка уже в списке покупок.