概述
NVMe(Non-Volatile Memory Express),非易失性存储器标准。
NVMe接口是替代AHCI(Advanced Host Controller Interface)的,它定义了主机(host)软件与非易失性存储子系统(subsystem)通信的方式。
NVMe接口适用于采用不同传输方式(PCIe/ethernet/InfiniBand/Fibre Channel)的所有存储解决方案。
从NVMe 2.0版本开始,将协议分成了4部分:
- base: 定义主机软件通过各种基于内存传输(memory-based)和消息传输(message-based)与NVM subsystem通信的协议
- command set: 定义扩展base spec的data structure / features / log pages / commands 和 status value
- transport: define the binding of the NVMe protocol including controller properties to a specific transport
- MI: management interface: 为所有的NVM subsystem定义的可选管理接口。
Command Set分类
NVMe中的command set分类如下
- Admin Command Set
- I/O Command Set
- NVM Command Set
- Zoned Namespace Command Set
- Key Value Command Set
- Fabrics Command Set
NVMe采用一个Admin SQ和其对应的CQ,来管理和控制controller。只有Admin Command Set和Fabrics Command Set中的命令才能添加到Admin队列中。
I/O Command Set使用的是I/O的Queue Pair。Base spec中定义了common I/O commands,其他I/O commands都定义在对应的Command Set Spec中。
Fabrics Command Set是针对Nvme over Fabrics场景,它定义了NoF的一些特定命令,如建立链接(establishing a connection), 带内身份校验(NVMe in-band autherations),获取/设置属性(get or set a property)等。 所有的Fabrics commands都可以提交到Admin队列,部分Fabrics commands也可以提交到I/O队列中。与Admin和命令不同的时,处理Fabrics命令时无需关注controller是否enabled(CC.EN)。
名词解释
名词 | 说明 |
---|---|
Admin Queue | id为0的一组SQ和CQ。 |
Administrative Controller | 控制器的一种类型,不实现I/O队列,它提供对存储介质中数据和元数据的访问能力;支持namespace附加到ctrl |
arbitration burst | 仲裁机制中每次可以从SQ中获取的最大命令数 |
arbitration mechanism | 仲裁机制:用来确定接下来从哪个SQ中获取命令交给ctrl处理 |
association | 特定主机和特定ctrl之前的独占通信关系,host独占ctrl的所有admin和I/O队列 |
capsule | NVMe over Frabics场景中表示信息交换单元,一个capsule中包含一个命令或响应,也可能包含命令或响应数据或SGLs |
command completion | ctrl完成命令处理,在CQE(completion queue entry)中更新状态信息,并将CQE添加到对应的CQ中 |
command submission | 对于memory-based传输(如pcie)实现,指的是host将SQE添加到SQ中,更新SQ指针,并设置SQ Tail Doorbell 对于message-based传输(如NVMe over Fabrics)实现,指host将capsule加入到SQ中 |
controller | host和NVM subsystem之间的接口。 有三种类型的ctrl: I/O controller;discovery controller;Administrative controller。 ctrl执行主机在SQ中提交的命令,post completion 到CQ中。所有控制器都实现一个管理SQ/CQ,有些控制器可以实现一个或多个SQ/CQ。 当PCIE作为传输协议时,controller时一个PCIE function |
directive | host与NVM subsystem/contoller之间信息交换的一种方法。信息可以通过Directive send或Directive receive命令传输。 |
Discovery Service | 只支持Discovery controller的一种NVM subsystem。它不支持namespace |
namespace | 可被host直接访问的,格式化好的NVM。(A formatted quantity of non-volatile memory that may be directly accessed by a host.) |
NVM subsystem | NVM subsystem可以包含一个或多个domain,一个或多个controller,0个或多个namesapce以及一个或多个端口。 |
协议原理
控制器架构
控制器模型
controller是host和NVM subsystem之间的接口。
协议定义了两种控制器模型:静态模型(static)和动态模型(dynamic)。NVM subsystem中的所有控制器都应该遵循同一种模型。
静态控制器模型中,控制器与主机建立链接时可能具有不同的状态,通过控制器ID来区分NVM subsystem中的不同控制器。host会基于控制器ID请求特定的控制器,控制器的状态来自上一次建立关联时的状态。
动态控制器模型中,控制器由NVM subsystem根据需要动态分配,所有控制器与主机建立链接时具有相同的状态(包含ctrl中的ns,以及feature settings)(不会保留之前建立关联时状态的修改)。建立链接后,对某个控制器的修改(如ns,feature setting)不会影响其他控制。
场景 | 是否支持静态控制器 | 是否支持动态控制器 | |
---|---|---|---|
Transport Model | memory-based | Y | N |
message-based | Y | Y | |
Controller Type | I/O Controller | ||
Administrative Controller | |||
Discovery Controller | N | Y |
控制器类型
Identify命令(CNS:01h)
的结果Identify Controller data Structure
中有一个属性Controller Type(CNTRLTYPE)
标识了控制器的类型。
所有的控制器类型都必须实现Admin Queue Pair
I/O Controller
I/O控制器支持使用I/O command set访问存储在NVM subsystem中的非易失性存储介质,也可能会提供管理capabilites的命令。
一个I/O控制器可以同时支持多种I/O Command Set。控制器具体支持哪些I/O Command Set可以通过
Identify命令(CNS:1Ch)
的结果Identify I/O Command Set data structure
中获取。
Administrative Controller
Administrative控制器的目的是为了给NVM subsystem提供管理功能。虽然I/O控制器可能也能提供这些管理功能,但Administrative控制器必须实现的强制性要求要比I/O控制器少。
Administrative控制器不支持I/O commands,但是可以支持I/O command set中特定的管理命令,这些管理命令下发时时通过Admin的队列。
Administrative控制器不支持I/O队列,也不允许添加namespace。
Discovery Controller
Discovery控制器只实现与
Discovery Log Pages
相关的feature。不支持I/O队列,I/O命令和namespace。
控制器属性
控制器属性通常时dword(4bytes)或qword(8bytes)大小。这些属性可能具有RO/RW权限。
读写这些属性时,只能根据它的偏移(offset)和大小进行读写,不能一次多多个属性或跨属性的地址进行访问。
说有的保留(reserved)属性和属性中的保留字段都是只读的,读取只写内容时返回值都是0.
message-based的场景中,可以通过Property Get
和Property Set
命令对属性进行读写。
memory-based的场景中,通常时将这些属性映射(ioremap)到主机的内存,然后采用readl
和writel
等相关命令进行读写。
具体的属性内容,参见base协议(2.0b版本)的 3.1.3章节。
在memory-base(pcie)场景中,控制器属性就是指控制器寄存器
队列模型
NVMe的实现是基于配对的Submission和Completion队列。命令由host软件提交到SQ,controller处理完后会将Completion添加到命令关联的CQ中。
memory-based传输场景中,SQ与CQ的对应关系时n:1(n>=1)。message-based传输场景中,SQ和CQ的对应关系时1:1。
Memory-Based Transport Model
I/O SQ和CQ的创建流程
- 初始化Admin队列的属性: Admin Queue Attributes (SQ size, CQ size), Admin SQ Base Address 和 Admin CQ Base Address。
- 通过Controller Configuration属性配置I/O SQ entry大小(CC.IOSQES)和 I/O CQ entry大小(CC.IOCQES)。
- 下发
Set Feature
命令(feature: number of queue)请求I/O SQ和CQ的队列数量,该命令返回控制器分配的SQ和CQ的队列数。 - 读取CAP.MQES(maximum Queue Entry Size),并确定队列深度的大小;读取CAP.CQR(Contiguous Queues Required)确定队列是否需要连续的物理地址。
- 下发
create i/o cq
命令创建I/O 的CQ队列,下发命令时会指定队列深度,队列dma地址等信息 - 下发
create i/o sq
命令创建I/O 的SQ队列