SSDのSilent Data Corruptionとその対策(2/2)

# はじめに
　[前回の記事](https://qiita.com/ken-yossy/items/596bbc353320b8e0fc23)では、NANDフラッシュメモリをメディアとするSSD（以降単にSSDと記載）にまつわるSilent Data Corruption (SDC)と呼ばれるエラーのうち、NANDフラッシュメモリで発生するエラーとその対策を説明しました。

　今回の記事では、SSDを構成するNANDフラッシュメモリ以外の要素で起きる事象と対策を説明します。

# まとめ
* SRAMやDRAMのビット化けは誤り訂正符号(ECC)で対応する
* それ以外のデータの誤りは、バスでの誤りを含めて誤り検出機能（CRCなど）を用い、誤り検出時は再読出しで対応する
* ハードウェアだけでなくファームウェア(FW)要因でSDCが起こることもあり、適切な機能の設計と実装が必要

# サイレントエラーは何故悪なのか？
　ストレージデバイスにおけるサイレントエラーとは、データが不正に変更されたにもかかわらずエラーとして検出されない現象を指します。つまり、データが損傷していることに気づかず、システムが誤りを含むデータを正しいものとして処理してしまうエラーです。

　サイレントエラーが発生してそれを見過ごしてしまうと、ストレージデバイスは誤りを含むデータをホストに返してしまいます。これはストレージデバイスの誤動作であり何としても避けなければなりません。

　すなわちSDCを防ぐ仕組みとは、誤りを含むデータをホストに返さないための仕組み、誤りを発見したら適切に管理してホストには正直にエラーを申告するための仕組み、とも言えます。

　サイレントエラーは、運用中には検出されにくいですが、ストレージデバイスの評価やテスト段階でミスコンペアとして検出されることがあります。

# SSDのブロック図とSDCが起こり得る箇所
　以下の図1は典型的なSSDのブロック図です。ブロック図中の吹き出しで示した箇所が、NANDフラッシュメモリ以外でSDCが起こり得るSSD内の主要な箇所です。
 
![SSDの簡易ブロック図とSDCが起こり得る箇所](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/a8ad5864-a24e-12e5-9046-54ccafd8c3f2.png "SSDの簡易ブロック図とSDCが起こり得る箇所")
_図1：SSDの簡易ブロック図とSDCが起こり得る箇所_

　SSDコントローラは、これらの箇所で発生する可能性があるデータ化けに対して、その発生確率と用途をはじめとした製品仕様に基づいて対策を講じます。

　また、SDCが発生する要因には、図1に示したハードウェアだけでなくコントローラ上で動作するファームウェア(FW)のバグや設計不備も含まれます。
 
　この記事ではSSDが講じるそれらの対策について説明します。

# SRAMやDRAMのビット化け
**＜誤り訂正符号(ECC)で保護＞**

　SSDコントローラは、製品により容量の違いはあるもののSRAMを搭載しています。また、最近では搭載しない製品も多いですが、特に高いデータアクセス性能や高い信頼性を実現するSSDはDRAMを搭載します。

　このSRAMやDRAMに格納されるデータは、大きく2種類に分類できます。

　1つは主にSSDコントローラ内のプロセッサコアがアクセスするデータです。4バイトや8バイトなどの単位でアクセスされるデータです。

　もう1つは、NANDフラッシュメモリとの間で読み書きするデータです。こちらは512バイトとか4キロバイトさらには16キロバイト（NANDフラッシュメモリのページサイズ）などの単位でアクセスされるデータです。

　これらのデータは共に誤り訂正符号(ECC)で保護します。15年ほど前に私が設計に参画していたSSDコントローラでも既に1ビット誤り訂正2ビット誤り検出(SECDED)のECCを備えていました。

　製品により異なるものの、高い信頼性を求められるエンタープライズ向けやデータセンター向けそしてインダストリアル向けSSDではSRAMやDRAMのビット化け対策を搭載するのが一般的だと思われます。
 
　ソフトエラーの一種である中性子線（例えばα線）によるビット誤りは、正しい値をもう一度書き込む（リフレッシュする）までメモリセルから正しいデータを読み出せないため、誤り訂正できることが必要です。

　また、プロセッサコア上で動作するFWとしては1ビットの誤りが致命的な誤動作につながりかねないため、やはり誤り訂正できることが重要です。

# 各種バスなどでのエラー
**＜CRCなどの誤り検出符号による保護で対応＞**

　図1に示した通りSDCが起こり得る場所にはバスが含まれます。特に、NANDフラッシュメモリとの間でデータの送受信を行うバスで発生するエラーは、SSDとして致命的なエラーになる可能性があり、対策が必要です。

　SSDでは一般的に、このバスでのエラーをCRCなどによる誤り検出可能な符号で対応します。エラーの訂正機能は求めません。エラーを検出した場合は主にデータの再送で対応します。エラーの原因がバス上でのソフトエラーであれば、メモリから再読出しすればその転送時にはバス上でのエラーは生じない可能性が高いからです。ホストとSSD間のインターフェースが備える誤り検出機能と再送機能と同じような機能です。

　こちらの場合も、再送してもエラーが検出される場合には相応の対応が必要になります。

　それでは具体的な保護の仕組みを説明します。この記事では説明用に誤り検出符号としてCRCを使います。また、ここで記載した仕組みはあくまで一例であり、実際には製品により異なりますので注意してください。

## 基本的な仕組み

### SSDへのデータ書き込み時
　基本的な設計では、SSDへのデータ書き込み時、SSDコントローラは図2のような処理を行います。

![CRCによる誤り検出の仕組み（データ書き込み時）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/6aac921d-9c21-8565-11b4-a32bb8f057cf.png "CRCによる誤り検出の仕組み（データ書き込み時）")
_図2：CRCによる誤り検出の仕組み（データ書き込み時）_

　SSDコントローラはホストから受領したデータに対してすぐにCRCを付与します(CRC1)。そしてSSD内部では常にデータとCRCを組にして扱います。

　そしてNANDフラッシュメモリへ書き込む際に、データとCRCを合わせたデータに対してNANDフラッシュメモリ用の誤り訂正符号によるパリティを付与します。

### SSDからのデータ読み出し時
　一方SSDからのデータ読み出し時、SSDコントローラは図3のような検査を実施します。

![CRCによる誤り検出の仕組み（データ読み出し時）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/69a57bb2-8943-fff1-a184-aa798e3e83ce.png "CRCによる誤り検出の仕組み（データ読み出し時）")
_図3：CRCによる誤り検出の仕組み（データ読み出し時）_

　NANDフラッシュメモリから読み出したデータとCRCに対して誤り訂正を行い、再びデータとCRCを組にして扱います。

　そして、ホストインターフェースを経由してホストにデータを返す時にこれまで常にデータと組にしていたCRCを用いてデータに誤りがないかどうかを検査します。

　このような仕組みにより、NANDフラッシュメモリを除くSSD内部でデータにエラーが発生していないかどうかを検査できます。

## 構成要素別に保護する仕組み

　図2と図3の仕組みの場合、CRCによるチェックはホストにデータを転送する直前しか行わないため、エラーの発生場所がSRAM、DRAM、もしくはその他のバッファなのかが判別できません。
 
　エラーの発生場所を特定するためだけであれば検査箇所を増やせば良く、実際そのようにしている製品もあります。

　一方エンタープライズ向けSSDなど一部の製品では、各部品の特性に応じて個別に保護することがあります。

　本節ではその仕組みを説明します。

### SSDへのデータ書き込み時

　この仕組みでは、SSDへのデータ書き込み時、SSDコントローラは図4のような処理を行います。

![構成要素別に保護する仕組み（データ書き込み時）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/050720ef-97d5-c352-8120-a7481e06be42.png "構成要素別に保護する仕組み（データ書き込み時）")
_図4：構成要素別に保護する仕組み（データ書き込み時）_

　図2との違いは、CRCを増やすことで各CRCの担当範囲を限定してかつ各範囲で最適な仕組みを適用できるようにしていることです。

　ここでは簡単のためにCRCと記載していますが、実際に付与される検査用符号がCRCではないこともあり得ます。

　加えて特徴的なのはCRC3です。CRC3は、NANDフラッシュメモリ用誤り訂正符号による誤訂正を検出するために付与されるものです。

### SSDからのデータ読み出し時

　この仕組みでも、SSDからのデータ読み出し時に行う処理はCRCが増えたこと以外変わりません。

![構成要素別に保護する仕組み（データ読み出し時）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/c25e5903-d160-00de-c1c2-4b3a47853db3.png "構成要素別に保護する仕組み（データ読み出し時）")
_図5：構成要素別に保護する仕組み（データ読み出し時）_

　NANDフラッシュメモリから読み出したデータとCRC3に対して誤り訂正を行い、その後CRC3を用いて誤訂正が行われていないかどうかをチェックします。そしてCRC3を取り除き新たにCRC2を付与します。

　CRC2はデータがホストインターフェースに転送される直前の検査に用いられて除去され、CRC1が新しく付与されてホストインターフェースに送られます。そしてホストインターフェースからホストにデータが転送される時にCRC1による検査が行われます。

### NANDフラッシュメモリバスでのエラー検出用
　NANDフラッシュメモリバスのソフトエラー、例えば一時的なクロックずれによりデータと位置の対応がずれるなどの転送失敗を検出するには、SSDへのデータ書き込み時の処理フローを図4から図6のように変える必要があります。

![NANDフラッシュメモリバスでのエラーを検出可能な仕組み](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/cd0994cb-6acc-db9f-458d-e4fcc381e78b.png "NANDフラッシュメモリバスでのエラーを検出可能な仕組み")
_図6：NANDフラッシュメモリバスでのエラーを検出可能な仕組み（データ書き込み時）_

　図6のようにNANDフラッシュメモリバスの両端でCRCの付与および検査を行えば、NANDフラッシュメモリバスで発生したエラー（ソフトエラー含む）を検出可能です。

　NANDフラッシュメモリバスは低消費電力化や広帯域化が進みかつ実装密度も上がり続けていることから、何らかの信頼性向上策が求められています。

　この図6の方法はそれを実現する方法のひとつではあるのですが、これを実現するにはNANDフラッシュメモリ側もCRC計算回路を備える必要があり、なかなか実現が難しいです。

:::note info
2024年7月の時点では、NANDフラッシュメモリにはDDR5 DRAMに見られるようなWrite/Read CRC機能は実装されていません。
:::

　このバスの入口と出口におけるCRCの計算および付与と検査をどこまで厳密に行うかは、SSDが実現する信頼性の高さに応じて決まります。

### （参考）End-to-End Data Protectionが有効な場合
　NVMeやSASなどSCSI由来のストレージプロトコルには、ホストがデータに検査用データを付与してストレージに記録するEnd-to-End Data Protectionと呼ばれる機能があります（以前説明した記事は[こちら](https://qiita.com/ken-yossy/items/f7f458e41008eb224903)）。

　そのEnd-to-End Data Protectionが有効である場合、図4の仕組みは図7のようになります。

![End-to-End Data Protectionが有効なシステムでの検査の仕組み（データ書き込み時）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/178f3dac-caff-eea9-297d-20acec74c29d.png "End-to-End Data Protectionが有効なシステムでの検査の仕組み（データ書き込み時）")
_図7：End-to-End Data Protectionが有効なシステムでの検査の仕組み（データ書き込み時）_

　図7を見ると、ホストの付与したCRCが一番内側（データに近いところ）にあり、データがSSDの内部で移動する際には常にこのCRCがついて回ることがわかります。

　このホストが付与したCRCは、データ本体と合わせて、SSD内ではSSDコントローラが付与するCRCやその他の誤り訂正符号による保護が常に施された状態となります。

# ファームウェアのバグや設計不備によるSDC

　これまでに説明したハードウェア起因のエラーによるSDC以外に、ファームウェア(FW)の設計不備やバグにより発生したエラー（不具合）を要因とするSDCも考えられます。

　ひとつの例は、Garbage Collection (GC)などの内部処理時に、誤り訂正に失敗してデータを喪失するケースです。

　内部処理はホストから受領したコマンドに基づく処理ではないため、内部処理時に発生したこのデータ喪失はすぐにはホストに通知されません。つまりこのエラーもホストから見ると「サイレント」なエラーです。

　FWは（というかSSDとして）、このような事象が発生しないように、前回説明したパトロールやリフレッシュを適切な条件で実施する、RAIDなどのより強力な誤り訂正機構を実装する、などの対策を講じる必要があります。

　これらの機能がないとSDCが発生してしまいます。

　これらの機能を備えていてもデータ喪失が発生した場合にそのエラーを伝播（拡大）させないため、FWはデータが失われたことを適切に管理できることも必要です。

# おわりに
　この記事では、SSDにおけるSDCについて、NANDフラッシュメモリを除く部分で発生する事象とその対策を説明しました。
 
　具体的には、SSDが搭載するSRAMやDRAMで発生するエラーにはECCが、バスなどでのエラーにはエラー検出用の符号（CRCなど）が適用され、SSDとして切れ目のない保護を実現します。

　またFWにも適切な機能の設計と実装が求められます。

　もちろん、製品によりこれらの保護の有無や方法は異なります。使用するSSDが備える機能や実現する信頼性は、システム全体が実現すべき信頼性にあわせて定めることが重要です。

# ライセンス表記
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="クリエイティブ・コモンズ・ライセンス" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />この記事は<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンス</a>の下に提供されています。