根據上一篇文章原理NVM Express - NVMe Submission Queue & Completion Queue (SQ & CQ),介紹了Host Software和Controller是如何透過Submission Queue和Completion Queue來溝通,而且還有提到Admin Queue和I/O Queue的差別,接下來的篇幅將會詳細介紹提交到Admin Queue的Command Set。
在介紹Command Set之前,首先介紹PRP List,圖1為提交command到Submission Queue(SQ)的基本格式,command裡的PSDT欄位為00b時,表示DPTR指向的是一個PRP List,如果是01b or 10b則表示DPTR欄位指向的是一個SGL List,但由於SGL使用在NVMeoF,此篇幅就不介紹。
由於有些command需要傳輸資料,所以Host Software提交command之前,需要在host端預先分配一塊memory buffer,那要如何讓NVMe Controller知道memory buffer的位置呢?主要透過command裡的PRP或者SGL,將buffer的base address填入所提交的command中的DPTR欄位,Controller就能知道要去哪裡取得data(Host Write) 或將data放置在正確的位置(Host Read)。
■ Physical Region Page (PRP)
如果CDW0.PSDT欄位為00b,代表著DPTR欄位使用的是PRP,圖2為PRP單一個Entry的格式,由Page Base Address和Offset欄位所組成,Page Base Address指向的是一個Memory Page的base address,Offset則可以是介於這個Memory Page之中。那麼怎麼決定一個Memoy Page的Size呢?主要透過Controller Configuration(CC) register裡的Memory Page Size(MPS)欄位來決定,計算方法為(2 ^ (12 + MPS)),所以當MPS設定為0表示page size為4 Ki(4096) bytes。
- VID: 與PCIe configuration space的Vendor ID欄位相同,同樣代表製造商的代碼。
- SSVID: 與PCIe configuration space的Subsystem Vendor ID欄位相同。
- CMIC: 此欄位bit[4:0]分別代表不同的意義,[1] 代表此NVM Subsystem包含2個(或以上)的controller,如果有support SR-IOV的話這個bit會設為1。[2] 代表return這份ICDS的controller是SR-IOV的Virtual Function。
- MDTS: Maximum Data Transfer Size代表Host與controller的資料傳輸所使用的memory buffer 的最大size為何,其單位為上面所提到的CC register裡的Memory Page Size(MPS),如果此欄位為8且MPS為4k,那麼MDTS = 4096 x (2^8) = 1,048,576 Bytes = 1M Bytes。
- CNTRLTYPE: Controller Type代表此controller的類型,一般市面上的M.2 NVME 通常都是回報I/O Controller(1h)
- OACS: 表示一些optional(可選的) admin command是否有support,像是Firmware Download與Firmware Commit或Namespace Management或 Virtualization Management command...等等
- ONCS: 表示一些optional(可選的) I/O command是否有support,像是Compare command或Write Uncorrectable command或 Dataset Management command...等等
- NPSS: 表示controller support多少個power state,並且可以透過set feature command來控制controller進入哪個power state。
- SQES: Submission Queue Entry Size代表host提交一筆command的格式為多少bytes,通常回報6,代表一筆command為64 bytes(2^6)。
- CQES: Completion Queue Entry Size代表controller回覆一筆command completion的格式為多少bytes,通常回報為4,也就是16 bytes(2^4)。
- PSD0~PSD31: 從bytes 2048之後,都是Power State Descriptor,但並不是所有0~31都有效,主要是根據上述NPSS欄位來決定support多少個Descriptor,假如NPSS為4,那麼就只有PSD0~PSD3有效。
- NSZE: 描述這個namespace總大小為何,單位為LBAs,而LBA編號為從0開始,所以此欄位回報值為n的話,就是從LBA 0 ~ LBA n-1。
- NCAP: 表示NSZE裡面最大可以有多少LBA被分配到namespace裡,正常來說NSZE等於NCAP。
- NUSE: 此欄位表示當前已經有多少LBA已經被分配到namespace裡。
- NLBAF、FLBAS、LBAF0~LBAF15: 從INDS的byte128~191得知,一個namespace最多可以support 16個LBA format,一個format entry如圖8所示,主要由LBADS欄為決定一個LBA的大小為何,如果LBAFx.LBADS為9表示 1 LBA = 512 bytes,如果LBADS為12表示1 LBA = 4096 bytes。NLBAF表示此namespace總共support幾個format,如果值為2表示只有LBAF0和LBAF1有效。FLBAS表示namespace當前所使用的LBA format為LBAF0或LBAF1。Figure 8. LBA Format Data Structure Entry Format
- NMIC: Namespace Multi-path I/O and Namespace Sharing Capabilities,bit0設為1表示namespace可以同時attach兩個以上的controllers,也就是namespace sharing,如果為0表示為private,一次只能attach到一個controller。
- NVMCAP: NVM Capacity欄位和NUSE欄位意思一樣,只是單位被換算成bytes。
- DPTR & CDW11.PC: DPTR欄位會受CDW11的Physically Contiguous(PC)欄位所影響,當host所準備的IO SQ memory buffer為連續的話,會將PC bit設為1,並且將64 bit buffer base address填到DPTR欄位。如果不是連續,則host必須將描述這些片段memory的PRP List的base addres填入DPTR。
- CDW10.QID: create queue的時候host必須給這個queue一個ID,之後提交command的時候才知道要敲哪一個doorbell
- CDW10.QSIZE: NVMe的queue為circular queue,此欄為決定此SQ有幾個slot,但這個欄位最大值主要受限於capability register的Maximum Queue Entries Supported(MQES)欄位。
- CDW11.QPRIO: 此欄為此SQ的priority等級,但只有在Controller Configuration(CC) register的Arbitration Mechanism Selected (AMS)欄位選擇Weighted Round Robin with Urgent Priority Class(001b)時此QPRIO才有效。
- CDW11.CQID: 表示提交的此I/O SQ command之後,所回覆的completion要提交到哪個I/O CQ。
- CDW12.NVMSETID: NVM Set是另外一個topic,目前文章先不介紹
- CDW11.IV: 根據開頭所提的文章中有提到,當controller提交completion到CQ的時候,controller會發interrupt(MSI or MSI-X)通知host software,但host software要如何知道是誰發的interrupt呢?主要就是透過interrupt vector,因此在create I/O CQ的時候host會為這個queue決定interrupt vector。
- CDW11.IEN: Enable bit,此欄位決定此I/O CQ能不能發出interrupt。
■ Asynchronous Event Request Command (OPC 0Ch)
NVMe support 非同步的事件,在admin command中只有Asynchronous Event
Request cmd不需要及時回覆completion到CQ,等到controller有async event發生,才需要回覆,所以spec有建議host可以一次提交多個Async Event Request Cmd,等到事件發生controller就可以馬上回覆completion。
那麼async event有哪些呢?主要有Error event、SMART / Health Status event、Notice event、NVM Command Set Specific events和Vendor Specific event,而async event的主要用途是為了通知host software現在可以透過Get Log Page(opcode 02h) cmd來獲得相對應的log page的information,舉例來說,當SSD測量到溫度大於SMART log page裡所定義的Over Temperature Threshold的時候,controller就會更新SMART Log Page的Critical Warning[1](下面篇幅會介紹),並且回覆Asynchronous Event Request cmd的completion(格式如圖12所示),並且會在Asynchronous Event Type(如圖13)欄位填上001b表示event是SMART / Health Status,這時候host會再提交Get Log Page cmd來取得SMART / Health Information Log Page。
- CDW10.LID: Log Page Identifier,填入想要取得Log Page的ID。
- CDW10.LSP: Log Specific Field,有些Log Page有一些自定義的欄位會放在這裡,每個定義都不一樣,其餘沒有用到LSP的Log Page這個欄位為Reserved。
- CDW10.RAE: Retain Asynchronous Event,這個bit主要是用來保持或停止Controller持續發送Asynchronous Event。
- CDW10.NUMDL & CDW11.NUMDU: Number of Dwords,這兩個欄位用來定義host想要多少DWORD的data,可以小於Log Page最大size,但不能大於。
- CDW11.LSI: 這個欄位只有在Endurance Group和NVM Set相關的Log Page才會用到,由於這兩個功能故事比較龐大,之後可能用另外一片篇幅講解。
- CDW12.LPOL & CDW13.LPOU: Log Page Offset,host可以決定要從哪個地方開始讀取Log Page,假如Offset為20h,然後NUMD為8,那麼controller就會回報20h ~ 3Fh總共32 bytes的data。
由於Log Page太多,本篇只介紹SMART / Health Information Log Page,SMART全稱為Self-Monitoring, Analysis and Reporting
Technology,主要紀錄controller的一些使用狀況和健康資訊,由於SMART log page欄位眾多,一樣只挑幾個欄位介紹。
- Critical Warning: 由上面所敘述的Asynchronous Event Request Command得知,當有相對應的event發生,controller會將Critical Warning對應的bit設為1,並且回覆host在先前所提交的Asynchronous Event Request Cmd的completion
- Bit 0 發生的情況為為Available Spare如果低於Available
Spare Threshold的值的時候。
- Bit 1 發生的情況為Composite Temperature溫度高於Over
Temperature Threshold或低於Under
Temperature Threshold的時候。
- Composite Temperature: SSD當前的溫度為何,單位是°K。
- Available Spare: 目前SSD剩餘多少容量,單位為%。
- Available Spare Threshold: 發出aysnc event警告host的門檻為何,單位為%。
■ Set Features(OPC 09h) & Get Features(OPC
0Ah) Command
Set/Get feature主要會使用到的欄位為DPTR、CDW10、CDW14,然後依照不同的feature會有不同的CDW11、12、13和15的欄位,格式如圖16、17所示。
Set Feature和Get Feature的格式差異在於CDW10,Set Feature的Save(SV)欄位主要是為了Set Feature後的值不能因為reset或power cycles而不見。Get Feature的Select(SEL)欄位表示了每一個feature有三種型態,分別為Current(000b)、Default(001b)和Saved(010b),Current為目前的值為何,Default為host還沒下過任何Set Feature之前的值,Saved為host曾經提交Set Feature cmd with Save bit set的話,則會回傳這個Save過的值。011b為Support Capabilities,bit 0表示這個feature是否是是可以Saveable的,如果bit0設為1,host才可以在set feature cmd裡面設置SV bit為1,bit 1為NS Specific,表示這個feature是否只針對特定的namespace,如果為0表示set feature是針對整個controller,bit 2 Changeable表示這個feature的值是否可以更改。
圖20為所有feature的ID列表,由於feature眾多,一樣挑選幾個來介紹。
■ Features - Number of Queues (FID 07h)
在開頭的文章中關於Initialization的部分有提到Host Software透過Set Features - Number of Queues來決定要create多少的I/O Queues,Number of Queues feature使用到的欄位為CDW11(如圖21),NCQR欄位為Host Software想要create I/O CQ的數量,NSQR則為Host Software想要create I/O SQ的數量,由於兩個欄位是0's based,所以填0表示至少會有一個I/O CQ or SQ會被create。但如果controller沒辦法create那麼多queue resource的話,可以再回覆completion的DW0欄位回報已經allocate了幾個queue(如圖22),所以controller有可能allocate queue的數量少於host所request的。
■ Features - Temperature Threshold (FID 04h)
Controller最多可以support 9組溫度sensor,並且report當前的溫度(°K)在SMART /Health Log
Page的byte 200~215的地方。此feature主用是用來設置每組溫度sensor的Over Temperature Threshold和Under Temperature Threshold的值,由THSEL欄位選擇設置Over還是Under,由TMPSEL欄位選擇哪一組溫度sensor,TMPTH則填入門檻值。
■ Features - Asynchronous Event Configuration (FID 0Bh)
上面有提到Asynchronous Event Request Cmd為host想要有async event發生的時候,馬上回覆Asynchronous Event Request cmd的completion來通知host,但是async event發生的時候controller要不要回覆asyn event completion其實要先透過Set Feature - Asynchronous Event Configuration來打開開關,如圖24所示為Asynchronous Event Configuration的格式,CDW11[7:0]為SMART/Health Critical Warning Event的enble bit,CDW11[8]為當Namespace Attribute屬性有更改的時候,就可以發出event的enable bit,bit9~bit14以此類推。
Reference: NVM Express Base Specification
Revision 1.4c
还能继续更新NVMe的文章吗?
回覆刪除