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),如图