NVMe over PCIe Transport 1.4:完整傳輸綁定
00.01.NVMe over PCIe Transport 說明 NVMe 的佇列、properties 與通知如何透過 PCIe 運作。本篇把作業系統熟悉的記憶體映射 I/O、DMA 與中斷,接到一筆 NVMe 命令的實際傳遞過程。
- NVMe
- Non-Volatile Memory Express,主機與非揮發性記憶體子系統之間的介面規範家族。
- PCIe
- PCI Express,NVMe memory-based controller 使用的 transport 與裝置互連。
- I/O
- Input/Output,對 namespace 執行資料輸入與輸出的操作類別。
這篇的主軸
介面位置
01-01透過 BAR 與 configuration space 找到 NVMe 介面及能力。
- BAR
- Base Address Register,PCI configuration space 中用來找出裝置 memory space 的 register。
命令與通知
02-01區分佇列資料、Doorbell 與 interrupt 的作用。
平台行為
03-01理解 reset、電源、錯誤回報與鏈路量測各自的適用範圍。
00.02.Base 規格定義 NVMe 的共同命令與佇列模型;PCIe Transport 補上本機 PCIe 的連接方式。讀取記憶體中的 queue entry,與存取裝置的 MMIO register,是不同種類的存取。
- MMIO
- Memory-Mapped I/O,以 CPU memory access 形式讀寫裝置 register。
把主軸連起來
00.03.Base 定義的提交與完成機制,在 PCIe 上需要具體的位址、記憶體存取和通知方式。先找到控制器的暫存器空間,再看 SQ/CQ 如何交換命令,最後理解中斷及 PCIe 狀態回報。
- CQ
- Completion Queue,controller 放入完成結果的完成佇列。
- SQ
- Submission Queue,主機放入命令的提交佇列。
00.04.Configuration Space、錯誤紀錄與眼圖量測又提供不同層次的資訊:裝置如何呈現、傳輸發生了什麼、接收端量測資料如何排列。它們不等同 NVMe 命令完成狀態。學完應能沿一次交換辨認資料、Doorbell 和中斷的分工。
01 NVMe 如何使用 PCIe
01.01.Figure 1 說明文件適用關係,Figure 2 再把 protocol responsibility 分層。工程上應把『command 語意』與『如何透過 host memory、MMIO、configuration space、interrupt 傳送』分開查證;Transport 發現衝突時不能改寫 Base。
- Host
- 主機;執行作業系統並送出 NVMe 命令的一端。
01.02.PCIe Transport 補充 Base Specification,定義 PCIe 專屬資料結構、延伸、要求與行為;通用 NVMe 行為仍由 Base 定義。規格衝突時 Base 的優先序高於 Transport。
來源:PCIe Transport 1.4 §1.2
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §1.2, 文件頁 6, PDF 頁 6
| 規格層次 | 負責的行為 | 本篇如何使用它 |
|---|---|---|
| Base | command 與 completion 的共通語意 | 最高優先序的 NVMe 定義 |
| PCIe Transport | address、register、doorbell、interrupt 綁定 | 補充 PCIe-specific 要求 |
| PCI-SIG 規格 | 原生 PCIe capability/transaction 語意 | 本報告只引用來源明載的 NVMe-specific 部分 |
02 BAR、MMIO 與 Doorbell 位址
02.01.NVMe controller registers 位於 BAR0/BAR1 指定的 memory space。Doorbell 從 1000h 起,queue y 的 SQ tail 與 CQ head 依 CAP.DSTRD 計算間距。Figures 3-6 要連成 address derivation,而不是四張獨立 register 表。
- controller
- controller,實作 NVMe 介面、取走 command 並回報 completion 的控制實體。
- DSTRD
- Doorbell Stride,CAP 中決定相鄰 doorbell register 間距的欄位。
- CAP
- Controller Capabilities,offset 00h 的 controller property,回報 queue、page size、timeout 與其他能力。
02.02.NVMe controller registers 位於 BAR0/BAR1 所指定的 memory space。host 必須(shall)使用 native width 或 aligned 32-bit access,不得發出 locked access;違反時行為未定義。
來源:PCIe Transport 1.4 §3.1
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.1, 文件頁 9-10, PDF 頁 9-10
| Doorbell 或寫入值 | 位址或內容如何計算 | 主機用它通知什麼 |
|---|---|---|
| SQ y tail | 1000h + (2y) × (4 << DSTRD) | host 公布新 SQ tail |
| CQ y head | 1000h + (2y+1) × (4 << DSTRD) | host 公布已消費 CQ head |
| doorbell value | queue pointer | 不含 SQE/CQE 本體 |
- CQE
- Completion Queue Entry,CQ 中的一筆完成結果資料結構。
03 Host 與 Controller 的命令交換
03.01.SQE、doorbell、controller fetch、CQE、interrupt 與 CQ head 不是同一個事件的不同名稱,而是 host/controller 之間逐步移交 ownership。正確順序同時決定 memory ordering 與資源何時可重用。
- Host 將命令寫入 SQ(提交佇列)。
- Host 更新 SQ Tail Doorbell,通知 Controller 有新命令。
- Controller 取出並執行命令,將結果寫入 CQ(完成佇列)。
- Host 讀取 CQE,再更新 CQ Head Doorbell,交還已讀取的位置。
03.02.command flow 是:寫 SQE、更新 SQ tail doorbell、controller 取走與執行、寫 CQE、發出 interrupt(若啟用)、host 處理 CQE、更新 CQ head doorbell。doorbell 只通告 pointer,不攜帶 command 本體。
來源:PCIe Transport 1.4 §3.4
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.4, 文件頁 12-13, PDF 頁 12-13
| 需要重用的資源 | 何時不再由原操作使用 | 主機應觀察的資訊 |
|---|---|---|
| SQ slot reuse | controller 已消費該 SQE | 由完成資訊的 SQHD 協助追蹤 |
| command buffer reuse | command 已 completion 且資料可見 | 依 command/data direction 核對 |
| CQ slot release | host 已完整消費 CQE | 之後才寫 CQ head doorbell |
04 Interrupt 模式與通知行為
04.01.pin-based、single-message MSI、multiple-message MSI 與 MSI-X 的差異不只效能。它們提供的 vector 數、masking 位置與 capability structure 不同;interrupt coalescing 另外決定多個 completion 何時合併通知。Figure 9 與 Figures 34-46 應配合 queue-to-vector mapping 閱讀。
04.02.可用模式為 pin-based、single-message MSI、multiple-message MSI 與 MSI-X。規格建議 MSI-X;coalescing 可降低 interrupt rate,但通常增加 latency。Admin CQ 的 interrupt 不宜(should not)延遲。
- Admin
- Administrative,建立、設定、查詢或管理 controller 與 queue 的控制路徑。
來源:PCIe Transport 1.4 §3.5
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.5, 文件頁 13-16, PDF 頁 13-16
| 中斷方式 | 通知與遮罩如何安排 | 影響的資源或限制 |
|---|---|---|
| pin-based | 傳統共享線路 | 共享與 masking 行為不同 |
| single MSI | 單一 message/vector | 多個 CQ 可能共享服務路徑 |
| multiple MSI | 一組連續 messages | 受 MME/MMC 等能力限制 |
| MSI-X | table-based 多 vectors、獨立 mask | 規格建議優先使用 |
05 Configuration Space 與 PCIe 錯誤回報
05.01.Figures 10-67 從 Type 0 header 走到 Power Management、MSI/MSI-X、PCIe capability 與 AER。閱讀順序應先找 capability pointer/extended capability,再以該 capability base 加 offset;AER status/mask/severity/header log 應視為一組,不可只截取單一 error bit。
- AER
- Advanced Error Reporting,PCIe 用來分類、遮罩與記錄 link/transaction error 的 capability。
05.02.§3.8 逐欄定義 NVMe controller 的 PCI header、Power Management、MSI/MSI-X、PCIe capability 與 AER 額外要求。PCI/PCIe 原始欄位語意仍以 PCI-SIG 規格為準。
來源:PCIe Transport 1.4 §3.8.1-3.8.7
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.8.1-3.8.7, 文件頁 16-35, PDF 頁 16-35
| 回報層次或能力 | 描述的事件或資源 | 必須連同哪些資訊閱讀 |
|---|---|---|
| NVMe CQE status | command 執行結果 | 由 NVMe command context 解 |
| PCIe Device Status | PCIe Function 狀態摘要 | 位於 PCIe capability |
| AER | correctable/uncorrectable transport errors | status、mask、severity、header 一起看 |
| power state | slot limit 與 device power 控制 | 不得選超過 slot power limit 的 NVMe state |
06 接收端眼圖量測資料的結構
06.01.接收端眼圖量測 log 是變長結構。Header 描述整體資料,lane descriptors 描述各 lane;將結構層級與長度單位分開,才能理解每筆量測屬於哪條 lane。
06.02.Physical Interface Receiver Eye Opening Measurement log page 以 header、lane descriptor 與 EOM data 回報量測;host 先查支援與大小,再依 lane/parameter 解析。
- EOM
- Eye Opening Measurement,量測 PCIe receiver eye opening 的程序與 log data。
來源:PCIe Transport 1.4 §3.9
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.9, 文件頁 39-46, PDF 頁 39-46
| 量測資料區域 | 描述的量測與位置 | 比較前須先確認什麼 |
|---|---|---|
| specific parameter | 選量測動作與品質/狀態 | 先決定 request context |
| specific identifier | 選 lane/test context | 避免把不同量測混在一起 |
| header | 全域長度與配置 | 所有後續 offset 的基準 |
| lane descriptor | 每 lane 邊界/狀態 | 只在 buffer 內走訪 |
接著打開 Spec 看什麼
07.01.以下按概念列出閱讀位置。報告時先用上面的流程說明問題,再打開對應章節看欄位與完整條件。中文教學 HTML 另有本篇全部圖表的逐圖重點、案例與細節。
| 要說明的觀念 | Spec 閱讀位置 |
|---|---|
| NVMe 如何使用 PCIe | PCIe Transport 1.4 §1.2 · PCIe Transport 1.4 §1.3 · PCIe Transport 1.4 §2 |
| BAR、MMIO 與 Doorbell 位址 | PCIe Transport 1.4 §3.1 · PCIe Transport 1.4 §3.1.2.1-3.1.2.2 |
| Host 與 Controller 的命令交換 | PCIe Transport 1.4 §3.4 · PCIe Transport 1.4 §3.2 |
| Interrupt 模式與通知行為 | PCIe Transport 1.4 §3.5 · PCIe Transport 1.4 §3.2 · PCIe Transport 1.4 §Annex A |
| Configuration Space 與 PCIe 錯誤回報 | PCIe Transport 1.4 §3.8.1-3.8.7 · PCIe Transport 1.4 §3.7 · PCIe Transport 1.4 §3.6 |
| 接收端眼圖量測資料的結構 | PCIe Transport 1.4 §3.9 · PCIe Transport 1.4 §Annex A |
學完後想一想
1. PCIe MMIO properties 和 host memory 中的 queues 分別扮演什麼角色?
08.01.Properties 提供 controller 設定、狀態與 queue 通知介面;queues 承載命令和完成項目。將控制介面與資料結構分開,才能理解一次提交如何運作。
來源
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.1, 文件頁 9-10, PDF 頁 9-10
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.2, 文件頁 11, PDF 頁 11
2. 為何不能假設所有 controller 的相鄰 doorbells 都相距 4 bytes?
08.02.Doorbell spacing 由 CAP.DSTRD 決定,stride 是 2^(2+DSTRD) bytes。只有 DSTRD=0 時才是 4 bytes;SQ Tail 與 CQ Head 的位置還需搭配 queue ID 計算。
來源
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.1.2.1-3.1.2.2, 文件頁 10-11, PDF 頁 10-11
3. 收到 interrupt 後,為何仍需讀取 CQ?
08.03.Interrupt 是通知,CQE 才包含命令識別與完成狀態。一個通知不必等於一個完成項目;host 應依 queue 的有效項目與進度處理完成。
來源
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.5, 文件頁 13-16, PDF 頁 13-16
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.4, 文件頁 12-13, PDF 頁 12-13
4. NVMe 命令的 status 與 PCIe 錯誤回報,為何需要分開看?
08.04.前者描述命令處理結果,後者描述傳輸與裝置層的錯誤資訊。兩者可能相關,但解釋的對象不同,不能把某一層的成功當成所有層都沒有問題。
來源
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.7, 文件頁 16, PDF 頁 16
來源:NVME-PCIE-TRANSPORT-1.4, Rev. 1.4, §3.8.1-3.8.7, 文件頁 16-35, PDF 頁 16-35


Comments