CXL (Compute Express Link) その15 - QoSとCXL.ioコマンド: SLD QoS Telemetry

私はメモリデバイスの不揮発性メモリ制御やホストIFなどを扱うソフト屋をやっております。
仕事でCXL(Compute Express Link)まわりの技術に関わっています。
CXL技術に関連するメモ書きを残していこうと思います。
ホストのCPUとOS/Applicationまわりの経験・知識共に乏しいので、親切な方は教えて下さると幸いです。
また、間違い、アドバイス、その他、ご意見やご要望ありましたらお気軽にどうぞ。

---
CXLメモリデバイスのQoSについてと、QoSの設定に関する設定と情報取得のコマンドについて書きます。

# 1. QoS (Quality of Service)
CXLのQoSでは、CLXメモリデバイスで行われているコマンド処理の負荷の状態に関する情報が扱われます。
ホストCPUは、CXLデバイスのCXL.memのレスポンスでQoSの情報を取得することができます。またホストシステムは、CXL.ioのコマンドで、CXLデバイスでコマンド処理の負荷の状態を判断するために使用する情報に関する設定をすることができます。
なお、QoSに関する仕様はCXL2.0以降の仕様で定められています。

CXLその7の記事で触れていますが、CXLメモリデバイスは、ホストCPUへの応答であるNo Data Response、もしくはData ResponseでQoSを通知します。ホストCPUは、CXLメモリデバイスから取得したQoSの情報を利用し、CXLメモリデバイスへ発行するRead/Writeコマンドの時間間隔や発行順序を動的に制御・調整します。

CXL.ioでは、SLD対応のCXLメモリデバイスの場合には、SLD QoS Telemetryコマンドセットが定義され、CXLメモリデバイスがコマンド処理の負荷の状態を判断するために使用する情報に関して、設定をすることができます。MLD対応のCXLメモリデバイスについては、この記事では触れません。

# 1.1. CXL.memによるQoSの通知
No Data Response、もしくはData ResponseでQoSとして通知されるのは、Device Loadと呼ばれるパラメータです。
Device Loadでは、下表の3つの状態のうちいずれかの状態が通知されます。

| Device Load | Description | 
|:--|:--|
| Light Load | 軽い負荷の状態 |
| Optimal Load | 最適な負荷の状態 |
| Moderate Overload | 中程度の過負荷の状態 |
| Severe Overload | 重度の過負荷の状態 |

一般的なCXLメモリデバイスで想定される性能と、Device Loadで通知される負荷の状態との対応を下図に示します。グラフは、横軸が帯域、縦軸がコマンド毎の平均レイテンシを表しています。
ホストCPUからのコマンド発行の時間間隔が短くなると、消費される帯域が高くなりレイテンシは徐々に上がります(Light Load、Optimal Load)。
さらにコマンド発行間隔が短くなり、CXLメモリデバイスでのコマンドの処理が追い付かなくなると、コマンドはキューに溜められて処理の開始までの待ち時間が長くなるため、レイテンシは急激に上がります(Moderate Overload、Severe Overload)。
![performance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292852/0cf40278-1bf4-1588-d09a-25bef580d6e8.png)
一般的なCXLメモリデバイスの性能測定結果は、DDRで接続されたDRAMの性能測定結果と同様の結果となることが想定されるため、上図で示す形状のグラフになります。CXLメモリデバイスの製品により、帯域やレイテンシのスケールに違いがでるかと思います。

ホストCPUは、接続されたCXLメモリデバイスをOptimal Loadの状態で運用すると、帯域とレイテンシのバランスが取れた状態で使用することができます。

## 1.2. ホストによるDevice Loadへの対応

CXLの仕様書では、ホストCPUは、CXLメモリデバイスから通知されるDevice Loadへの対応として、下表に示される対応をすることが強く推奨されています。

| Device Load | Description |
|:--|:--|
| Light Load | 「Throttle[Range] -= NormalDelta」の時間間隔でコマンド数を調整 |
| Optimal Load | 調整をしない |
| Moderate Overload | 「Throttle[Range] += NormalDelta」の時間間隔でコマンド数を調整 |
| Severe Overload | 「Throttle[Range] += SevereDelta」の時間間隔でコマンド数を調整 |

要約すると、CXLメモリデバイスの負荷が軽い場合は短い時間間隔で発行するコマンド数を多くして負荷を上げ、負荷が重い場合は長い時間間隔で発行するコマンド数を少なくして負荷を下げるということになると思います。
結果として、Device LoadがModerate Overload/Severe Overloadの場合はOptimal Loadに戻し、Light Loadの場合はOptimal Loadに上げることになります。

Throttle[Range]、NormalDelta、SevereDeltaは、システムに依存する時間です。Throttle[Range]は、数百nsec程度の想定となっています。

## 1.3. CXL.ioによるQoSに関する設定
CXLの仕様書では、ホストCPUに通知されるDevice Loadを決める要因として、Internal Loading、Egress Port Congestion State、Temporary Throughput Reduction Stateが挙げられています。

それぞれを下図で説明します。下図は、CXLメモリデバイスのコントローラが共通して持つと想定されるキューと、キューが含まれるブロックの概略図です。CXLメモリデバイスの実装に依存しますが、実際のコントローラには、下図で示すよりも多くの数のキューやバッファが存在します。
![QoS_elements.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292852/73c92770-f19c-e9d7-5b4f-b1a90725aea3.png)
CXLメモリデバイスは、Ingress Portで受け付けたコマンドをDownstream traffic queueでキューイングし、ホストCPUが指定したアドレスを内部の物理アドレスへの変換等メモリアクセスを行うための処理を行い、Memory PortのInternal request queueでキューイングします。
Memory PortのInternal request queueでキューイングした処理は、それぞれの処理がメモリアクセスで衝突をしないよう順に処理を行います。Internal request queueでキューイングされる処理は、Ingress Portで受け付けたホストCPUからのコマンドから発生する処理だけではなく、メモリのリフレッシュなどのコントローラが自発的に行う処理が含まれます。メモリアクセスに関連する処理が完了し、ホストCPUに返す処理が必要な場合はEgress PortのUpstream traffci queueにキューイングします。
Egress PortのUpstream traffic queueでキューイングされている処理は、ホストCPUの受信側のキューに空きの状況に応じて順次処理されます。

CXLの仕様書では、Memory PortのInternal request queueに溜まっている処理の数などで判断される内部処理の負荷の状態をInternal Loadingと呼んでいます。また、メモリのリフレッシュなどのコントローラが自発的に行う処理の負荷により、ホストCPUへの帯域やレイテンシへの影響が出る状態をTemporary Throughput Reduction Stateと呼んでいます。

Egress Port Congestion Stateは、Upstream traffic queueに溜まっている処理の数をもとに判断される負荷の状態です。ホストCPUの受信側に十分な空きがある場合は、Upstream traffic queueに処理が溜まることはありません。
ただし、ホストCPUの受信側に空きがないと、Upstream traffic queueに処理が溜まり、結果として、Memory Portでの処理が終ってもEgress Portに出力できず、ホストCPUからCXLメモリデバイスからの応答が遅く見えてしまうことになります。

CXLメモリデバイスは、主にInternal Loadingを元にDevice Loadを決定し、ホストCPUに通知しますが、ホストシステムは、SLD QoS TelemetryコマンドセットでDevice Loadを決定するための要因に、Egress Port Congestion StateとTemporary Throughput Reductionを設定することができます。

ホストシステムからEgress Port Congestion Stateを設定することにより、Internal Loadingの負荷が軽くてもEgress PortのUpstream traffic queueに処理が溜まっていれば、Device Loadとして、Moderate OverloadやSevere Overloadを返すようにすることができます。
また、Temporary Throughput Reduction Stateを設定することにより、CXLメモリデバイスは、リフレッシュなどコントローラが自発的に行う処理の負荷が高くなることが想定されると、ホストCPUから指示されたコマンド処理の負荷が軽い場合でもoderate OverloadやSevere Overloadを返すようにすることができます。

# 2. SLD QoS Telemetry Command Set
SLD QoS Telemetry Commandコマンドセットには、下表に示す3つのコマンドが定義されています。
| Command | Required | 概要 |
|:--|:-:|:--|
| Get SLD QoS Control | O | Egress Port、Temporary Throughput Reductionの有効化状況を取得する。 |
| Set SLD QoS Control | O |Egress Port、Temporary Throughput Reductionの有効化する。 | 
| Get SLD QoS Status | O | Egress Port Congestion Stateを取得する。 |

## 2.1. コマンドパラメータ
SLD QoS Telemetry Commandコマンドセットで定義されるコマンドの詳細を示します。
ホストシステムがコマンドで指定するパラメータをInput Payload、ホストシステムに応答として返されるパラメータをOutput Payloadで記載します。

### 2.1.1. Get SLD QoS Control

Get SLD QoS Controlコマンドでは、Egress Port Congestion StateとTemporary Throughput Reduction Stateの設定に関する情報を取得します。

***Output Payload***
| Byte Offset | Length | Description |
|--:|--:|:--|
| 0 | 1 | QoS Telemetry Control<br>Bit[0] Egress Port Congestion Enable:<br>　Device Loadの状態の判断に、Egress Port Congestion Stateを使用することを有効化されているかを示す<br>Bit[1] Temporary Throughput Reduction Enable:<br>　Device Loadの状態の判断に、Temporary Throughput Reduction Stateを使用することを有効化されているかを示す|
| 1 | 1 | Egress Moderate Percentage:<br>　Egress Port Congestion Stateの状態をModerate Overloadと判断する閾値を示す。|
| 2 | 1 | Egress Severe Percentage:<br>　Egress Port Congestion Stateの状態をSevere Overloadと判断する閾値をしめす。|
| 3 | 1 | Backpressure Sample Interval:<br>　Egress Port Congestion Stateの状態の判断を行う時間間隔を示す。|

### 2.1.2 Set SLD QoS Control

Set SLD QoS Controlコマンドでは、Egress Port Congestion StateとTemporary Throughput Reduction Stateの設定をします。

Input Payloadで設定されるパラメータのフォーマットは、Get SLD QoS ControlコマンドのOutput Payloadと同様のため省略します。

### 2.1.3 Get SLD QoS Status
Get SLD QoS Statusコマンドでは、Egress Port Congestion Stateの状態を取得します。

***Output Payload***
| Byte Offset | Length | Description |
|--:|--:|:--|
| 0 | 1 | Backpressure Average Percentage:<br>　Egress Port Congestion Stateの状態(%)を示す。|

---