私はメモリデバイスの不揮発性メモリ制御やホストIFなどを扱うソフト屋をやっております。
仕事でCXL(Compute Express Link)まわりの技術に関わっています。
CXL技術に関連するメモ書きを残していこうと思います。
ホストのCPUとOS/Applicationまわりの経験・知識共に乏しいので、親切な方は教えて下さると幸いです。
また、間違い、アドバイス、その他、ご意見やご要望ありましたらお気軽にどうぞ。
今回は、Poison、およびPoisonの情報を取得するためのCXL.ioのコマンドについて、詳細を書きます。
1. Poison
一般的に、SSDなどで使用されているNANDフラッシュメモリなど、不揮発性メモリから読み出されたデータにはビット単位で誤りが含まれます。CXLメモリデバイスで使用される不揮発性メモリも同様に、読み出したデータには誤りが含まれると考えられます。
そこで、SSDのメモリコントローラと同様に、CXLメモリデバイスで不揮発性メモリを扱うメモリコントローラは、ECC(Error Correction Code)等を使用し、読み出したデータの誤り訂正を行い、訂正したデータをホストシステムに返す動作をすることになります。
不揮発性メモリから読み出されたデータに、コントローラの誤り訂正能力を超えたビット数の誤りが含まれる場合、データには誤りが含まれたままの状態となります。CXLの仕様では、コントローラの誤り訂正能力を超える誤りが含まれるデータは、Poisonの状態として扱うよう定められています。
余談ですが、SSDでは訂正不可が発生する確率は、JEDECでUBER(Uncorrectable Bit Error Rate)で定義されており、コンシューマ向けのSSDではUBER $\leq 10^{-15}$、エンタープライズ向けのSSDではUBER $\leq 10^{-16}$、が基準となっています。
参考: [JEDEC SSD Specifications Explained][1]
[1]:https://www.jedec.org/sites/default/files/Alvin_Cox%20%5BCompatibility%20Mode%5D_0.pdf
CXL.memのMemRdDataコマンドでPoisonが発生した場合の処理の流れの例を下図に示します。

CXLメモリデバイスにおいて、CXL.memのデータ読み出しコマンド(MemRd/MemRdData)に対する処理で、データがPoisonの状態となった場合、Data ResponseでPoisonであることを示し、データを返します。CXLメモリデバイスでは、Poisonとなったデータは、以降、書き込みコマンド(MemWr/MemWrPtl)で64Bの全てが上書きされるまで、Poisonの状態として扱われます。Poisonの状態は、CXLメモリモジュールの電源OFF/ONの状態に関係なく継続されるため、CXLメモリデバイスでは、データとPoisonの状態を紐づけて不揮発性メモリにデータを記録します。
CXLの仕様では、CXLメモリデバイスは、Poisonの発生をGeneral Media Event Recordで保持してイベントとして通知すること、Poisonの状態となったデータのアドレスをPoison Listとして保持しすることが定められています。General Media Event RecordはGet Event Recordコマンド、Poison ListはGet Poison Listコマンドでホストシステムに送信します。
Poisonの状態となったデータをどう扱うかはホストシステムが決定し、データに対して必要な処理を行います。CXLメモリデバイスとしては、Poisonの状態になったデータを救うことはできませんので、前述の通り、ホストシステムからデータの書き換えがあるまでPoisonの状態として扱い続けます。
2. Media and Poison Management Command Set
CXL.ioで実行するコマンドには、Poison Listの取得など、Poisonが発生したデータを管理するためのコマンドセットとして、Media and Poison Managementコマンドセットが定められています。
下表に、Media and Poison Managementコマンドセットを構成するコマンドを示します。
| Command | Required | 概要 |
|---|---|---|
| Get Poison List | PM | Poison Listの取得をする。 |
| Inject Poison | O | 指定したアドレスのデータをPoisonの扱いにする。 |
| Clear Poison | O | 指定したアドレスのデータを上書きし、Poisonの状態をクリアする。 |
| Get Scan Media Capabilities | PM | 指定したアドレスの範囲をスキャンするために掛かる時間を取得する。 |
| Scan Media | PM | 指定したアドレスの範囲のスキャンを実行する。 |
| Get Scan Media Results | PM | スキャンの実行結果を取得する。 |
| 表中の「PM」は、記録媒体に不揮発性メモリを使用するCXLメモリデバイスの場合はMandatoryであることを示します。 |
Inject PoisonコマンドとClear Poisonコマンドは、主に、ホストシステムの動作検証の一環として使用されるコマンドです。ホストシステムが、Inject Poisonコマンドの実行を指示すると、CXLメモリデバイスは、指定されたアドレスのデータをPoisonの状態として扱い、Poisonの発生時に行われる一連の処理を実行します。これにより、ホストシステムは、Poisonが発生時にホストシステムで行う処理の動作検証を行うことができます。
Scan Mediaコマンドは、誤り訂正ができないデータの存在するアドレスの検出に使用されます。
CXLメモリデバイスは、ホストシステムからScan Mediaコマンドの実行が指示されると、メモリコントローラでメモリのデータを読み出して誤り訂正の可不可を判別し、不可となったアドレスをPoison Listに記録します。
Scan Mediaコマンドの実行中も、CXLメモリデバイスはホストCPUからのデータ書き込み・読み出しコマンドは受付可能であるため、Scan Mediaコマンドの実行によるメモリアクセスと、ホストCPUからのデータ書き込み・読み出しコマンドの実行のためのメモリアクセスとが衝突し、データ書き込み・読み出しの性能低下を引き起こす可能性があります。
そのため、CXLの仕様では、Scan Mediaコマンドの実行は、Poison Listがオーバーフローした場合にのみ実行することが推奨されています。
Media and Poison Managementコマンドセットで扱われるPoison Listに記録されるデータのフォーマットを下表に示します。
Poison Listでは、下表に示すデータを1つのエントリとして扱われます。複数のデータがPoisonの状態である場合は、Poison Listに複数のエントリが含まれます。
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | 記録されたデータがPoisonの状態のアドレスとPoisonの発生要因。 Bit[2:0]: Poisonの発生要因を示す 000b = 不明 001b = External(ホストCPUによるPoison=1でのデータ書き込みによるPoison) 010b = Internal(CXLデバイス内部の誤り訂正不可の発生によるPoison) 011b = Injected(Poison Injectコマンドの実行によるPoison) 111b = Vendor Specific Bit[5:3]: Reserved Bit[63:6]: アドレス[63:6] |
| 08h | 4 | データがPoisonの状態である隣接するアドレスの数。 |
| 0Ch | 4 | Reserved |
2.1 コマンドパラメータ
Media and Poison Managementコマンドセットで定義されるコマンドの詳細を示します。
コマンドで指定するパラメータをInput Payload、応答として返されるパラメータをOutput Payloadで記載します。
2.1.1 Get Poison List
先頭アドレスと先頭からのアドレス数で範囲を指定し、範囲内に含まれるPoisonの状態データが記録されているアドレスのリスト(Poison List)を取得する。
Input Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | 取得するPoison Listの範囲の先頭アドレス。 |
| 08h | 8 | 取得するPoison Listの範囲のアドレス数。 |
Output Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 1 | Poison Listの状態を示すフラグ。 Bit[0]: CXLメモリデバイスが保持するPoison ListのサイズがMailboxレジスタに収まらないため、複数回の読み出しが必要であることを示す Bit[1]: Poisonの状態のデータが記録されているアドレsの下図が、Poison Listで保持することが可能なアドレス数を超えていること(オーバーフロー)を示す Bit[2]: Scan Mediaの実行中であり、Poison Listが更新される可能性があることを示す |
| 01h | 1 | Reserved |
| 02h | 8 | Poison Listのオーバーフロー発生時のタイムスタンプ。 |
| 0Ah | 2 | Poison Listに含まれるアドレスの数。 |
| 0Ch | 20 | Reserved |
| 20h | Varies | Poison List |
2.1.2 Inject Poison
指定したアドレスのデータをPoisonの状態にする。
Input Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | データをPoisonの状態にするアドレス。 |
2.1.3 Clear Poison
指定したアドレスのデータを上書きし、Poisonの状態をクリアする。
Input Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | データのPoisonの状態をクリアするアドレス。 |
| 08h | 64 | 上書きするデータ(64B)。 |
2.1.4 Get Scan Media Capabilities
指定した範囲のアドレスのスキャンを実行した場合に完了までに掛かる時間を取得する。
Input Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | スキャンする範囲の先頭アドレス。 |
| 08h | 8 | スキャンする範囲(アドレスの数)。 |
Output Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 4 | スキャン完了までに掛かる時間(推定)。 |
2.1.5 Scan Media
指定された範囲のアドレスのスキャンをし、検出されたアドレスをPoison Listに追加する。
スキャン中に、保持できるPoison Listの容量がフルになった場合、スキャンは中断される。
Input Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | スキャンする範囲の先頭アドレス。 |
| 08h | 8 | スキャンする範囲(アドレスの数)。 |
| 10h | 1 | スキャン実行に関するパラメータを設定する。 Bit[0]: スキャンで検出されたPoisonをGeneral Media Event Recordに記録をすることを禁止する |
2.1.6 Get Scan Media Results
スキャンの実行結果とPoison Listを取得する。
Output Payload
| Byte Offset | Length | Description |
|---|---|---|
| 00h | 8 | 中断されたスキャンを再開する場合に、ホストシステムが先頭アドレスとして指定すべきアドレス。 |
| 08h | 8 | スキャンの中断によりスキャンされなかった範囲(アドレスの数)。 |
| 10h | 1 | Poison Listの状態とスキャンの中断の有無を示すフラグ。 Bit[0]: CXLメモリデバイスが保持するPoison ListのサイズがMailboxレジスタに収まらないため、複数回の読み出しが必要であることを示す Bit[1]: Poison Listがフルになり、スキャンが中断されたことを示す |
| 11h | 1 | Reserved |
| 12h | 2 | Poison Listに含まれるアドレスの数。 |
| 14h | 12 | Reserved |
| 20h | Varies | Poison List |
次回は、CXLメモリデバイスのHealth Infoについてと、Health Infoの取得コマンドについて書こうと考えています。