NVMe Directives 與 Streams:從主機分組到寫入與資源管理
00.01.這篇說明主機如何把「哪些資料屬於同一組」告訴 SSD。先建立主機、控制器、namespace 與串流的關係,再走過能力查詢、啟用、資源配置、Write 與釋放;最後看相同編號在不同路徑下的含義,以及 SWS/SGS 如何影響資料安排。
- namespace
- namespace,主機透過 controller 存取的一份已格式化非揮發性容量。
- SGS
- Stream Granularity Size;以 SWS 為單位表示媒體配置的粒度大小。
- SWS
- Stream Write Size;在 NVM Command Set 以 logical blocks 表示最佳寫入的對齊與大小單位。
這篇的主軸
資料分組的目的
01-01Stream Identifier 為寫入補上資料關聯,LBA 仍決定寫入位置。先理解這個分工,才不會把串流當成另一個 namespace。
- Stream Identifier
- 串流編號;主機選擇的 16-bit 標記,其意義還取決於 namespace、主機身分與共享設定。
管理流程與資料流
02-01查能力、登記身分、啟用功能與配置資源是準備工作;真正使用串流的是帶標記的 Write。管理命令不必跟每一筆資料同步重送。
身分與資源的共享範圍
03-01Host Identifier 與 SSID 決定哪些路徑共用串流;NSA、NSSA、NSO 則區分容量、資源池與目前使用狀態。
- Host Identifier
- 主機識別值;用來判斷不同控制器是否服務同一主機,與串流編號不同。
- Host
- 主機;執行作業系統並送出 NVMe 命令的一端。
- NSSA
- NVM Subsystem Streams Available;未分配成 namespace 專用的資源池大小,不等於其中完全閒置的數量。
- SSID
- Shared Stream Identifiers;決定不同非零主機身分是否可共享同一 namespace 的同號串流。
- NSA
- Namespace Streams Allocated;指定 namespace 與可見主機關聯下的專用配置數,也用於 Allocate 的完成回覆。
- NSO
- Namespace Streams Open;指定 namespace 與可見主機關聯下的開啟串流數。
大小安排與生命週期
04-01SWS/SGS 協助安排寫入與解除配置;Release、停用及 reset 決定追蹤狀態何時結束,這和使用者資料是否仍存在不同。
00.02.讀者只需有 OS、Computer Organization 與 SSD 基本概念。本文以 PCIe 控制器為情境,完整涵蓋指定 Directives/Streams 範圍;Data Placement §8.1.9.4 不展開。例子的數量、LBA 與主機 A/B 是說明性設定,實際能力以裝置回覆為準。
- Directives
- 主機與控制器交換附加資訊的機制;依類型定義查詢、設定與 I/O 附加資訊。
- Streams
- 以串流編號標示相關寫入資料的 Directive;不直接指定 NAND 實體位置。
- PCIe
- PCI Express,NVMe memory-based controller 使用的 transport 與裝置互連。
把主軸連起來
00.03.可以把這篇想成一次完整的資料使用週期:先決定哪幾筆資料有關,再確認控制器支援、各路徑的主機身分與啟用狀態,接著選擇資源來源。Write 帶入編號時才產生串流活動;資料不再屬於這次群組時,再結束編號的使用。
00.04.兩個數字相同不一定代表同一件事:相同 Stream Identifier 可能屬於不同主機,SWS=8 與 NSA=8 更分別是資料大小和資源個數。後面的例子會逐步固定其他條件,只改一項設定,觀察意義如何變化。
開著 Spec 的報告路徑
R-1先用本文的例子建立全貌,再開 Base PDF 第 227 頁。下面依實際 PDF 頁碼往後走,最後只切換一次到 NVM。章節共用同一頁時,以標題為停止位置;不要使用目錄中的舊頁碼代替 PDF 檢視器頁碼。
- NVM
- Non-Volatile Memory,斷電後仍能保存資料的記憶體。
| 翻頁順序 | 章節 | 在這裡講清楚什麼 |
|---|---|---|
| R1 · Base PDF 227–228 | §5.2.7 → §5.2.8 | 先比較 Receive/Send 的 DPTR、NUMD、DTYPE/DOPER;在 §5.2.9 Firmware Commit 前停下。 |
| R2 · Base PDF 534–536 | §5.2.30.1.35 → .35.1 | 讀 Host Identifier 與 PCIe 規則:EXHID、HOSTID、0h、非零身分、不可保存;在 .35.2 標題前停下。 |
| R3 · Base PDF 642–646 | §8.1.9 → §8.1.9.2 | 從 Directives 標題開始;用 702/703 看類型,再用 704–707 看查詢與啟用。 |
| R4 · Base PDF 646–653 | §8.1.9.3 | 708 大小組成 → 709 操作 → 710 共享 → 711–715 參數/狀態/配置 → 兩個 Release;在 §8.1.9.4 前停下。 |
| R5 · NVM PDF 175 | §5.13 | 確認 SWS 的單位是 logical blocks,帶入 4 KiB、SWS=8、SGS=4 完成換算。 |
- HOSTID
- Host Identifier 資料結構中的實際身分值。
- DOPER
- Directive Operation;在所選類型與命令方向下,指定要執行的操作。
- DTYPE
- Directive Type;選 Directive 類型。Enable 的外層操作類型與內層目標類型必須分開讀。
- EXHID
- Enable Extended Host Identifier;0 選 64-bit,1 選 128-bit 身分格式。
- DPTR
- Data Pointer,SQE 中指出 command data buffer 的欄位。
- NUMD
- Number of Dwords;有資料傳輸時,欄位保存 4-byte 單位的數量減 1。
01 先理解 Streams 要解決什麼問題
- 查 Directives/Streams 支援;先登記適用的非零 Host Identifier。
- 透過 Identify Directive 啟用 Streams;確認狀態與參數。
- 選擇專用或 subsystem 資源;需要專用容量時請求配置並讀實際授予數。
- Write 帶 Stream Identifier;第一筆使用未開啟編號的寫入會開啟串流。
- Get Status 看開啟編號;用 Release Identifier 結束分組,用 Release Resources 歸還專用配置。
01.01.Directives 讓主機與控制器交換額外資訊。Streams 用主機指定的 Stream Identifier,指出哪些寫入資料屬於同一組;控制器可利用分組改善資料配置或效能,但這個編號不直接指定 NAND 的實體位置。
來源:Base 2.4 §8.1.9, 8.1.9.1, 8.1.9.3
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9, 8.1.9.1, 8.1.9.3, 文件頁 616-623, PDF 頁 642-649
02 先讓控制器知道哪些路徑屬於同一主機
02.01.FID 81h 登記 Host Identifier,讓同一 NVM subsystem 內的控制器辨認共同主機。相同非零值可建立共同身分;0h 則表示不與其他控制器建立這種關聯。PCIe 的預設值為 0h,此 Feature 不可保存。
- NVM subsystem
- NVM subsystem,包含 controller、port、namespace 與非揮發性儲存資源的 NVMe 系統邊界。
- FID
- Feature Identifier;指定要讀取或設定哪一項 Feature 的編號。
來源:Base 2.4 §5.2.30.1.35, 5.2.30.1.35.1
來源:NVME-BASE-2.4, Rev. 2.4, §5.2.30.1.35, 5.2.30.1.35.1, 文件頁 508-510, PDF 頁 534-536
03 查支援、登記身分,再啟用 Streams
- ENDIR
- Enable Directive;1 要求啟用,0 要求停用 CDW12 選定的類型。
- CDW
- CDW(Command Dword);命令中的 32-bit 欄位單位,例如 CDW10 的 10 是欄位 index,不是 byte offset。
03.01.先由 OACS.DIRS 確認 Directives,再用 Identify Directive 查 Streams 是否支援與啟用。Enable Directive 的 CDW11 選 Identify 操作,CDW12 才選要啟用的 Streams;namespace 與 Host Identifier 一起決定共享的啟用狀態。
- DIRS
- Directives Supported;OACS 中的 Directives 整體支援位元。
來源:Base 2.4 §8.1.9, 8.1.9.2, 8.1.9.3
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9, 8.1.9.2, 8.1.9.3, 文件頁 616-624, PDF 頁 642-650
04 讀懂 Directive 命令的欄位與資料方向
04.01.Directive Receive 的資料由控制器送往主機,Directive Send 則相反;實際是否有資料傳輸取決於操作。CDW11 用 DTYPE/DOPER 選操作,DSPEC 的含義由類型決定;需要 buffer 時,NUMD 是 Dword 數量減 1。
- buffer
- 記憶體緩衝區;主機準備用來提供或接收資料的空間。
- DSPEC
- Directive Specific;含義由類型和操作決定,在 Streams 的 I/O 中放串流編號。
- Dword
- Dword(Double word);32 bits,也就是 4 bytes。對比 word=16 bits;例如 zero-based dword count=3 代表 4 個 Dwords,也就是 16 bytes。
來源:Base 2.4 §5.2.7, 5.2.8
來源:NVME-BASE-2.4, Rev. 2.4, §5.2.7, 5.2.8, 文件頁 201-202, PDF 頁 227-228
05 配置多少資源,與開了幾條串流分開看
- NSSO
- NVM Subsystem Streams Open;使用非專用資源池的開啟串流數。
- MSL
- Max Streams Limit;整個 NVM subsystem 同時開啟串流的上限。
05.01.Streams 可使用 namespace 的專用資源,或使用尚未專用配置的 subsystem 資源。Allocate Resources 要求的是可同時追蹤的數量,回覆 NSA 可以小於 NSR;真正開啟串流,是後續 Write 使用尚未開啟的編號時。
- NSR
- Namespace Streams Requested;主機要求的專用資源數,直接計數。
來源:Base 2.4 §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.3
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.3, 文件頁 621-626, PDF 頁 647-652
06 同一個 Stream Identifier,到底是不是同一條串流
| 控制器路徑 | 非零 Host Identifier | SSID=0 的串流分組 | SSID=1 的串流分組 |
|---|---|---|---|
| C1 | A | A / 7 | 7 |
| C2 | A | A / 7 | 7 |
| C3 | B | B / 7 | 7 |
| C4 | C | C / 7 | 7 |
06.01.Stream Identifier 的意義要連同 namespace、Host Identifier 與 NSSC.SSID 判斷。SSID=0 時,不同非零主機身分的同號串流彼此獨立;SSID=1 時,同一 namespace 的同號串流可由不同非零主機身分共享。
- NSSC
- NVM Subsystem Stream Capability;包含主機身分要求與串流共享能力。
來源:Base 2.4 §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.2
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.2, 文件頁 621-626, PDF 頁 647-652
07 把一筆 Write 接到串流
07.01.使用 Streams 的 Write 指定 DTYPE=1、DSPEC=非零 Stream Identifier;首次使用尚未開啟的編號時,控制器開啟串流。DTYPE=0 或 Streams 的 DSPEC=0 不使用串流分組;未啟用類型的處理還要看是否已有任何 I/O Directive 啟用。
- I/O
- Input/Output,對 namespace 執行資料輸入與輸出的操作類別。
來源:Base 2.4 §8.1.9.1, 8.1.9.3
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.1, 8.1.9.3, 文件頁 617-623, PDF 頁 643-649
08 把 SWS/SGS 換成實際的資料量
- logical block
- 邏輯區塊;namespace 可定址的基本單位,其資料大小由使用中的格式決定。
- granularity
- 粒度;用來安排寫入或配置的一個大小單位,不是資源個數。
08.01.NVM Command Set 的 SWS 以 logical blocks 為單位;SGS 則以 SWS 為單位。先用 namespace 的 logical block 大小換成 bytes,才能比較寫入對齊、傳輸長度與整組資料的解除配置範圍。
來源:NVM Command Set 1.3 §5.13
來源:NVME-NVM-CS-1.3, Rev. 1.3, §5.13, 文件頁 175, PDF 頁 175
09 觀察串流、結束使用與處理狀態變更
| 事件或操作 | 編號/開啟狀態 | 專用配置 | 資料本身 |
|---|---|---|---|
| Release Identifier | 結束指定編號的本次串流 | 保留給 namespace 重用 | 此操作不刪除資料 |
| Release Resources | 不可只用 NSA=0 推論全部編號狀態 | 歸還,NSA 清 0 | 此操作不刪除資料 |
| 停用 Streams | 釋放受影響主機的所有編號 | 釋放其資源 | 停用不是安全清除 |
| Format NVM | 釋放受影響 namespace 的開啟編號 | 不能從這條規則推論全部歸還 | 資料效果依 Format 操作 |
| 刪除/變成寫入保護 | 釋放 namespace 的全部編號 | 釋放全部串流資源 | 不能把追蹤清除等同媒體清除 |
09.01.Get Status 回報目前開啟的編號。Release Identifier 結束一個編號的本次串流關聯,專用資源仍可保留;Release Resources 歸還 namespace 的專用配置。停用、Format、刪除、寫入保護與 reset 則各有不同的狀態影響。
來源:Base 2.4 §8.1.9.2.2.1, 8.1.9.3, 8.1.9.3.1.2, 8.1.9.3.2
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.2.2.1, 8.1.9.3, 8.1.9.3.1.2, 8.1.9.3.2, 文件頁 619-627, PDF 頁 645-653
接著打開 Spec 看什麼
10.01.以下按概念列出閱讀位置。報告時先用上面的流程說明問題,再打開對應章節看欄位與完整條件。中文教學 HTML 另有本篇全部圖表的逐圖重點、案例與細節。
| 要說明的觀念 | Spec 閱讀位置 |
|---|---|
| 先理解 Streams 要解決什麼問題 | Base 2.4 §8.1.9, 8.1.9.1, 8.1.9.3 |
| 先讓控制器知道哪些路徑屬於同一主機 | Base 2.4 §5.2.30.1.35, 5.2.30.1.35.1 |
| 查支援、登記身分,再啟用 Streams | Base 2.4 §8.1.9, 8.1.9.2, 8.1.9.3 |
| 讀懂 Directive 命令的欄位與資料方向 | Base 2.4 §5.2.7, 5.2.8 |
| 配置多少資源,與開了幾條串流分開看 | Base 2.4 §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.3 |
| 同一個 Stream Identifier,到底是不是同一條串流 | Base 2.4 §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.2 |
| 把一筆 Write 接到串流 | Base 2.4 §8.1.9.1, 8.1.9.3 |
| 把 SWS/SGS 換成實際的資料量 | NVM 1.3 §5.13 |
| 觀察串流、結束使用與處理狀態變更 | Base 2.4 §8.1.9.2.2.1, 8.1.9.3, 8.1.9.3.1.2, 8.1.9.3.2 |
學完後想一想
1. SDIRS=1、NSA=3、NSO=0,這些值互相矛盾嗎?
11.01.不矛盾。它們分別是支援能力、已配置專用容量與目前開啟數。主機可以已啟用且配置容量,但還沒有用任何串流編號寫入。
來源
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9, 8.1.9.2, 8.1.9.3, 文件頁 616-624, PDF 頁 642-650
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.3, 文件頁 621-626, PDF 頁 647-652
2. C1、C2 都是 Host Identifier=0h,可否當成同一主機的 stream 7?
11.02.不能只因兩個值都是 0h 就合併。0h 表示不建立跨控制器主機關聯;先登記相同非零識別值,才符合共同主機的判斷前提。
來源
來源:NVME-BASE-2.4, Rev. 2.4, §5.2.30.1.35, 5.2.30.1.35.1, 文件頁 508-510, PDF 頁 534-536
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.2, 文件頁 621-626, PDF 頁 647-652
3. 已取得 3 個專用資源,再送 NSR=2,能變成 5 個嗎?
11.03.不能。已有專用配置時重複申請會被拒絕;要先歸還原配置,再請求完整的新數量,並檢查實際授予數。釋放一個編號不等於歸還整份配置。
來源
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.3, 8.1.9.3.1.1, 8.1.9.3.1.3, 文件頁 621-626, PDF 頁 647-652
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.2.2.1, 8.1.9.3, 8.1.9.3.1.2, 8.1.9.3.2, 文件頁 619-627, PDF 頁 645-653
4. 4 KiB/block、SWS=8、SGS=4,LBA 136 起的 16-block Write 與同起點解除配置,各符合哪個大小建議?
11.04.Write 的起點與長度都是 8 的倍數,符合 SWS;Stream Granularity 是 32 blocks,起點 136 與長度 16 都不是 32 的倍數,所以不符合該解除配置最佳化建議。這不是在宣告命令必須失敗。
來源
來源:NVME-NVM-CS-1.3, Rev. 1.3, §5.13, 文件頁 175, PDF 頁 175
5. 整體 Get Status 只列出一次編號 7,能證明只有一個 namespace 正在用它嗎?
11.05.不能。整體查詢只涵蓋非專用資源,跨 namespace 的重複編號只回一次。要知道某個 namespace 的狀態,需要用該 NSID 和正確主機關聯查詢。
來源
來源:NVME-BASE-2.4, Rev. 2.4, §8.1.9.2.2.1, 8.1.9.3, 8.1.9.3.1.2, 8.1.9.3.2, 文件頁 619-627, PDF 頁 645-653


Comments