NVMe仕様のS.M.A.R.T.属性(2/4)：「警告」分類の属性値

# はじめに
　[前回の記事](https://qiita.com/ken-yossy/items/3c5bc733d34450e452b6)で、最新NVMe基本仕様（リビジョン2.0b、以降単に「NVMe仕様」と記載）のSelf-Monitoring Analysis and Reporting Technology (S.M.A.R.T.)属性について、大まかに「警告」「現在値」「累積値」「設定値」に分類（※）して概要を説明しました。

　今回はそれらの属性のうち「警告」分類のものについてもう少し詳しく説明します。

　※注意：この分類は説明の便宜上私が作成したものです

# まとめ
* 「警告」分類のS.M.A.R.T.属性は、値が非ゼロであればほとんどの場合早急な対応が必要
* これらの属性値の変化時にドライブから通知を受ける仕組みはあるものの、残念ながらユーザがこの仕組みを直接利用するのは難しく、ツールの利用が現実的

# NVMe仕様における「警告」分類のS.M.A.R.T.属性
　NVMe仕様<sup>[1]</sup>に定義されたS.M.A.R.T.属性（正確には"SMART / Health Information"）のうち「警告」分類のものは、以下の2つです。

_表：NVMe仕様における「警告」分類のS.M.A.R.T.属性_
| 名称 | 分類 | 意味（概要） |
|----:|:----:|:--:|
| Critical Warning | 警告 | 警告有無表示 |
| Endurance Group Critical Warning Summary | 警告 | Endurance Group用警告有無表示 |

　この「警告」分類の属性はどちらもサイズが1バイト（8ビット）で、ビットマップ形式つまり属性値の各ビットが特定の状態や事象に対応します。

　Endurance Group Critical Warning Summaryという属性は、**Endurance Group**という機能の導入（NVMeリビジョン1.4で導入）に合わせて追加されました。

　Endurance Groupとは、多少雑な言いかたをすると「NVMeドライブの中に**寿命について独立した別のドライブを作成する**」機能です。

　つまり、Critical WarningはNVMeドライブ全体を対象とした、Endurance Group Critical Warning SummaryはEndurance Groupを対象とした、警告有無表示です。

　このため、Critical WarningとEndurance Group Critical Warning Summaryは、類似する現象のビット位置を一致させています。

　このことは、2つの属性をならべると良くわかります。

_表：Critical WarningとEndurance Group Critical Warning Summaryの内容比較_
| ビット | Critical Warning | Endurance Group Critical Warning Summary |
|----:|:----|:----|
| 7 | _（予約）_ | _（予約）_ |
| 6 | _（予約）_ | _（予約）_ |
| 5 | Persistent Memory RegionがRead-Only状態もしくは信頼度に問題がある | _（予約）_ |
| 4 | 揮発メモリのバックアップ機構に問題がある | _（予約）_ |
| 3 | メディアが**Read-Onlyモード**である | 1つ以上のEndurance Group内のNamespaceが**Read-Onlyモード**である |
| 2 | NVMサブシステムの**信頼度が低下**している | NVMサブシステムの信頼度低下により1つ以上のEndurance Groupの**信頼度が低下**している |
| 1 | 温度が上限閾値を超えたもしくは下限閾値より低下した | _（予約）_ |
| 0 | **予備領域量が下限閾値より低下した** | 1つ以上のEndurance Groupの**予備領域量が下限閾値より低下した** |

　同じビットに割り当てられた現象の説明中で、両属性で類似する部分を**太字**にしました。綺麗に一致させています。

# 各属性の内容
　それでは各属性の内容について説明します。

　なお、前節で説明した通りEndurance Group Critical Warning Summaryの各項目はCritical Warningの内容と同じで対象が異なるだけですので、Endurance Group Critical Warning Summaryについては説明しません。

　Critical WarningがNVMeドライブ全体を対象にしているところを、Endurance Group Critical Warning SummaryはEndurance Groupが対象だと読み替えればそのまま解釈可能です。

## Persistent Memory Region (PMR)異常
　ビット5は、Persistent Memory Region (PMR)という機能の状態を表示するビットです。

　PMRとは、NVMeドライブが備える不揮発なメモリ領域（＝Persistent Memory Region）をPCIeのアドレス空間に配置する機能です。

　この機能は、NVMeの読み書きコマンド単位サイズ（最小512バイト）よりも小さいサイズ（64バイトなど）で不揮発なメモリを読み書きしたいというホストの要望に応えて導入されました。

　ホストから見たPMRのメリットは、一般的なメモリと同様にロード(load)とストア(store)で読み書きできること（読み書きの単位サイズも小さい）、そしてPMRのデータはその名の通りドライブにより不揮発化されること、の2点です。

　PMRを備えるNVMeドライブにおいてPMRに異常が発生した場合に、このビットが1になります。

　具体的な異常としては、「読み出し専用に移行した」や「信頼性が低下した」などが挙げられます。後者の要因には、例えばPMRのデータを不揮発化するメモリのエラーが増加した、などが考えられます。

## 揮発メモリのバックアップ機構異常
　ビット4は、ドライブ内部の揮発メモリ(Volatile Memory)をバックアップする機構の状態を表示するビットです。

　例えば、SSD内部のSRAMやDRAM（SRAMやDRAM自体は揮発メモリ）上のデータを、不意の電源断時にNANDフラッシュメモリに書き込むための機構です。この機構のために必要な電力を蓄えるキャパシタを備える製品も存在します。

　上記例の場合、このビットが1になる異常には、キャパシタそのものの性能劣化（蓄えられる電気量の低下）だけでなく、キャパシタの蓄電量監視や充放電制御システムの故障も含まれます。

　ドライブが揮発メモリを搭載していてかつそのバックアップ機構が存在する場合、このビットが1であることは、何らかの現象によりバックアップが正しく機能せず揮発メモリ上のデータを失う可能性があることを示します。

　なお、ドライブがSRAMやDRAMを搭載していてもバックアップ機構が存在するとは限りません。製品仕様の確認が必要です。 

## 読み出し専用モード
　ビット3は、ドライブが読み出し専用(Read-Only)モードかどうかを示します。このビットが1であれば、ドライブは読み出し専用モードです。

　ドライブが読み出し専用モードになる理由は様々ですが、その原因は他の情報（ログなど）を取得するなどして特定する必要があります。

## 信頼度低下
　ビット2は、ドライブの信頼度が低下しているかどうかを示します。このビットが1であれば、ドライブの信頼度は低下しています。

　前節で説明した読み出し専用モード同様、ドライブの信頼度が低下する原因は数多くあります。またその深刻度も重大なものから軽微なものまで様々です。

　このため、このビットが1であることを検出したら、速やかに原因を究明して対処する必要があります。

## 温度異常
　ビット1は、SSDの温度に関する異常を示します。具体的には、SSDが報告する「SSDの温度」が以下の時にこのビットが1になります。

* 予め設定された上限閾値(over temperature threshold)を超過している
* 予め設定された下限閾値(under temperature threshold)を割り込んでいる

　上記2つの閾値は`Set Features`コマンドで設定可能です。

　SSDの温度が下図の網掛けの領域にある場合、このビットが1になります。

![温度異常ビットが1になる温度のイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/0a5f5686-8403-6235-add9-a60710210257.png "温度異常ビットが1になる温度のイメージ")
_図：温度異常ビットが1になる温度のイメージ_

　温度についてはいくつか注意が必要です。

　まず、ここで言う「SSDの温度」は _Composite Temperature_ と呼ばれるものでありSSDの表面温度などとは限らないことです。NVMe仕様ではComposite Temperatureの測定位置や方法を定めていません（実装依存）。このため、この「SSDの温度」が外部から測定可能とは限りません。

　また、上記2つの温度閾値は、NVMeが定めるサーマルスロットリングの制御のために参照される温度（TMT1やTMT2）とは異なります。

　NVMe仕様には温度に関する機能がいくつかありますが、それらの機能（動作）を制御する設定値（設定温度）はそれぞれの機能に専用の値が存在します。つまり、同じ温度とはいえ、異なる機能の設定値の間で整合性が取れているとは限りません。

　SSD、特に性能が高いNVMe SSDでは温度（高温）対策が重要です。これらの設定は慎重に行う必要があるとともに、もしこのビットが1であれば速やかに対応する必要があります。

## 予備領域量低下
　最後にビット0は、ドライブの予備容量が予め設定された閾値を割り込んでいるかどうかを示します。

　ちなみに、予備領域量の現在値(Available Spare)とその閾値(Available Spare Threshold)もS.M.A.R.T.属性として取得可能です。つまり、この予備領域量が閾値よりも小さい時にこのビットが1になります。

　手元にある数個のコンシューマNVMe SSDの予備領域量閾値を調べてみると以下の表のようになりました。たまたまですが、10%と5%のみでした。

_表：コンシューマ向けNVMe SSDの予備領域量閾値_
| メーカー | Available Spare Threshold |
|:--:|:--:|
| W社 | 0xA（10進数で10） |
| S社 | 0xA (10) |
| K社 | 0x5 (5) |
| K社 | 0x5 (5) |

　ただ、NVMe仕様上、この閾値をユーザが自由に設定する方法はありません。各ドライブメーカーが自社ドライブ向けに配布しているドライブ管理ソフトウェアなどでは設定変更が可能かもしれません（ベンダ固有コマンドを使用するなどして）。

　このビットが1に変化した場合、すぐにドライブが故障するわけではありませんが、ドライブの寿命が近いことを示すほか、最高性能を発揮できない・維持できない原因になるため、ドライブの交換などを考える必要があります。

# 属性値の変化を検出する方法
　以上のように、この「警告」分類のS.M.A.R.T.属性値はいずれも値が変化する（1になる）と速やかな対応が必要なものばかりです。

　では、この変化の検出にはS.M.A.R.T.属性をポーリングするしかないのでしょうか？

　実は、NVMe仕様にはこれらの属性値が変化した時にそのこと（＝イベント）をドライブからホストに通知する仕組みがあります。それが**Asynchronous Event**です。

　以下の図に、Critical Warningの変化をポーリングで検出する方法(A)とAsynchronous Eventを利用して知る方法(B)を示します。

![Critical Warningの変化を検出する2つの方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/195898b7-a396-100f-053c-61728d95f214.png "Critical Warningの変化を検出する2つの方法")
_図：Critical Warningの変化を検出する方法（A：ポーリング、B：Asynchronous Eventを活用）_

　ポーリングする方法(A)はホストが自分のタイミングでチェックできる点がメリットで、Asynchronous Eventを活用する方法(B)は実際にCritical Warningの変化が起きるまでホストは気にしないで良い点がメリットです。

　ただ、Windowsでは現時点でユーザはこのAsynchronous Eventを利用できないようです（OS内部で利用）<sup>[2]</sup>。ですので、ポーリングにより値の変化を検出したらユーザに通知してくれる[CrystalDiskInfo](https://crystalmark.info/ja/software/crystaldiskinfo/)などのツールを活用するのが現実的です。

# まとめ
　今回の記事では、NVMe基本仕様の最新版（リビジョン2.0b）に定義されているS.M.A.R.T.属性のうち、「警告」分類の属性の内容とその変化の検出方法を説明しました。

　この「警告」分類のS.M.A.R.T.属性は、値が非ゼロであればほとんどの場合早急な対応が必要です。ツールを利用するなどして値の変化を検出できるようにしておき、もし変化が起きた時には速やかな対応を取れるように準備しておくことが大切です。

　次回は、S.M.A.R.T.属性のうち「現在値」と「設定値」分類の属性について説明します。

# References
[1] NVM Express, _"NVM Express Base Specification,"_ Revision 2.0b, Jan. 2022
[2] Microsoft, _"[StorNVMe command set support](https://docs.microsoft.com/en-us/windows-hardware/drivers/storage/stornvme-command-set-support)"_, Retrieved on June 1, 2022
 
# ライセンス表記
<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>の下に提供されています。