注意:本文翻译仅为学习交流用,版权归原文作者所有。
原文出处。
NVM Express TM (NVMe TM)允许主机软件与非易失内存子系统交互。这个接口是针对企业级和客户级固态盘优化的,作为一种寄存器级别的接口连接到PCI Express接口上。
注意:在开发期间,这个规范参考了企业级NVMHCI,但是由于先于完成,名字修改成NVM Express基础规范。这个接口使用于客户级和企业级系统。
对于版本1.3和1.4的修改简介可参考 http://nvmexpress.org/changes 里面的一个文档,描述了新特性,包括控制器遵循版本1.4必须实现的特性。
NVM Express基础规范1.4版本和以前的版本为主机软件定义了寄存器级别的接口,用于主机软件与PCI Express非易失内存子系统交互(NVMe TM over PCIe TM)。NVMe TM over Fabrics规范定义了一种协议接口,和一些与NVMe接口相关的扩展,这个接口赋能际间互连操作,比如以太网,InfiniBand TM,Fibre Channel。NVMe over Fabrics规范为每个NVMe传输规定了接口绑定。
在这个规范中,一些要求/特性可能是专门为NVMe over Fabrics实现或者特殊的NVMe传输接口绑定而写的。另外,对特性和功能支持要求可能在NVMe over PCIe和NVMe over Fabrics实现上有所不同。
这个规范定义寄存器接口,用于在NVM子系统中与控制器交互。它也定义了一些标准指令集,这些指令集可能被控制器支持。有三种不同能力的寄存器:
寄存器接口和命令集与NVM使用的模型不同,仅指定与NVM子系统交互接口。因此,这个规范并没有指定非易失内存系统被当作固态盘、主存、cache缓存,后端内存、冗余内存等。具体的使用模型是在本规范讨论范围之外。
这个接口指定任何非易失内存的管理,比如磨损均衡。对像NAND等非易失技术的擦除和管理技术是被抽象的。
这个规范不包含任何缓存算法和技术的信息。
NVM Express可扩展接口被设计用于处理企业级和客户级系统的需求,这些系统利用PCI Express运行在固态盘或者fabric连接的设备上。这个接口提供了命令完成和命令提交路径的优化。它支持并行操作,支持多达65535个IO队列,每个队列能容纳(64Ki-1)个未完成IO。另外,添加了像企业级要求的端到端数据保护(兼容SCSI保护信息,T10 DIF, SNIA DIX标准)能力,增强型错误报告,虚拟化等。
这些接口有一下关键属性:
这个规范定义了一系列流水线式寄存器,功能如下:
一个NVM Express控制器与单个PCI Function关联。功能(capability)和设置在CAP寄存器(Controller Capabilities)和Identify Controller数据结构中被指示,这个设置被应用到整个控制器。
命名空间是大量的备格式化为逻辑块的非易失内存。一个NVM Express控制器可能支持多个命命名空间,通过命令空间ID标识。命令空间能够通过Namespace Management/Attachment命令创建和删除。Identify命令空间数据结构指示某个命名空间的功能和设置。对于所有命名空间一样的capability和setting由Identify命名空间数据结构报告,命名空间ID为FFFFFFFFh.
NVM Express接口是以提交队列和完成队列机制为基础的。在主机软件中命令被放到提交队列。在控制器里,完成项被放到与之关联的完成队列中。多个提交队列可能使用相同的完成队列吗,完成队列在内存中分配。
Admin提交和关联的完成队列存在的目的是,控制器的管理和控制(I/O提交队列和完成队列、终止命令的创建和删除),只有Admin命令集才可能放到Admin提交队列。
I/O 命令集被一对I/O队列使用。规范定义一个I/O命令集为NVM命令集。主机选择一个I/O命令集,这个命令集用于所有I/O队列。
主机软件创建队列,最大的数量由控制器决定。往往创建的命令队列数量是以系统配置和负载为基础的。比如,在一个四核处理器系统上,可能安排每个核一个队列对,避免锁和确保数据结构在处理器核的缓存中被创建。图1提供图形化展示,提交队列和完成队列1:1,图2显示多个I/O提交队列使用相同的I/O完成队列。图1和图2在Admin提交和完成队列是1:1.
提交队列是一个环形缓冲,每个槽位大小固定,主机软件提交命令,控制器执行命令。当有新命令执行时候,主机软件更新SQ尾部doorbell寄存器。当有新的doorbell写时,之前的SQ尾部的值在寄存器中被覆盖,控制器从提交队列中有序取回SQ项,然后以任意顺序执行这些命令。
每个提交队列项是一个命令,命令大小是64字节。在内存中用于数据传输的物理内存位置通过PRP(Physical Region Page)项或者SGL(Scatter Gather Lists)指定,每个命令包含两个PRP项或者一个SGL段。如果描述数据缓存需要两个以上PRP项,那么提供一个指针,指向PRP List,这个PRP List描述一个PRP项list。如果需要至少一个以上SGL段描述数据缓存,那么SGL段提供一个指针,指向下一个SGL段。
一个完成队列是一个环形缓冲,每个槽大小固定,用于记录完成命令的状态。一个完成命令被一个关联的SQ ID和由主机软件分配的命令id唯一标记。多个提交队列可能与一个完成队列关联。这个特性能在这个场景下使用,即一个工作线程通过一个完成队列处理所有命令完成,即使这些命令来自于多个提交队列。CQ头指针在处理完完成队列项后,由主机软件更新,指示最后一个空闲的CQ槽位。Phase Tag§在完成队列项中被定义,表示这个项是否被报告,并且不用咨询寄存器。这也能用于主机判断这个项是否被作为以前或者当前环形中是否完成的提示。具体的是,每次走完一个完成队列项的环时,控制器对Phase Tag做反转。
这个章节提供多路径I/O和命名空间共享简介。多路径I/O是指在单个主机和命名空间之间存在两个及以上完全独立的路径,命名空间共享是指一种能力,即两个及以上主机使用不同NVM Express控制器访问相同的命名空间。多路径IO和命名空间共享要求NVM子系统包含两个及以上的控制器。NVM子系统支持多路径IO和命名空间共享,也支持非对称控制器行为。两个及以上个主机同时访问共享命名空间需要主机间协调。如何协调主机超过本规范范畴。
图3显示NVM子系统包含单个NVM Express控制器,和单个PCI Express端口,因为这是单个Function PCI Express设备,NVM Express控制器与PCI Function0关联。一个控制器可能支持多个命名空间。图3中的控制器支持两个命名空间,标记为NS A和 NS B,与每个命名空间关联的是命名空间ID,被标记为NSID1何NSID2,被控制器使用指示特定命名空间。命名空间ID是不同于命名空间本身的。主机和控制器使用这个句柄在命令中指定特定空间。命名空间选取超过本规范范围。在实验中,命名空间ID1与命名空间A关联,命名空间ID2与命名空间B关联。命名空间对控制器是私有的,这个配置不支持多路径IO和命名空间共享。
图4显示一个多Function NVM子系统,包含单个PCI Express端口,两个控制器。一个控制器关联到PCI Function 0,另一个控制器关联到PCI Function 1。每个控制器支持单个私有命名空间,并且访问特定共享命名空间。
每个支持单个私有命名空间和访问共享命名空间B。命名空间ID在所有命名空间中都是相同的,这些控制器访问特定共享命名空间。在这个例子中,所有控制器使用命名空间ID2访问共享命名空间B。
对于每个控制器有唯一Identify数据结构,和唯一Identify命名空间数据结构。控制器访问共享命名空间并且返回Identify Namespace与共享命名空间关联的数据结构。这个全局唯一与命名空间关联标识符可能用于判断何时多个路径共享相同命名空间。
与共享命名空间关联的控制器可能并发操作一个命名空间。单个控制器执行的操作对共享命名空间是原子性的,此时提交的命令对于控制器是原子写级别。原子写并不要求多个控制器共享命名空间。如果下发到不同控制器之间的命令有顺序要求,那么主机软件需要执行这些顺序要求。
图5描述了带有两个PCI Express端口NVM子系统,每个端口与控制器关联。两个控制器都关联到PCI Function 0的相应端口上。在例子中的PCI Express端口是完全独立的,有自己的PCI Express基础的Reset和输入时钟参考电压。图5中两个port可能会与相同的Root Complex或者不同的Root Complex关联在一起,并且用于实现多路径IO和IO共享架构。
图6描述支持 Single Root I/O Virtualization(SR-IOV),有四个Physical Function和4个 Virtual Functions。一个NVM Express控制器与每个Function关联。
非对称控制器行为发生在NVM子系统,命名空间访问特性会基于下面两点变化:
NVM子系统提供非对称行为,可能会支持Asymmetric Namespace Access Reporting。
对于寄存器的保留位,硬件可能会返回0
。软件可能会为所有寄存器保留位写值0h
。
寄存器中的值:
Admin Queue 是 ID0的提交队列和完成队列,Admin提交队列和相应的Admin完成队列被用于提交管理命令和接收完成信息。
Admin Submission Queue是与Admin Completion Queue唯一关联的。
暴露capabilities的控制器允许主机参与NVM子系统管理。Administrative控制器不实现IO队列,提供数据和元数据的访问,这些信息与非易失内存存储介质上的逻辑块关联,或者支持与依附于administrative controller的命名空间。
提交队列一次能发送的最大命名数量,这些命令通过round robin或者加权并且带有优先级仲裁的round robin发送。
判断哪个提供队列发送控制器执行命令,有两种冲裁机制,round robin,加权带仲裁优先级的round robin,厂商自定义。
NVM子系统使用缓存,不能被主机访问,可能包含非易失介质上数据或者包含还未写入到非易失介质上的数据。
已经传输到控制器,并且控制器准备执行的命令。
控制器完成处理命令,并且命令完成状态已经被更新到完成队列项,并且报抛到关联的完成队列中。
NVMe over PCIe实现,当提交队列Tail Doorbell写被完成,并且移动Submission Queue Tail指针。
控制器是主机和NVM子系统之间的接口,有三种类型控制器:
控制器执行被主机在Submission Queue上提交的命令,并且发布完成信息到Completion Queue上。所有控制器实现一个Admin Submission Queue和一个Admin Completion Queue.根于控制器的类型,控制器可能实现一个或者多个IO提交队列和完成队列。当使用PCI Express作为传输时,控制器作为PCI Express Function。
主机与NVM子系统之间的信息交互。
Discovery Log Page.
用软件定义的控制器,底层没有相应的物理NVMe controller(比如,物理PCIe function)
…
与LBA数据相关的连续LBA.
firmware slot是NVM子系统用于存放firmware镜像的位置,NVM子系统存放1~7个firmware镜像。
…
主机和controller读或者写的内存,但是不会被controller暴露(i.e.,Controller Memory Buffer或者Persistent Memory Region)。主机内存能够在主机里面或者外面实现,e.g.,设备暴露的一段内存,既不是主机的也不是controller的。
提交到IO提交队列的命令。
IO完成队列标识符为1~65535
控制器实现IO队列,并且用于访问非易失内存存储介质。
IO提交队列标识ID是1~65535。
连续的逻辑地址,由起始LBA和逻辑块个数表示。
最小的读写命令可寻址单位。
逻辑块地址,一般指的是LBA。
元数据是特定一段LBA范围的数据的上下文信息。主机可能包含NVM子系统存储的元数据,如果存储空间是由controller提供的。元数据可能包含保护信息(Protection Information)。
许多非易失内存被格式化为逻辑块。当被格式化时,尺寸为n的命名空间是逻辑块地址0~n-1的集合。
…
…
…
NVM子系统包含一个至多个controller,0至多个namespace,1至多个port,包含非易失内存介质,以及非易失介质与controller的接口。
primary controller支持虚拟化管理命令。NVM子系统包含多个primary controller,secondary controller依赖primary controller动态资源管理。
PCI Express SR-IOV Physical Function 支持NVM Express接口和虚拟化增强capability。
一次进附加到一个controller上,主机能决定一个命名空间是否是私有命名空间。
…
…
…
…
数据由逻辑块数据和可选的元数据组成。
关键字用于表示requirement不同级别。
按照规范定义被实现。
灵活选择。
可选。
R被用作reserved的缩写。
指示bits,bytes,words,fields和opcode值被闲置用作将来使用。
应该实现。
灵活选择,但是建议实现。
byte-> 8比特,word->2字节,dword->4字节。