NVME-SQ、CQ & DoorBell
參考資料:《深入淺出SSD》 , NVME協議1.3
SQ和CQ
全稱Submission/Completion Queue
1.主機往SQ中寫入命令,SSD往CQ中寫入命令執行的結果
2.SQ和CQ有兩種,
一種是Admin,用來放Admin命令,用以主機管理控制SSD
一種是IO,用來放IO命令,用以主機與SSD之間傳輸數據
3.SQ和CQ可以是一對一的關系,也可以是多對一的關系,它們是成對的
4.系統中只有一對Admin SQ/CQ,它們是一 一對應關系,IO SQ/CQ卻可以有很多(最多為65536,即64k-1)
5.IO SQ/CQ不是一生下來就有的,它們需要通過Admin命令創建
6.主機端每個CPU只有一個CQ(主機端只能有一對Admin SQ/CQ,為一 一對應關系;每個CPU最多可以有一個IO CQ,但是可以有多個SQ)
可以有一個或多個SQ(多個SQ可以用來賦予不同的優先級)
實際系統中需要多少SQ, 取決於系統配置和性能需求,可靈活設置IO SQ
7.SQ和CQ都有一定的深度,對Admin SQ/CQ來說,其深度可以是2 ~ 4096(4K)
對IO SQ/CQ來說,其深度可以是2 ~ 65536(64K),隊列深度是可以配置的(SQ和CQ的個數也是可以配置的)
NVME的性能可以通過配置隊列個數和隊列深度來靈活調節的
8.每個SQ放入的是 命令條目,無論是Admin還是IO命令 ,每個命令條目大小都是64字節 ,
每個CQ放入的是命令完成信息的條目,每個條目大小是16字節
Queue
1. 隊列要素
1)隊列深度
2)隊列內容
3)隊列頭部
隊列頭部的那個正在被服務或等待被服務,完成后將離開隊伍
頭部決定誰先被服務
4)隊列尾部
尾部決定新來隊列的站位
2.隊列的生產者消費者模型
簡述:如下圖,生產者往隊列的尾部寫入東西,消費者從隊列的頭部取出東西
1)對SQ來說,主機是它的生產者(主機向SQ的尾部寫入指令),SSD是它的消費者(SSD從SQ的頭部取出指令執行)
2)對CQ來說,SSD是它的生產者(SSD向CQ的尾部寫入命令的執行結果),主機是它的消費者(主機從CQ的頭部讀取命令的執行結果)
DoorBell
1.DoorBell是SSD控制器端的寄存器,記錄SQ和CQ的頭部和尾部
2.每個SQ或CQ都有兩個對應的DoorBell,即Head DoorBell和Tail DoorBell
3.主機只能寫DoorBell,不能讀DoorBell
4.主機通過SSD往CQ中寫入的命令完成狀態獲取其隊列頭部或者尾部
案例
下面我們以一個案例來說明SQ, CQ和DoorBell之間的聯系
1.一開始,假設SQ1和CQ1都是空的,Head=Tail=0,如圖
2.Host往SQ1寫入三條指令,SQ的Tail變成3,Host寫SQ1 Tail DoorBell(值為3),通知SSD控制器取指令,如圖
3.SSD控制器收到通知,取回SQ1中的3條指令
4.SSD開始執行指令,SSD把SQ1中的3條指令都消費了,SQ1的Head變成3,Host寫SQ1 Head DoorBell(為Head值3),如圖
5.SSD執行完成兩條指令,SSD往CQ1中寫入兩條指令完成的信息,SSD寫CQ1 Tail DoorBell(值為2)
6.SSD生成中斷,通知Host有命令完成,如圖
7.Host收到通知,從CQ1中取出兩條命令的完成信息,開始處理,CQ1中的兩條命令完成信息都消費了,CQ1的Head變為2
8.處理完畢,Host寫CQ1 Head DoorBell(為CQ1的Head值2),如圖