NVM Express(NVMe),或称非易失性内存主机控制器接口规范(英语:Non-VolatileMemoryHostControllerInterfaceSpecification,缩写:NVMHCIS),是一个逻辑设备接口规范。它是与AHCI类似的、基于设备逻辑接口的总线传输协议规范(相当于通讯协议中的应用层),用于访问通过PCI Express(PCIe)总线附加的非易失性存储器介质(例如采用闪存的固态硬盘驱动器),虽然理论上不一定要求 PCIe 总线协议。
NVM代表非易失性存储器(non-volatile memory)的首字母缩略字,这是固态硬盘(SSD)的常见的闪存形式。此规范主要是为基于闪存的存储设备提供一个低延时、内部并发化的原生界面规范,也为现代CPU、计算机平台及相关应用提供原生存储并发化的支持,令主机硬件和软件可以充分利用固态存储设备的并行化存储能力。相比此前机械硬盘驱动器(HDD)时代的AHCI,NVMe/NVMHCI降低了I/O操作等待时间、提升同一时间内的操作数、更大容量的操作队列等。
依托于PCIe总线,NVMe设备可适用于各种支持PCIe总线的物理插槽上,包括标准尺寸的PCIe扩展卡(一般是4个PCIe通道)、采用U.2物理连接界面(SFF-8639)的2.5英寸/3.5英寸标准尺寸固态硬盘驱动器、SATA Express总线(兼容于PCIe)的设备、M.2规格扩展卡等。
此规范由“Non-Volatile Memory Host Controller Interface Working Group”(非易失性存储器主机控制器界面工作组)负责管理。
历史上,大多数SSD使用如SATA、SAS或光纤通道等接口与计算机接口的总线连接。随着固态硬盘在大众市场上的流行,SATA已成为个人计算机中连接SSD的最典型方式;但是,SATA的设计主要是作为机械硬盘驱动器(HDD)的接口,并随着时间的推移越来越难满足速度日益提高的SSD。随着在大众市场的流行,许多固态硬盘的数据速率提升已经放缓。不同于机械硬盘,部分SSD已受到SATA最大吞吐量的限制。
在NVMe出现之前,高端SSD只得以采用PCI Express总线制造,但需使用非标准规范的接口。若使用标准化的SSD接口,操作系统只需要一个驱动程序就能使用匹配规范的所有SSD。这也意味着每个SSD制造商不必用额外的资源来设计特定接口的驱动程序。
截至2014年9月,在光纤通道(FC)上使用NVMe的新标准也正在开发。
2009年Intel开始着手寻找SATA的替代方案。SATA作为串行接口,采用AHCI规范,其已经成为制约SSD速度的瓶颈。AHCI只有1个命令队列,队列深度32.而NVMe可以有65535个命令队列,每个队列都可以深达65536个命令。NVMe也充分使用了MSI的2048个中断向量优势,延迟大大减小。
2011年有了1.0。最新的版本是1.2.1;最大带宽为11.6Gbps,约为1200MB/s。
操作系统 | 说明 |
9Front |
2017年3月30日,NVMe驱动程序发布并供使用 |
Chrome OS | 2015年2月24日,加入NVMe驱动至内核和引导加载程序,可从NVMe设备启动Chrome OS |
DragonFly BSD | DragonFly 4.6开始内置NVMe驱动程序 |
FreeBSD | Intel赞助开发的驱动程序已内置于FreeBSD的head、stable/9分支中。nvd(4)和nvme(4)驱动程序则是在10.2版FreeBSD中开始默认内置于其中。 |
Haiku | Haiku已有驱动开发时程,但是目前仍未完成 |
illumos | illumos于2014年10月15日获得驱动程序支持 |
iOS | iOS 9开始支持,首款配备了NVMe接口的设备是iPhone 6S/6S Plus,也是首款采用NVMe的移动设备。物理接口和UFS相同的采用M-PHY PCIe。接下来Apple推出的iPad Pro和iPhone SE也采用了NVMe |
Linux | NVMe的驱动程序最早是英特尔提供的,适用于Linux的内核驱动程序模块。这个模块在2012年3月19日集成到Linux内核的主线驱动程序当中,Linux内核3.3版开始内置支持而无需安装额外模块。 2014年1月19日的Linux内核 3.13版开始,加入由Fusion-io开发的blk-multiqueue或称blk-mq模块,是为“可变区块层”(scalable block layer),用于NVMe SSD。This leverages the performance offered by SSDs and NVM Express, by allowing much higher I/O submission rates. With this new design of the Linux kernel block layer, internal queues are split into two levels (per-CPU and hardware-submission queues), thus removing bottlenecks and allowing much higher levels of I/O parallelization. 2015年4月12日发布的Linux内核 4.0版开始,VirtIO区块层驱动程序,SCSI驱动层(与SATA驱动共用)、回环设备驱动(loop device) UBI(unsorted block images)驱动(供闪存实现区块擦写管理)以及RBD驱动程序(which exportsCephRADOS objects as block devices)都被修改,以适应及适配越来越多的NVMe设备 |
NetBSD | NetBSD在2016年的开发版本中初步支持NVMe。OpenBSD则是在其6.0版时发布了NVMe的驱动程序。 |
OpenBSD | OpenBSD的NVMe驱动程序自2014年6月开始,由此前开发并发布USB、AHCI驱动程序的高级开发团队负责。OpenBSD 6.0开始正式支持。 |
OS X/macOS | Mac OS X 10.10.3(OS X Yosemite)开始支持NVMe。苹果公司的Retina MacBook和2016年发布MacBook Pro,配备了使用NVMe的PCIe SSD作为主硬盘驱动器使用。 |
Solaris | Solaris自Oracle Solaris 11.2开始支持NVMe。 |
Vmware | 英特尔发布了供VMWare使用的NVMe驱动程序,vSphere 6.0以及其后的版本中,均包含了该驱动程序,支持多种NVMe设备。在 vSphere 6 update 1 更新中,VMWare的VSAN软件模拟的存储子系统也开始支持NVMe设备。 |
Windows | 微软在Windows 8.1和Windows Server 2012 R2开始,原生支持NVMe设备。同时也为Windows 7和Windows Server 2008 R2提供原生驱动程序支持(需由用户自行下载获取) 除了微软官方提供的驱动程序以外,OpenFabrics Alliance也有维护一套开放源代码的NVMe驱动程序,使用于Windows 7、8、8.1、10以及Windows Server 2008 R2、2012、2012 R2,这套驱动程序由数个加入了NVMe工作组的公司开发,包括IDT、英特尔以及LSI。 |
下图显示了NVMe家族结构间的相互关系:
图1中5个结构对应的任务和管理内容为:
名词 | 说明 |
I/O Command Set Specifications | 定义扩展NVM Express基本规范的数据结构、功能、日志页、命令和状态值。 |
NVM Express Base Specification | 定义了主机软件通过各种基于存储器的传输和基于消息的传输与非易失性存储器子系统通信的协议。 |
Transport Specifications | 定义包括控制器属性的NVMe协议到特定传输的绑定。 |
The NVM Express Management Interface (NVMe-MI) Specification | 定义了所有NVM Express子系统的可选管理接口。 |
NVM Express Boot Specification (NVMe Boot) | 定义了从NVM Express接口启动的结构和指南。 |
NVM Express可扩展接口旨在满足使用基于PCI Express的固态驱动器或结构连接设备的存储系统的需求。该接口提供了优化的命令提交和完成路径。它支持并行操作,支持最多65535个I/O队列,每个I/O队列最多有64Ki-1个未完成的命令。此外,还增加了对许多企业功能的支持,如端到端数据保护(与SCSI保护信息(通常称为T10 DIF)和SNIA DIX标准兼容)、增强的错误报告和虚拟化。
该接口具有以下关键属性:
•不需要在命令提交或完成路径中读取不可缓存/MIO寄存器;
•命令提交路径中最多需要一个MMIO寄存器写入或一个64B消息;
•支持最多65535个I/O队列,每个I/O队列最多支持65535个未完成的命令;
•与每个I/O队列相关的优先级,具有定义明确的仲裁机制;
•完成4 KiB读取请求的所有信息都包含在64B命令本身中,确保高效的小型I/O操作;
•高效、精简的指挥系统;
•支持MSI/MSI-X和中断聚合;
•支持多个名称空间;
•高效支持SR-IOV等I/O虚拟化体系结构;
•强大的错误报告和管理能力;和
•支持多路径I/O和命名空间共享。
本规范定义了一组用于配置低级别控制器属性和获取低级别控制器状态的精简属性。这些属性具有特定于传输的机制来定义访问(例如,内存映射项使用寄存器,而结构使用Property Get和Property Set命令)。以下是在属性中定义的功能示例:
•控制器能力指示;
•控制器故障状态(通过CQ直接处理命令状态);
•管理队列配置(通过管理命令处理I/O队列配置);和
•门铃注册可扩展数量的提交和完成队列。
主机和NVM子系统之间的通信有两种定义的结构,一种是基于内存的传输模型,另一种是消息的传输模型。所有NVM子系统都需要底层NVMe传输来提供可靠的NVMe命令和数据传输。NVMe传输是一个独立于任何物理互连属性的抽象协议层。NVMe-Transports的分类法以及示例如图4所示。NVMe传输可以公开基于存储器的传输模型或基于消息的传输模型。基于消息的传输模型有两个子类型:仅消息传输模型和消息/内存传输模型。基于内存的传输模型是通过执行显式内存读写操作在主机和NVM子系统之间传输命令、响应和数据的模型。基于消息的传输模型是在主机和NVM子类型之间发送包含命令封装和响应封装的消息的模型。
NVM子系统由单个域或多个域组成,如第3.2.4节所述。NVM子系统可以可选地包括非易失性存储介质以及NVM子公司的控制器和非易失存储介质之间的接口。控制器暴露此非易失性存储介质通过名称空间连接到主机。NVM子系统不需要具有连接到所有控制器的相同名称空间。支持发现控制器的NVM子系统不支持任何其他控制器类型。Discovery Service是仅支持Discovery控制器的NVM子系统(请参阅第3.1节)。
适用于NVM Express控制器的功能和设置显示在控制器功能(CAP)属性和识别控制器数据结构中。
命名空间是可由主机访问的格式化数量的非易失性存储器。与每个命名空间关联的是一个在该命名空间上操作的I/O命令集。NVM Express控制器可以支持使用命名空间ID引用的多个命名空间。可以使用命名空间管理命令和容量管理命令创建和删除命名空间。标识命名空间数据结构(请参阅第1.5.29节)表示特定命名空间的功能和设置。
NVM Express接口基于成对的提交和完成队列机制。命令由主机软件放入提交队列中。完成由控制器放置到相关联的完成队列中。
NVM Express中定义了三种类型的命令:管理命令、I/O命令和结构命令。图5显示了这些不同的命令类型。
管理提交队列和相关的完成队列用于控制器管理和控制(例如,创建和删除I/O提交和完成队列、中止命令等)。只有属于管理命令集或结构命令集的命令才能提交到管理提交队列。
I/O命令集与I/O队列对一起使用。本规范定义了常见的I/O命令。I/O命令集在NVMe I/O命令集规范中定义(例如,NVM命令集、键值命令集或分区命名空间命令集)。
Fabrics命令集是特定于Fabrics的NVMe。Fabrics命令集命令用于特定于NVMe over Fabrics的操作,包括建立连接、NVMe带内身份验证以及获取或设置属性。所有结构命令都可以在Admin Submission Queue上提交,一些结构命令也可以在I/O Submission Queue上提交。与Admin和I/O命令不同,Fabrics命令由控制器处理,而与控制器是否启用无关(即,与CC.EN的状态无关)。
在基于内存的模型中,提交和完成队列在内存中分配。
主机软件会创建队列,最高可达控制器支持的最大值。通常,创建的命令队列数量基于系统配置和预期工作负载。例如,在基于四核处理器的系统上,每个核可能有一个队列对,以避免锁定并确保在适当的处理器核的高速缓存中创建数据结构。图6提供了队列对机制的图形表示,显示了Submission Queues和Completion Queues之间的1:1映射。图7显示了一个示例,其中多个I/O提交队列在Core B上使用相同的I/O完成队列。图6和图7显示管理提交队列和管理完成队列之间始终存在1:1的映射。
提交队列(SQ)是一个具有固定插槽大小的循环缓冲区,主机软件用来提交命令供控制器执行。当有一到n个新命令要执行时,主机软件会更新相应的SQ Tail门铃寄存器。当有新的门铃寄存器写入时,控制器中先前的SQ-Tail值将被覆盖。控制器按顺序从提交队列中获取SQ条目,并可以按任何顺序执行这些命令。
每个提交队列条目都是一个命令。命令的大小为64字节。内存中用于数据传输的物理内存位置是使用物理区域页面(PRP)条目或分散收集列表(SGL)指定的。每个命令可以包括两个PRP条目或一个散点收集列表段。如果需要两个以上的PRP条目来描述数据缓冲器,则提供指向描述PRP条目列表的PRP列表的指针。如果需要一个以上的SGL段来描述数据缓冲器,则SGL段提供指向下一个SGL段的指针。
完成队列(CQ)是一个具有固定时隙大小的循环缓冲区,用于发布已完成命令的状态。已完成的命令由相关的SQ标识符和主机软件分配的命令标识符的组合唯一标识。在基于存储器的传输模型中,多个提交队列可以与单个完成队列相关联。可以使用具有单个完成队列的配置,其中单个工作线程通过一个完成队列处理所有命令完成,即使这些命令源自多个提交队列。在处理指示最后空闲CQ时隙的完成队列条目之后,由主机软件更新CQ头指针。在完成队列条目中定义了一个阶段标记(P)位,以指示条目是否是在主机未咨询寄存器的情况下新发布的(参见第3.3.3.2.2节)。阶段标记位使主机能够确定条目是否是新的。
用于结构上的NVMe的基于消息的传输模型与基于内存的传输模型有以下区别:
•I/O提交队列和I/O完成队列之间存在一对一映射。NVMe over Fabrics不支持将多个I/O提交队列映射到单个I/O完成队列;
•NVMe over Fabrics未定义允许控制器生成主机中断的中断机制。主机结构接口(例如,主机总线适配器)负责生成主机中断;
•NVMe over Fabrics使用不同的机制创建和删除I/O提交队列和I/O完成队列(请参阅第3.5节);
•结构上的NVMe不支持从单独的缓冲区传输元数据(例如,不支持元数据指针字段);
•NVMe over Fabrics不支持PRP,但需要使用SGL执行Admin、I/O和Fabrics命令。这与基于内存的传输模型不同,在该模型中,管理命令不支持SGL,I/O命令可选择SGL;
•结构上的NVMe不支持完成队列流控制(请参阅第3.3.1.2.1节)。这要求主机在提交新命令之前确保有可用的完成队列插槽;和
•如果主机和控制器同意禁用NVMe over Fabrics,则允许禁用提交队列流控制。如果禁用了提交队列流控,则要求主机在提交新命令之前确保有可用的提交队列插槽。
NVMe over Fabrics使用如图8所示的协议分层。本规范定义了独立于NVMe传输的体系结构的核心方面。NVMe传输绑定规范用于描述任何NVMe传输特定的专业化,以及NVMe接口所需的服务如何映射到相应的NVMe传输上。NVMe接口和NVMe传输使用的本地结构通信服务和其他功能(例如,图8中的结构协议和结构物理层)不在NVMe系列规范的范围内。
2.2.2 NVM Subsystem Ports
NVM子系统提供了一个用于访问名称空间的一到(64Ki-16)控制器的集合。控制器可以通过一到64Ki的NVM子系统端口与主机相关联。NVM Express®底座
NVM子系统端口是NVM子公司和结构之间的协议接口。NVM子系统端口是一个或多个物理结构接口的集合,它们一起充当单个协议接口。当使用链路聚合(例如以太网)时,聚合链路组的物理端口构成单个NVM子系统端口。
NVM子系统包含一个或多个NVM子端口。
每个NVM子系统端口都有一个16位端口标识符(端口ID)。NVM子系统端口由NVM子公司NVMe合格名称(NQN)和端口ID标识。如果底层结构存在一个以上的NVMe传输绑定规范,则NVM子系统端口可以支持多个NVMe传输(例如,由端口ID标识的NVM子公司端口可以同时支持iWARP和RoCE)。NVM子系统实现可以将特定的控制器绑定到特定的NVM子端口,或者允许在NVM子模块端口之间灵活地分配控制器,然而,一旦连接,每个特定的控制器就绑定到单个NVM子组件端口。
一个控制器一次只与一个主机关联。NVMe over Fabrics允许多个主机通过同一NVM系统端口连接到NVM子系统中的不同控制器。NVMe over Fabrics的所有其他方面的多路径I/O和命名空间共享(请参阅第2.4.1节)与基于内存的传输模型等效。
NVMe over Fabrics定义了一种发现机制,主机使用该机制来确定暴露主机可以访问的命名空间的NVM子系统。Discovery Service为主机提供了以下功能:
•能够发现具有主机可访问的名称空间的NVM子系统列表;
•能够发现通往NVM子系统的多条路径;
•能够发现静态配置的控制器;
•与发现控制器建立显式持久连接的可选能力;和
•从发现控制器接收异步事件通知的可选功能。
Discovery Service是一种NVM子系统,仅支持Discovery控制器(请参阅第3.1.2.3节),不应支持任何其他控制器类型。
Capsules是一种NVMe信息交换单元,用于结构上的NVMe。胶囊可以被分类为命令Capsules或响应Capsules。命令封装包含一个命令(格式化为提交队列条目),并且可以选择性地包括SGL或数据。响应胶囊包含响应
(格式化为完成队列条目)并且可以可选地包括数据。数据是指在主机和NVM子系统之间的NVMe层传输的任何数据(例如,逻辑块数据或与命令相关联的数据结构)。胶囊独立于任何底层NVMe传输单元(例如,数据包、消息或帧以及相关的页眉和页脚),并且可以由多个这样的单元组成。
命令封装从主机传输到NVM子系统。SQE包含一个Admin命令、一个I/O命令或一个Fabrics命令。命令封装的最小大小是NVMe传输绑定特定的,但大小应至少为64B。命令封装的最大大小是特定于NVMe传输绑定的。命令封装的格式如图9所示。
响应封装从NVM子系统传输到主机。CQE与以前发布的Admin命令、I/O命令或Fabrics命令相关联。响应Capsules的大小是NVMe传输结合特异性的,但大小应至少为16B。响应封装的最大大小是NVMe传输绑定特定的。响应Capsules的格式如图10所示。
使用仅消息传输模型和消息/内存传输模型的NVMe传输要求在命令内传输从主机发送到控制器的所有SGL。它们可以可选地支持命令和响应封装内的部分或全部数据的传输。
结构上的NVMe需要用于所有命令(结构、管理和I/O)的SGL。SGL可以指定数据在封装内的位置,或者使用NVMe传输特定的数据传输机制(例如,通过RDMA中的存储器传输)传输数据所需的信息。每个NVMe传输绑定规范定义特定NVMe传输使用的SGL以及任何封装SGL和数据放置限制。
NVMe over Fabrics支持结构安全通道,包括身份验证和NVMe带内身份验证。NVM子系统可能需要主机使用结构安全通道、NVMe带内身份验证或两者兼有。发现服务指示结构安全通道是否应用于NVM子系统。Connect响应指示NVMe带内认证是否应与该控制器一起使用。
与需要结构安全通道的NVM子系统相关的控制器在建立安全通道之前,不得接受NVMe传输上的任何命令(即结构命令、管理命令或i/O命令)。在Connect命令之后,需要NVMe带内身份验证的控制器不得接受由该Connect命令创建的队列上的除身份验证命令之外的任何命令,直到NVMe带外身份验证完成。
NVM存储模型包括以下实体:
•NVM子系统
•Domains域
•Endurance Groups
•NVM Sets
•Namespaces命名空间
如下所示,每个域包含在单个NVM子系统中,每个耐久性组包含在单个域中,每个NVM集包含在单个耐久性组中,并且每个命名空间包含在单个NVM集中。每个媒体单元都包含在一个耐力组中。
每个耐久性组由称为介质单元的存储介质组成。为清楚起见,以下示例中未显示介质单元。
图11显示了一个简单NVM子系统中这些实体的层次关系,该子系统具有一个域、一个Endurance Group、一个NVM Set和一个命名空间:
图12显示了复杂NVM子系统中这些实体的关系,该子系统具有多个域、每个域多个耐力组、每个耐力组多个NVM集和每个NVM集多个命名空间:
实体命名密钥(Abc):
A: 域(大写字母)
b: 耐力组(数字)
c: NVM集(小写字母)
持久性组或NVM集的报告是可选的,但存储模型支持这些概念。NVM子系统可以由供应商在配置了其存储实体的情况下发货,也可以由客户配置或重新配置。配置的典型更改是创建和删除名称空间。
不支持多个NVM集的NVM子系统不需要报告NVM集。不支持多个耐久性组的NVM子系统不需要报告耐久性组。
I/O命令对名称空间执行操作,每个名称空间都与一个I/O命令集相关联。例如,NVM命令集中的命令访问在命名空间中表示为逻辑块的数据,而键值命令集中的指令访问在命名空间中将表示为键值对的数据。
命名空间与I/O命令集的关联是在创建命名空间时指定的,并且在命名空间的生存期内是固定的。
控制器可以支持一个或多个I/O命令集,并且可以附加到与不同I/O命令集相关联的名称空间。主机向命名空间发出命令,并根据与该命名空间关联的I/O命令集来解释这些命令。
图13展示了一个简单的NVM子系统,该子系统具有每个存储实体的单个实例。
•NVM子系统由一个端口和一个域组成。
•域包含一个控制器和存储介质。
•所有存储介质都包含在一个耐久性组中。
•该耐久性组中的所有存储介质都组织到一个NVM集合中。
•该NVM集包含单个命名空间
图14显示了一个具有两个namespaces空间的NVM子系统。
NVM子系统可能具有多个域、多个命名空间、多个控制器和多个端口,如图15所示。
本节概述了多路径I/O和命名空间共享。多路径I/O指的是单个主机和命名空间之间的两个或多个完全独立的路径,而命名空间共享指的是两个或更多主机使用不同的NVM Express控制器访问公共共享命名空间的能力。多路径I/O和命名空间共享都要求NVM子系统包含两个或多个控制器。支持多路径I/O和命名空间共享的NVM子系统也可能支持非对称控制器行为(请参阅第2.4.2节)。两个或多个主机对共享命名空间的并发访问需要主机之间进行某种形式的协调。用于协调这些主机的过程不在本规范的范围内。
图16显示了一个NVM子系统,它包含一个通过PCI Express实现的NVM Express控制器和一个PCI Express端口。由于这是一个单功能PCI Express设备,NVM Express控制程序应与PCI功能0相关联。一个控制器可以支持多个名称空间。图16中的控制器支持标记为NS A和NS B的两个名称空间。与每个控制器名称空间相关的是一个名称空间ID,标记为NSID 1和NSID 2,控制器使用它来引用特定的名称空间。命名空间ID与命名空间本身不同,是主机和控制器用于在命令中指定特定命名空间的句柄。控制器名称空间ID的选择不在此规范的范围内。在该示例中,名称空间ID 1与名称空间A相关联,并且名称空间ID 2与名称空间B相关联。这两个命名空间对控制器都是私有的,并且此配置既不支持多路径I/O,也不支持命名空间共享。
图17显示了具有单个PCI Express端口的多功能NVM子系统,该端口包含两个通过PCIe实现NVMe的控制器。一个控制器与PCI功能0相关联,而另一个控制器则与PCI功能1相关联。每个控制器都支持单个私有命名空间和对共享命名空间B的访问。在所有有权访问特定共享命名空间的控制器中,命名空间ID应相同。在本例中,两个控制器都使用命名空间ID 2来访问共享命名空间B。
每个控制器有一个或多个标识控制器数据结构,每个命名空间有一个或者多个标识命名空间数据结构。访问共享命名空间的控制器返回与该共享命名空间相关联的标识命名空间数据结构(即,访问同一共享命名空间的所有控制器返回相同的数据结构内容)。存在与命名空间本身相关联的全局唯一标识符,并且可以用于确定何时存在到同一共享命名空间的多个路径。
与共享命名空间相关联的控制器可以同时在命名空间上操作。单个控制器执行的操作在提交命令的控制器的写入原子性级别上是共享命名空间的原子性操作。在共享命名空间的控制器之间,写入原子性等级不需要相同。如果向访问共享命名空间的不同控制器发出的命令之间存在任何排序要求,则需要主机软件或相关应用程序来强制执行这些排序要求。
图18显示了一个NVM子系统,它有两个PCI Express端口,每个端口都有一个相关的控制器,通过PCIe实现NVMe。两个控制器都映射到相应端口的PCI功能0。本例中的每个PCI Express端口都是完全独立的,并且有自己的PCI Express基本重置和参考时钟输入。端口的重置只影响与该端口相关联的控制器,对其他控制器、共享命名空间或其他控制器在共享命名空间上执行的操作没有影响。此示例的功能行为在其他方面与图17中所示的相同。
图18所示的两个端口可能与同一根复合体或不同的根复合体相关联,可用于实现多路径I/O和I/O共享架构。系统级体系结构方面和PCI Express结构中多个端口的使用超出了本规范的范围。
图19展示了一个NVM子系统,它支持Single Root I/O虚拟化(SR-IOV),具有一个物理功能和四个虚拟功能。在PCIe上实现NVMe的NVM Express控制器与每个功能相关联,每个控制器具有专用名称空间并访问由所有控制器共享的名称空间,标记为NS F。本示例中控制器的行为与本节中其他示例的行为相似。
本节中提供的示例旨在说明概念,而不是列举所有可能的配置。例如,NVM子系统可以包含多个PCI Express端口,每个端口都支持SR-IOV。
非对称控制器行为发生在NVM子系统中,其中命名空间访问特性(例如性能)可能基于以下因素而变化:
•NVM子系统的内部配置;或
•哪个控制器用于访问命名空间(例如Fabrics)。
提供非对称控制器行为的NVM子系统可以支持非对称命名空间访问报告。
控制器是主机和NVM子系统之间的接口。
本规范定义了两种控制器型号。NVM子系统可以支持静态或动态控制器模型。NVM子系统中的所有控制器应遵循相同的控制器型号。
在静态控制器模型中,可以分配给特定主机的控制器在建立关联时可能具有不同的状态。NVM子系统内的控制器通过它们的控制器标识符来区分。所有基于内存的传输模型控制器应支持静态控制器模型。
在动态控制器模型中,控制器由NVM子系统按需分配。在此模型中,分配给特定主机的所有控制器在建立关联时都具有相同的状态,包括附加的命名空间和功能设置。建立关联后对控制器的更改(例如,附加的命名空间、功能设置)不会影响其他动态控制器。
在NVM子系统中使用基于消息的传输模型的控制器可以使用动态或静态控制器模型。Discovery控制器应支持动态控制器模型。
当主机使用Fabrics Connect命令连接到控制器的管理队列时,将在主机和控制器之间建立关联。在Connect命令中,主机指定主机NQN、NVM子系统NQN、主机标识符,并且可以请求特定的控制器ID,也可以请求连接到任何可用的控制器。一个控制器一次只有一个关联。
在动态控制器模型中,控制器由NVM子系统按需分配,没有从先前的关联中保留任何状态(例如,特征设置)。在静态控制器模型中,主机可以基于控制器ID来请求特定控制器,其中状态(例如,特征设置)从先前的关联中保留。
当主机和控制器之间存在关联时,只有该主机可以通过使用相同的NVM子系统端口、NVMe传输类型和NVMe传输地址在随后的连接命令中呈现相同的主机NQN、主机标识符、NVM子系统NQN和控制器ID来与该控制器的I/O队列建立连接。
如果出现以下情况,主机和控制器之间的关联将终止:
•控制器关闭;
•发生控制器级别重置;
•管理队列或任何I/O队列的主机和控制器之间的NVMe传输连接丢失;或
•任何I/O队列的主机和控制器之间的NVMe传输连接丢失,并且主机或控制器不支持删除单个I/O队列
没有明确的NVMe命令可以中断主机和控制器之间的NVMe传输关联。Disconnect命令提供了一种删除NVMe I/O队列的方法。当控制器与主机关联时,该控制器正忙,并且不能与该控制器进行其他关联。
要使用动态控制器模型,主机在使用Fabrics Connect命令与NVM子系统建立关联时,指定控制器标识符FFFFh。
当将静态控制器模型与结构连接的控制器一起使用时,在关联之间持续存在的状态是在控制器级别重置期间持续存在的任何状态。此外,不同的控制器可以向同一主机呈现不同的功能设置或命名空间附件。NVM子系统可以将特定的控制器分配给特定的主机。
虽然期望将静态控制器分配给主机是持久的(使得主机可以期望重复地(例如,在每次主机重新启动之后)形成与相同控制器的关联),但是NVM子系统可以由于实现特定的原因(例如,控制器资源回收、子系统重新配置)在任何时候移除未使用的控制器的主机分配。
如图20所示,有三种类型的控制器。I/O控制器是一种支持访问存储在NVM子系统非易失性存储介质上的用户数据的命令的控制器,并且可以支持提供管理功能的命令。管理控制器是一种支持提供管理功能的命令的控制器,但不支持访问存储在NVM子系统非易失性存储介质上的用户数据的I/O命令。发现控制器是NVMe over Fabrics中使用的控制器,用于提供对发现日志页的访问。
标识控制器数据结构中的控制器类型(CNTRLTYPE)字段指示控制器的类型。无论控制器类型如何,所有控制器都实现一个管理提交队列和一个管理完成队列。根据控制器类型,控制器还可以支持一个或多个I/O提交队列和I/O完成队列。
当使用基于内存的传输实现(例如PCIe)时,主机软件通过预先分配的提交队列向控制器提交命令。通过SQ Tail Doorbell寄存器写入,控制器会收到新提交的命令的警报。前一个门铃寄存器值和当前寄存器写入之间的差值表示提交的命令数。
控制器从提交队列中获取命令并对其进行处理。除了融合操作外,在提交队列内或跨提交队列处理命令没有顺序限制。主机软件不应将命令提交到不能任意重新排序的提交队列。与命令的处理相关联的数据可以按照提交命令的顺序提交或不提交到NVM子系统非易失性存储器存储介质。
主机软件将优先级较高的命令提交到相应的提交队列。优先级与提交队列本身相关联,因此命令的优先级基于该命令提交到的提交队列。控制器根据规定的仲裁方案,基于公平性和优先级在提交队列之间进行仲裁。
在NVM子系统完成命令执行后,控制器通过适当的完成队列向主机呈现完成队列条目。传输特定方法(例如PCIe中断)用于通知主机要处理的完成队列条目(参阅相应的传输规范)。
对主机的完成没有排序限制。每个完成队列条目标识关联命令的提交队列标识符和命令标识符。主机软件使用此信息将完成与提交到提交队列的命令关联起来。
主机软件负责在使用这些队列对向控制器提交命令之前创建I/O提交队列和I/O完成队列。I/O提交队列和I/O完成队列是使用创建I/O提交队列命令和创建I/O完成队列命令创建的。
I/O控制器是支持使用I/O命令集提供对存储在NVM子系统的非易失性存储介质上的用户数据的访问的命令的控制器,并且可以支持提供管理能力的命令。
一个I/O控制器可以同时支持多个I/O命令集。控制器支持的I/O命令集以及控制器同时支持的这些I/O命令集中的哪一个在识别I/O命令集数据结构中报告。对于NVM子系统中的所有控制器,识别I/O命令集合数据结构的内容不必相同。
图21显示了具有三个I/O控制器的NVM子系统。I/O控制器一有两个附加的命名空间,专用命名空间A和共享命名空间B。I/O控制器二也有两个连接的命名空间,私有命名空间C和共享命名空间B.I/O控制器三没有附加的命名空间。在稍后的某个时间点,共享命名空间B可以被附加到I/O控制器3。
管理控制器是一种旨在提供NVM子系统管理功能的控制器。虽然I/O控制器可能支持这些相同的管理功能,但管理控制器的强制功能较少。与I/O控制器不同,管理控制器不支持访问存储在NVM子系统的非易失性存储介质上的用户数据的I/O命令。NVMe Transports可以支持特定于传输的机制,以允许管理控制器加载专用NVMe管理驱动程序而不是通用NVMe驱动程序(有关详细信息,请参阅适用的NVMe传输绑定规范)。
管理控制器可能支持的管理功能示例包括以下内容。
•能够使用NVMe MI发送命令和NVMe MI接收命令通过NVMe MI有效轮询NVM子系统健康状态(请参阅NVM Express Management Interface Specification中的NVM subsystem health status poll部分);
•能够使用NVMe MI发送命令和NVMe MI接收命令通过NVMe MI管理NVMe机柜;
•能够使用命名空间附件命令和命名空间管理命令管理NVM子系统命名空间;
•能够使用“虚拟化管理”命令执行虚拟化管理;NVM Express®底座
•使用NVM子系统重置(NSSR)寄存器重置整个NVM子系的能力(如果支持);和
•如果支持,可以使用NVM子系统关闭(NSSD)属性关闭整个NVM子系。
管理控制器不应支持I/O队列。命名空间不应附加到管理控制器。
需要一个管理控制器来支持图28中列出的强制性Admin命令。管理控制器可以支持一个或多个I/O命令集。当管理控制器支持I/O命令集时,由于管理控制器只有管理队列而没有I/O队列,因此只能支持特定于I/O命令集的管理命令。
图26显示了一个NVM子系统,该子系统包含一个非易失性存储介质和名称空间,其中包含一个管理控制器和两个I/O控制器。I/O控制器一具有两个连接的命名空间,专用命名空间A和共享命名空间B。I/O控制器二还具有两个附加的命名空间,私有命名空间C和共享命名空间B.由于管理控制器不提供对存储在NVM子系统的非易失性存储介质上的用户数据的访问,因此管理控制器没有连接的命名空间。该示例中的管理控制器可以用于诸如NVM子系统名称空间管理和经由NVMe MI有效地轮询NVM子子系统健康状态之类的任务。虽然此示例显示了单个管理控制器,但NVM子系统可能支持零个或多个管理控制器。
图27显示了在不包含非易失性存储介质或命名空间的NVM子系统中具有一个管理控制器的NVM个子系统。本例中的管理控制器可用于使用NVMe MI管理NVMe机柜。由于管理控制器用于非常特定的专用目的,因此这种管理控制器的实现者可以选择仅实现强制性功能以及NVMe MI发送和NVMe MI接收命令。
发现控制器仅实现与发现日志页相关的功能,而不实现I/O队列、I/O命令或公开命名空间。
主机在将命令连接到发现服务中使用众所周知的发现服务NQN(NQN.2014-08.org.nvmexpress.decovery)。主机用于获取连接到众所周知的发现服务所需的NVMe传输信息的方法是特定于实现的。
发现控制器提供的发现日志页包含一个或多个条目。每个条目指定主机连接到NVM子系统所需的信息。条目可以与暴露名称空间的NVM子系统相关联,或者与对另一个发现服务的引用相关联。发现日志页中的日志页条目没有订购要求。
发现控制器可以根据所提供的主机NQN提供不同的日志页内容(例如,不同的NVM子系统可以由不同的主机访问)。发现日志页条目集应包括与发现服务位于同一结构上的所有适用地址,并且可能包括其他结构上的地址。
支持显式持久连接的发现控制器应同时支持异步事件请求和保持活动命令。主机通过在Connect命令中指定非零的Keep Alive Timer值,请求与发现控制器的显式持久连接,并从该持久连接上的发现控制器请求异步事件通知。如果Connect命令指定非零的Keep Alive Timer值,并且Discovery控制器不支持异步事件,则Discovery控制器应为Connect命令返回Connect Invalid Parameters(连接无效参数)的状态值。发现控制器应在识别控制器数据结构中表示支持发现日志更改通知。
不支持显式持久连接的发现控制器不应支持Keep Alive命令,并且可以使用固定的发现控制器活动超时值(例如,2分钟)。如果这样的发现控制器在该时间段内没有接收到命令,则控制器可以执行保持活动定时器到期的动作。
Discovery控制器不应支持Disconnect命令。
对于同一NVM子系统,具有多个发现日志页面条目的发现日志页面指示存在到NVM子子系统的多个结构路径,和/或多个静态控制器可以共享结构路径。主机可以使用该信息来形成与NVM子系统内的控制器的多个关联。
具有不同端口ID值的同一NVM子系统的多个发现日志页面条目表明所产生的NVMe传输连接相对于NVM子子系统端口硬件故障是独立的。使用单个关联的主机应该选择一个记录连接到NVM子系统。使用多个关联的主机应该选择不同的端口。
可能存在特定于传输的方法来指示对发现控制器的更改。
在发现日志页面条目中返回的控制器ID值指示NVM子系统是支持动态控制器模型还是静态控制器模型。FFFFh的控制器ID值是用于支持动态控制器模型的NVM子系统的特殊值,其指示可以返回任何可用的控制器。FFFEh的控制器ID值是用于支持静态控制器模型的NVM子系统的特殊值,指示可以返回任何可用的控制器。如果发现日志页面条目使用控制器ID值FFFFh,则NVM子系统支持动态控制器模型。如果发现日志页面条目使用的控制器ID值小于FFFFh,则NVM子系统支持静态控制器模型。识别控制器数据结构还指示NVM子系统是动态的还是静态的。
如果NVM子系统实现动态控制器模型,则可以在发现日志页面中为该NVM子模块返回控制器ID设置为FFFFh的多个发现日志页面条目(例如,指示多个NVM子组件端口)。如果NVM子系统实现静态控制器模型,则可以在发现日志页面中为该NVM子子系统返回指示不同控制器ID值的多个发现日志页面条目。如果实现静态控制器模型的NVM子系统包括任何指示控制器ID为FFFEh的发现日志页条目,则主机应记住从Fabrics Connect命令返回的控制器ID,并将分配的控制器ID重新用于将来与该特定控制器的关联。
属性是控制器的dword或qword属性。该属性可能具有读、写或读/写访问权限。除非在特定于传输的规范中另有说明,否则主机应使用为该属性指定的宽度访问该属性,偏移量位于该属性的开头。所有保留属性和属性中的所有保留位都是只读的,读取时返回0h。使用基于消息的传输模型,可以使用“属性获取”命令读取属性,也可以使用控制器的“属性集”命令写入属性。对于使用基于内存的传输模型的控制器,请参阅适用的NVMe传输绑定规范以了解访问方法和规则(例如,NVMe PCIe传输规范)。
图35描述了控制器的属性映射。
不支持以两个或多个属性的任何部分为目标的访问。
软件不应依赖于0h的返回。
以下约定用于描述所有传输模型的控制器属性。硬件应为所有标记为保留的位返回“0”,主机软件应写入所有保留位和值为0h的属性
使用以下术语和缩写:
RO只读
RW读写
RWC读取/写入“1”以清除
RWS读取/写入“1”以设置
Impl Spec Implementation Specific–控制器可以自由选择
它的实施。
HwInit默认状态取决于NVM Express控制器和
系统配置。
重置此列表示第3.7.2节中定义的控制器级别重置后的字段值。
对于某些字段,它是特定于具体实施的字段是RW、RWC还是RO;这通常显示为RW/RO或RWC/RO,以指示如果不支持该功能,则该字段是只读的。
当文档中引用字段时,使用的约定是“属性符号.字段符号”。例如,PCI命令寄存器奇偶校验错误响应启用位的名称为CMD.PEE。如果该字段是一个位数组,则该字段被称为“属性符号。字段符号(数组偏移到元素)”。当文档中引用子字段时,使用的约定是“属性符号.字段符号.子字段符号”。例如,当控制器能力属性中支持的控制器就绪模式字段的控制器就绪媒体支持子字段时,该子字段由名称CAP.CRMS.CRWMS引用。
流程解析说明
①host创建SQ Entry Command 到内存中;
②host更新SQ Tail Doorbell寄存器,通知Control来处理新命令;
③Control从Memory获取SQ command ;
④Control将命令放入可执行列表中等待执行;
⑤在命令被Control执行后,控制器写Completion Queue Entry 到 CQ中;表示最近SQ Entry被获取;
⑥控制器产生一个中断给host表示这有一个CQ Entry需要处理;
⑦host处理CQ Entry命令;
⑧host向CQ head Doorbell Register写值,表示CQ Entry已经被处理。
1.Specifications - NVM Express