作者:重庆互联网-晴天 发布时间:2022-12-06 浏览:19044 赞(1623) 收藏 评论(0)
NVMe over PCIe协议,定义了NVMe协议的使用范围、指令集、寄存器配置规范等。
名词解释
Namespace是一定数量逻辑块(LB)的集合,属性在Identify Controller中的数据结构中定义。
Fused Operations可以理解为聚合操作,只能聚合两条命令,并且这两条命令在队列中应保持相邻顺序。协议中只有NVM指令才有聚合操作。还需要保证聚合操作的两条命令读写的原子性,参考Compare and Write例子。
除了聚合操作(Fused Operations),每一条SQ中的命令都是独立的,不必考虑RAW等数据相关问题,即使考虑,也是host应该解决的问题。
控制器需要支持写单元的原子性。但有时也能通过host配置Write Atomicity feature,减小原子性单元的大小,提高性能。
数据的额外信息,相当于提供校验功能。可选的方式。
用来选择下一次执行的命令的SQ的机制,三种仲裁方式:
RR(每个队列优先级相同,轮转调度)
带权重的RR(队列有4种优先级,根据优先级调度)
自定义实现
NVMe定义的最小的读写单元,2KB、4KB……,用LBA来标识块地址,LBA range则表示物理上连续的逻辑块集合。
由SQ(提交队列)与CQ(完成队列)组成,host通过SQ提交命令,NVMe Controller通过CQ提交完成命令。
NVM子系统包括控制器、NVM存储介质以及控制器与NVM之间的接口。
整体来看,NVMe SSD可以分为三部分,host端的驱动(NVMe官网以及linux、Windows已经集成了相应的驱动)、PCIe+NVMe实现的控制器以及FTL+NAND Flash的存储介质。
NVMe控制器实质上为DMA + multi Queue,DMA负责数据搬运(指令+用户数据),多队列负责发挥闪存的并行能力。
NVMe over PCIe,通过利用PCIe总线实现数据交互的功能,实现对物理层的抽象功能。
PCIe总线分为三层,物理层,数据链路层,处理层(类似于计算机网络的分层结构),通过包来转发数据。NVMe协议定义的内容相当于PCIe的上一层应用层,处于应用层。PCIe给NVMe提供了底层的抽象。
NVMe SSD相当于一个PCIe的端设备(EP)。
在协议中主要定义了PC header、PCI Capabilities和PCI Express Extended Capabilities三部分内容。
具体在host内存中会占有4KB,结构如下:
PCI header有两种类型,type0表示设备,type1表示桥。NVMe 控制器属于EP,所以定义为type0的类型。共64KB,如下图:
这里配置了PCI Capbilities,包括电源管理、中断管理(MSI、MSI-X)、PCIe Capbilities。
这里配置有关错误恢复等高级功能。
NVMe寄存器主要分为两部分,一部分定义了Controller整体属性,一部分用来存放每组队列的头尾DB寄存器。
CAP——控制器能力,定义了内存页大小的最大最小值、支持的I/O指令集、DB寄存器步长、等待时间界限、仲裁机制、队列是否物理上连续、队列大小;
VS——版本号,定义了控制器实现NVMe协议的版本号;
INTMS——中断掩码,每个bit对应一个中断向量,使用MSI-X中断时,此寄存器无效;
INTMC——中断有效,每个bit对应一个中断向量,使用MSI-X中断时,此寄存器无效;
CC——控制器配置,定义了I/O SQ和CQ队列元素大小、关机状态提醒、仲裁机制、内存页大小、支持的I/O指令集、使能;
CSTS——控制器状态,包括关机状态、控制器致命错误、就绪状态;
AQA——Admin 队列属性,包括SQ大小和CQ大小;
ASQ——Admin SQ基地址;
ACQ——Admin CQ基地址;
1000h之后的寄存器定义了队列的头、尾DB寄存器。
CAP寄存器标识的是Controller具有多少能力,而CC寄存器则是指当前Controller选择了哪些能力,可以理解为CC是CAP的一个子集;如果重启(reset)的话,可以更换CC配置;
CC.EN置一,表示Controller已经可以开始处理NVM命令,从1到0表示Controller重启;
CC.EN与CSTS.RDY关系密切,CSTS.RDY总是在CC.EN之后由Controller改变,其他不符合执行顺序的操作都将产生未定义的行为;
Admin队列有host直接创建,AQA、ASQ、ACQ三个寄存器标识了Admin队列,而其他I/O队列则有Admin命令创建(eg,创建I/O CQ命令);
Admin队列的头、尾DB寄存器标识为0,其他I/O队列标识由host按照一定规则分配;只有16bit的有效位,是因为队列深度最大64K。
判断队列满可以有多种方法,协议中规定的是头指针比尾指针大一,所以队列满时,空余一个元素。
1. 队列大小有16bit,最小队列大小为2个元素(因为满队列的定义方式,所以最小为2个元素),对于I/O队列,最大队列大小为64k;对于Admin队列,最大队列为4k;
2. QID来标识唯一ID,16bit,由host分配;
3. host可以修改队列优先级(如果支持的话),共四级,U、H、M、L;
RR仲裁,Admin SQ与I/O SQ优先级相同,控制器每次可以选择一个队列中的多个命令(Arbitration Burst setting)。
有3个严格的优先权,Priority1 > Priority2 > Priority3,在这三个优先级队列中,高优先级的队列中如果有命令,则优先执行(非抢占式)。
Vendor Specific。
NVMe把Host的内存分为页的集合,页的大小在CC寄存器中配置,PRP是一个64位的内存物理地址指针,结构如下:
最后两位为0,指四字节对齐;(n:2)位表示页内内偏移。
举个例子,内存页大小位4KB,则(11:2)表示页内偏移。
PRP寻址有两种方式,直接用PRP指针寻址,通过PRP List寻址。当使用PRP List寻址时,偏移必须为0h,每一个PRP条目表示一个内存页,如下:
欢迎广大用户为此页面进行评价,评价成功将获得积分奖励!