fpga nvme 寄存器

news2024/11/24 9:17:31

图1所示的NVMe多队列,每个队列支持64K命令,最多支持64K队列。这些队列的设计使得IO命令和对命令的处理不仅可以在同一处理器内核上运行,也可以充分利用多核处理器的并行处理能力。每个应用程序或线程可以有自己的独立队列,因此不需要IO锁定。NVMe还支持MSI-X和中断控制,避免了CPU中断处理的瓶颈,实现了系统扩展的可伸缩性。NVMe采用简化的命令集,相比SAS或SATA,NVMe命令集使用的处理IO请求的指令数量减少了一半,从而在单位CPU指令周期内可以提供更高的IOPS,并且降低主机中IO软件堆栈的处理延迟。

2 NVMe寄存器

NVMe(Over PCIe)寄存器主要分为两类,一类是PCIe配置空间寄存器,一类是NVMe控制器相关的寄存器。

a.PCIe配置空间和功能

NVMe PCIe总线寄存器如表1所示,NVMe跟主机CPU的接口主要是基于PCIe总线,使用PCIe的Config和Capability机制。包括PCI/PCIe头、PCI功能和PCIe扩展功能。

表1 NVMe PCIe配置空间和功能

 

b.NVMe控制器寄存器

NVMe控制器寄存器位于MLBAR/MUBAR寄存器(PCI BAR0和BAR1)中,这些寄存器应映射到支持顺序访问和可变访问宽度的内存空间。NVMe 1.3d版本的控制器寄存器列表如表2所示。

表2 NVMe 1.3d版本的控制器寄存器列表

起始结束缩写描述
0h7hCAP控制功能
8hBhVS版本
ChFhINTMS中断屏蔽设置
10h13hINTMC中断屏蔽清楚
14h17hCC控制器配置
18h1BhReserved保留
1Ch1FhCSTS控制器状态
20h23hNSSRNVM子系统重置(可选)
24h27hAQA管理队列属性
28h2FhASQ管理提交队列基地址
30h37hACQ管理完成队列基地址
38h3BhCMBLOC控制器存储缓冲位置(可选)
3Ch3FhCMBSZ控制器存储缓冲大小(可选)
40h43hBPINFO引导分区信息(可选)
44h47hBPRSEL引导分区读选择(可选)
48h4FhBPMBL引导分区存储缓冲位置(可选)
50hEFFhReserved保留
F00hFFFhReserved命令设置具体的寄存器
1000h1003hSQ0TDBL管理SQ0尾Db
1000h + (1 * (4 << CAP.DSTRD))1003h + (1 * (4 << CAP.DSTRD))CQ0HDBL管理CQ0头Db
1000h + (2 * (4 << CAP.DSTRD))1003h + (2 * (4 << CAP.DSTRD))SQ1TDBLSQ1尾Db
1000h + (3 * (4 << CAP.DSTRD))1003h + (3 * (4 << CAP.DSTRD))CQ1HDBLCQ1头Db
1000h+ (2y * (4 << CAP.DSTRD))1003h + (2y * (4 << CAP.DSTRD))SQyTDBLSQy尾Db
1000h + ((2y + 1) * (4 << CAP.DSTRD))1003h + ((2y + 1) * (4 << CAP.DSTRD))CQyHDBLCQy头Db
供应商定制寄存器(可选)
SQ:Submission Queue,提交队列;CQ:Completion Queue,完成队列;Db:Doorbell,门铃。

3 NVMe队列

NVMe的队列是经典的环形队列结构,通过提交/完成队列对来实现队列的传输交互。

a.队列概述

NVMe使用的是经典的循环队列结构来传递消息(例如,传递命令和命令完成通知)。队列可以映射到任何PCIe可访问的内存中,通常是放在主机内存。

如图2,队列是固定大小的,通过Tail和Head来分别指向写入和读取的指针。像通常的队列数据结构一样,队列实际可使用的大小是队列大小减1,并且用Head等于Tail指示队列空,用Head等于(Tail+1)除以队列大小的余数来指示队列满。

 如上一节的图1,根据用途,NVMe队列有两类:管理队列和IO队列;根据传输方向有两类:提交队列和完成队列。具体介绍见表3。

表3 NVMe队列类型

管理IO
提交用于提交管理命令,最大4K项;
用于配置控制器和IO队列等;
从主机侧到控制器侧。
用于传输IO命令,最大64K项;
用于提交IO操作命令;
从主机侧到控制器侧。
完成管理命令的完成确认,最大4K项;
从控制器侧到主机侧;
独立的MSI-X中断处理。
IO命令的完成确认,最大64K项;
从控制器侧到主机侧;
独立的MSI-X中断处理。

b.队列处理流程

NVMe的驱动和设备交互跟Virtio不同:Virtio是在通过一个队列完成双向通知交互;而NVMe则采用提交队列和完成队列配合完成双向交互的方式。

如图3,NVMe队列处理流程如下(其中主机为软件驱动,控制器为硬件设备):

(1)主机写命令到提交队列项中。

(2)主机写DB(Doorbell)寄存器,通知控制器有新命令待处理。

(3)控制器从内存中的提交队列中读取命令。

(4)控制器执行命令。

(5)控制器更新完成队列,表示当前的SQ项已经处理。

(6)控制器发MSI-x中断到主机CPU。

(7)主机处理完成队列,同步更新提交队列中的已处理项。

(8)主机写完成队列Db到控制器,告知完成队列项已释放。

4 NVMe命令结构

我们通过如下一些概念来理解NVMe命令结构:

队列项的数据格式。NVMe的提交命令固定64字节,完成命令固定16字节。

命令。NVMe命令分为Admin和IO两类。

NVMe的数据块组织方式有PRP和SGL两种。

a.队列项的数据格式

提交队列和完成队列,组成队列对,协作完成NVMe驱动和设备之间的命令传输。提交队列每一项64字节固定大小,完成队列每一项16字节固定大小。

提交队列的数据格式如图4所示。NVMe提交队列项的数据格式属性如下:

Opcode:命令操作码

FUSE:熔合两个命令为一条命令

PSDT:PRP或SGL数据传输

Command Identifier:命令ID

Namespace Identifier:命名空间ID

Metadata Pointer:元数据指针

PRP entry 1/2:物理区域页项,对应的由PRP和PRP列表

SGL:散列聚合列表

 完成队列的数据格式如图5所示。

图5 完成队列项的数据格式

NVMe完成队列的数据格式属性如下:

SQ Header pointer:SQ头指针

SQ Identifier:SQ ID

Command Identifier:命令ID

P:相位标志phase tag,完成队列没有head/tail交互,通过相位标志实现完成队列项的释放

Status Field:状态域

b.NVMe命令

NVMe管理类的命令如表4所示。

表4 NVMe管理命令列表

NVMe IO类命令如表5所示。

表5 NVMe IO类命令列表

命令必选或可选类别
创建IO SQ必选队列管理
删除IO SQ必选
创建IO CQ必选
删除IO CQ必选
鉴别必选配置
获取特征必选
设置特征必选
获取日志页必选状态报告
异步事件请求必选
中止必选中止命令
固件镜像下载可选固件更新和管理
固件可用可选
IO命令集定制命令可选IO命令集定制
供应商定制命令可选供应商定制

NVMe IO类命令如表5所示。

表5 NVMe IO类命令列表

命令必选或可选类别
必选必选的数据命令
必选
清洗必选
不可改正的写可选可选的数据命令
写0可选
比较可选
数据集管理可选数据提示
预约获取可选预约命令
预约寄存器可选
预约释放可选
预约报告可选
供应商专用命令可选供应商专用

c.物理区域页PRP

PRP本质是一个链表,链表中的每一个指针都指向一个不超过页大小的数据块。PRP为8字节(64bits)固定大小,PRPList则最多可以占满一整个页。

PRP1和PRP2的格式如图6(a)所示。如果是首个PRP,则Offset(偏移量)可能是非零的数据,另外,偏移量是32bits对齐的(即末尾两位为0)。如图6(b)所示,在PRP列表中的所有PRP项的偏移量都为0,也即是PRP指针指向页面起始地址。

 如图7(a)所示,当数据只有一个或两个页面的时候,就不需要使用PRP列表数据结构,直接PRP1和PRP2指向内存页面。当一个命令指向的数据超过两个内存页面的时候,就需要使用PRP列表,图7(b)所显式的为使用PRP列表的数据结构。

(b) 范例2:PRP列表指针,指向PRP列表,再指向内存页面

图7 PRP数据结构范例

d.散列聚合列表SGL

PRP每个链表指针最多指向一个页大小的数据块,即使若干个页在内存连续放置,PRP也需要对应的多个PRP项。为了减少元数据规模,SGL不限制指针指向数据块的大小,这样连续的若干个页的数据,只需要一个SGL项就可以标识。

NVMe中SGL的长度为16字节固定长度,其格式如图8(a)所示,在最高的第15字节SGL描述符类型域和子类型域标识不同类型的SGL描述符,根据不同的描述符,字节14-0的格式各有不同。SGL描述符类型如图8(b)所示。

如图9,NVMe SGL的数据结构是链表形式,SQ中的首个SGL段只有1项,为指向下一个SGL段的指针。下一个SGL段包含若干SGL数据块描述符,SGL段的最后的一个SGL描述符为另一个SGL段指针,指向下一个SGL段。根据传输数据大小,在最后一个SGL 段中,所有的SGL描述符都是SGL数据块描述符。

PRP只能指向单个内存页,这样,当要传输的数据块非常大的时候,就需要非常多的PRP项。而SGL可以指向不同大小的数据块,处于连续内存区域的多个数据块只需要一个SGL描述符就可以标识。因此,一般情况下,SGL比PRP更高效,更节省描述符资源。

NVMe over PCIe协议,定义了NVMe协议的使用范围、指令集、寄存器配置规范等。

1.1 名词解释

1.1.1 Namespace

Namespace是一定数量逻辑块(LB)的集合,属性在Identify Controller中的数据结构中定义。

1.1.2 Fused Operations

Fused Operations可以理解为聚合操作,只能聚合两条命令,并且这两条命令在队列中应保持相邻顺序。协议中只有NVM指令才有聚合操作。还需要保证聚合操作的两条命令读写的原子性,参考Compare and Write例子。

1.1.3 指令执行顺序

除了聚合操作(Fused Operations),每一条SQ中的命令都是独立的,不必考虑RAW等数据相关问题,即使考虑,也是host应该解决的问题。

1.1.4 写单元的原子性

控制器需要支持写单元的原子性。但有时也能通过host配置Write Atomicity feature,减小原子性单元的大小,提高性能。

1.1.5 元数据

数据的额外信息,相当于提供校验功能。可选的方式。

1.1.6 仲裁机制

用来选择下一次执行的命令的SQ的机制,三种仲裁方式:

  • RR(每个队列优先级相同,轮转调度)

  • 带权重的RR(队列有4种优先级,根据优先级调度)

  • 自定义实现

  • 1.1.8 Queue Pair

    由SQ(提交队列)与CQ(完成队列)组成,host通过SQ提交命令,NVMe Controller通过CQ提交完成命令。

    1.1.9 NVM 子系统

    NVM子系统包括控制器、NVM存储介质以及控制器与NVM之间的接口。

    1.2 NVMe SSD

    1.2.1基本架构

    整体来看,NVMe SSD可以分为三部分,host端的驱动(NVMe官网以及linux、Windows已经集成了相应的驱动)、PCIe+NVMe实现的控制器以及FTL+NAND Flash的存储介质。

  •  

    1.2.2 NVMe控制器

    NVMe控制器实质上为DMA + multi Queue,DMA负责数据搬运(指令+用户数据),多队列负责发挥闪存的并行能力。

  •  

    2. PCIe寄存器配置

    NVMe over PCIe,通过利用PCIe总线实现数据交互的功能,实现对物理层的抽象功能。

    2.1 PCIe总线的基本结构

    PCIe总线分为三层,物理层,数据链路层,处理层(类似于计算机网络的分层结构),通过包来转发数据。NVMe协议定义的内容相当于PCIe的上一层应用层,处于应用层。PCIe给NVMe提供了底层的抽象。

    NVMe SSD相当于一个PCIe的端设备(EP)。

  •  

    2.2 寄存器配置

    在协议中主要定义了PC header、PCI Capabilities和PCI Express Extended Capabilities三部分内容。

    具体在host内存中会占有4KB,结构如下:

  •  

    2.2.1 PCI header

    PCI header有两种类型,type0表示设备,type1表示桥。NVMe 控制器属于EP,所以定义为type0的类型。共64KB,如下图:

  •  

    2.2.2 PCI Capabilities

    这里配置了PCI Capbilities,包括电源管理、中断管理(MSI、MSI-X)、PCIe Capbilities。

    2.2.3 PCI Express Extended Capabilities

    这里配置有关错误恢复等高级功能。

    3. NVMe寄存器配置

    3.1 寄存器定义

    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寄存器。


  •  

    3.2 寄存器理解

  • 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。
     

    4. 内存数据结构

    4.1 SQ与CQ的详细定义

    4.1.1 空队列

 

4.1.2 满队列

判断队列满可以有多种方法,协议中规定的是头指针比尾指针大一,所以队列满时,空余一个元素。

 

4.1.3 队列性质

1. 队列大小有16bit,最小队列大小为2个元素(因为满队列的定义方式,所以最小为2个元素),对于I/O队列,最大队列大小为64k;对于Admin队列,最大队列为4k;

2. QID来标识唯一ID,16bit,由host分配;

3. host可以修改队列优先级(如果支持的话),共四级,U、H、M、L;

4.2 仲裁机制

4.2.1 RR

RR仲裁,Admin SQ与I/O SQ优先级相同,控制器每次可以选择一个队列中的多个命令(Arbitration Burst setting)。

 

4.2.2 带有优先权的RR

有3个严格的优先权,Priority1 > Priority2 > Priority3,在这三个优先级队列中,高优先级的队列中如果有命令,则优先执行(非抢占式)。

 

4.2.3 其他仲裁方式

Vendor Specific。

4.3 数据寻址方式(PRP和SGL)

4.3.1 PRP

NVMe把Host的内存分为页的集合,页的大小在CC寄存器中配置,PRP是一个64位的内存物理地址指针,结构如下:

 

最后两位为0,指四字节对齐;(n:2)位表示页内内偏移。

举个例子,内存页大小位4KB,则(11:2)表示页内偏移。

PRP寻址有两种方式,直接用PRP指针寻址,通过PRP List寻址。当使用PRP List寻址时,偏移必须为0h,每一个PRP条目表示一个内存页,如下:

 

 

Admin命令的数据地址只能采取PRP的方式,I/O命令的数据地址既可以采取PRP的方式,又可以采取SGL的方式。Host在命令中会告诉Controller采用何种方式。具体来说,如果命令当中DW0[15:14]是0,就是PRP的方式,否则就是SGL的方式。

命令的Dword6~Dword9只定义了PRP1、PRP2两个数据指针,通过PRP条目可以指向PRP List。如下图:

 

 

在上面的例子中,PRP1直接指向内存页,PRP2指向PRP List存在的地址,在PRP List中存有数据的真正的地址。

更详细的说:

协议中PRP Entry是一个指向物理内存页的指针。PRP被用作NVMe Controller和PC内存之间进行数据传输。PRPEntry是固定大小的(8B)。

首先,明确两个概念,PRP Entry 为PRP指针,PRP List为PRP列表指针,示意图如下:

 

 

根据每次传输数据的大小,以及PRP指针的偏移(offset)可以分为以下五种情况:

 

 

 

4.3.2 SGL

SGL是另外一种索引内存的数据结构。SGL由若干个SGL段组成,SGL段又由若干个SGL描述符组成,所以SGL描述符是SGL数据结构的基本单位。

目前定义的SGL描述符有6种:

5.4 NVM指令

NVMe控制器读写的最小单元是LB,层次图如下:

 NVM指令与Admin指令结构完全相同,也是通过Dword0中的8位操作码来定义不同指令。

  1. SGL 数据描述符,用来索引数据块地址,host内存;

  2. SGL 垃圾数据描述符,用来索引无用数据;

  3. SGL 段描述符,用来索引下一个SGL段;

  4. SGL 最后一个段描述符,用来索引最后一个SGL段;

  5. keyed SGL 数据描述符;

  6. Transport SGL 数据描述符;

     

    在上面SGL例子中,共有3个SGL段,用到了4种SGL描述符。Host需要往SSD中读取13KB的数据,其中真正只需要11KB数据,这11KB的数据需要放到3个大小不同的内存中,分别是:3KB,4KB和4KB。

    4.3.3 比较PRP与SGL

    无论是PRP还是SGL,本质都是描述内存中的一段数据空间,这段数据空间在物理上可能连续的,也可能是不连续的。Host在命令中设置好PRP或者SGL,告诉Controller数据源在内存的什么位置,或者从闪存上读取的数据应该放到内存的什么位置。

    SGL和PRP本质的区别在于,一段数据空间,对PRP来说,它只能映射到一个个物理页,而对SGL来说,它可以映射到任意大小的连续物理空间,具有更大的灵活性,也能够描述更大的数据空间。如下图:

     

    5. NVMe协议定义的命令

    5.0 命令执行过程

    命令由host提交到内存中的SQ队列中,更新TDBxSQ后,NVMe控制器通过DMA的方式将SQ中的命令(怎么取,如何取,取多少,因设计而异)取到控制器缓冲区,执行命令;执行完成后,根据执行状态,组装完成命令,仍然通过DMA的方式将完成命令写入内存CQ的队列中;NVMe控制器通过MSI-X中断方式通知host已完成命令;最后,host处理CQ命令,更新控制器中HDBxCQ,标识着命令真正完成。

    5.1 命令分类

    命令分为Admin指令与NVM指令(I/O指令)。

    Admin指令只能提交到Admin Controller中,主要负责管理NVMe控制器,也包含对NVM的一些控制指令。

    NVM 指令只能提交到I/O Controller中,主要负责完成数据的传输。

    在1.0e版本中,Admin指令有15条(3条与NVM相关),NVM指令有6条;在1.3d版本中,Admin指令有15条(3条与NVM相关),NVM指令有11条。

    5.2 命令通用格式

    命令均为64字节,具有相同的格式,某些字段根据命令的不同有不同的定义。

    完成命令同样具有相同的格式,某些字段根据命令的不同有不同的定义。

    5.3 Admin 指令

    Admin指令与NVM指令根据放置的的队列组(Queue Pair)来区分,Admin指令在Admin CQ与SQ里,NVM指令在I/O CQ与SQ里。

    通过Dword0中的8位操作码定义不同指令,注意并不是绝对的顺序增加(eg,没有03h)。每一种指令都对应有其完成命令,通过SQID(提交队列ID)+CID(命令ID)唯一标识完成的命令。

    Note:

  7. Admin队列是通过配置ASQ等寄存器创建的

  8. 先创建CQ再创建SQ

6 控制器结构

控制器从功能上可以分为三类,I/O、Admin和Discovery

 

在实现过程中,Admin 控制器只有一个,负责管理控制器及其他控制功能。控制器只是抽象的概念,应用于具体的实现中,可能是一个具体的模块,也可能多个模块。

控制器主要的作用是实现对NVMe定义命令的翻译,从而实现数据传输、状态控制等功能。

6.1 命令执行过程

1. host将命令(1条或者多条)写入提前分配好的SQ中;

2. 更新对应SQ的DB寄存器;

3. NVMe控制器取SQ中命令(通过HDB和TDB可以判断是否有未完成命令);

4. NVMe控制器执行命令;

5. NVMe 控制器在命令完成后,将完成命令(可能执行成功,也可能失败,但都会返回完成命令)写入host内存SQ对应的CQ中;

6. NVMe 控制器根据实现的中断方式,提醒host命令已完成;

7. host响应中断,处理完成命令;

8. host 更新对应CQ的DB寄存器。

 

6.2 重启(Reset)

6.2.1 Controller level

Controller重启可能发生在PCIe总线重启、PCI重启、控制器CC.EN从1到0重启。当重启发生时:

  1. 所有的I/O SQ和CQ都被删除;

  2. 所有未完成的指令(Admin和I/O)应该执行撤销操作;

  3. Controller处于idele状态,CSTS.RDY清0;

  4. AQA、ASQ、ACQ不受影响。

重启后,host操作:

  1. 更新寄存器状态;

  2. 将CC.EN置1;

  3. 等待CSTS.RDY置1;

  4. 使用Admin命令配置Controller;

  5. 创建I/O CQ和SQ;

  6. 执行正常的I/O指令。

6.2.2 Queue level

队列水平的重启,即,删除该队列,再重新创建一个新队列。删除队列的时候,host应该保证队列处于idle状态(所有命令均已完成——接收到了完成命令),否则的话,可能会导致CQ接收不到提交命令的完成命令。

6.3 中断

在Controller完成SQ命令后,根据执行状态,将结果组装成完成命令写入CQ中,Controller通过中断机制通知Host处理完成命令。

NVMe协议中支持的中断方式有4种,pin-based、Single MSI、Multi-message MSI和MSI-X,协议推荐采用MSI-X中断方式,能够支持更多的中断向量(2K)。

MSI-X允许每一个CQ发送自己的中断信息(相比于发一条中断信息提醒全部CQ队列有很大的优势)。在产生MSI-X中断信息前,需要检查该中断在相应寄存器种不被屏蔽。

6.4 Controller初始化

Controller的初始化过程:

  1. 设置PCI和PCIe寄存器;

  2. 等待CSTS.RDY变为;

  3. 配置AQA、ASQ、ACQ寄存器;

  4. 配置CC寄存器;

  5. 将CC.EN置1;

  6. 等待CSTS.RDY置1

  7. Host通过Identify命令,确定Controller的数据结构、确定Namespace的数据结构;

  8. Host通过get features(协议中是set features,待研究)获取I/O SQ和CQ信息,然后配置中断机制;

  9. Host分配适当的I/O CQ、SQ队列;

  10. 如果Host希望获取Controller的错误或健康信息,可以添加异步事件请求命令。

Controller 关机

正常关机:

  1. Host停止提交新的I/O命令,但允许未完成的命令继续完成;

  2. Host删除所有I/O SQ,删除所有SQ队列后,所有未完成的命令将被撤销;

  3. Host删除所有I/O CQ;

  4. Host将CC.SHN置01b,表示正常关机;关机程序完成时,将CSTS.SHST置10b。

突然关机:

  1. Host停止提交新的I/O命令;

  2. Host将CC.SHN置10b,表示突然关机;关机程序完成时,将CSTS.SHST置10b

6.5 host端命令实例

6.5.1 创建命令

 6.5.2 处理完成命令

 

6.6 NVMe与PCIe交互实例(分析包结构)

以Host发出read命令为例。

  1. Host准备了一个Read命令给SSD:

     

    分析该包,Host需要从起始LBA 0x20E0448(SLBA)上读取128个DWORD (512字节)的数据,读到哪里去呢?PRP1给出内存地址是0x14ACCB000。这个命令放在编号为3的SQ里 (SQID = 3),CQ编号也是3 (CQID = 3)

  2. Host通过写SQ的Tail DB,通知Controller来取命令:

     上图中,上层是NVMe层,下层是PCIe传输层的TLP。Host想往SQ Tail DB中写入的值是5。PCIe是通过一个Memory Write TLP来实现Host写CQ的Tail DB的。该Tail DB寄存器映射在Host的内存地址为F7C11018,由于NVMe 的寄存器映射到了Host内存中,所以可以根据这个地址写入寄存器值
    SSD收到通知,去Host端的SQ中取指

     

    PCIe是通过发一个Memory Read TLP到Host的SQ中取指的。可以看到,PCIe需要往Host内存中读取16个DWORD的数据(一个NVMe指令大小),

  3. SSD执行读命令,把数据从闪存中读到缓存中,然后把数据传给Host:

     

    SSD是通过Memory write TLP 把Host命令所需的128个DWORD数据写入到Host命令所要求的内存中去。SSD每次写入32个DWORD,一共写了4次。

  4. SSD往Host的CQ中返回状态:

     

    SSD是通过Memory write TLP 把16个字节的命令完成状态信息写入到Host的CQ中。

  5. SSD采用中断的方式告诉Host去处理CQ

     

上图使用的是MSI-X中断方式。这种方式将中断信息和正常的数据信息一样,PCIe打包把中断信息告知Host。SSD还是通过Memory Write TLP把中断信息告知Host,这个中断信息长度是1DWORD。

  1. Host处理相应的CQ

  2. Host处理完相应的CQ后,需要更新SSD端的CQ Head DB告知SSD处理

完成:

 

Host还是通过Memory Write TLP更新SSD端的CQ Head DB。

该过程完整的包流程如下:

 

7. NVMe features

7.1 固件(Firmware)更新过程

1. 将固件下载到Controller中(使用 Firmware Image Download命令);

2. Host提交Firmware Activate命令(也可以激活之前版本的Controller镜像);

3. Controller reset;

4. reset完成后,Host重新初始化Controller,包括Host重新分配I/O队列,与reset步骤相同。

7.2 元数据(Metadata)传输

元数据的使用并没有强制规定,最经常的使用方法是用做端到端数据的保护信息。有两种传输元数据的方式,一种可以作为LB数据块的一部分,如下图:

 

7.3 端到端的数据保护

端到端,一端指主机的内存空间,一端指闪存空间(NVM)。数据传输的两个环节如下图:

 

 

数据在PCIe上传输的时候,由于信道噪声的存在(说白了就是存在干扰),可能导致数据出错;另外,Controller闪存之间,数据也可能发生错误。采用元数据进行数据的保护是最常用的一种手段。

充当保护数据角色的元数据结构如下:

 其中,Guard为16bit的CRC校验码,Application Tag与LBAT相关,Reference Tag将用户数据和地址(LBA)相关联。下图为以512bytes的数据块为例:

 

那么按照排列组合,共有四种保护情况(1带2带、1不带2不带、1带2不带、1不带2带)。但由于协议中控制保护信息的只有两个字段(1. 是否采用保护 2. PRACT位),只有三种情况,如下图(是以写命令为例,读命令相同):

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14257.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Nacos的注册中心与配置中心

基于Nacos的注册中心与配置中心 Nacos简介 概述 Nacos全称是动态命名和配置服务&#xff0c;Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos主要用于发现、配置和管理微服务。 什么是Nacos Nacos支持几乎所有主流类型的服务的发现、配置和…

同花顺_代码解析_技术指标_A

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 目录 ABI AD ADL ADR ADTM ADVOL AMV ARBR ARMS ASI ATR ABI 绝对幅度指标 算法&#xff1a;上涨家数减去下跌家数所得的差的绝对值。 该指标只适用于大盘日线。 行号 1 aa…

题目7飞机票订票系统

题目7飞机票订票系统问题描述:某公司每天有10航班(航班号、价格)&#xff0c;每个航班的飞机&#xff0c;共有80个座位&#xff0c; 20排&#xff0c;每排4个位子。编号为A&#xff0c;BCD。如座位号:10D表示10排D座。 运行界面如下&#xff1a; 1)能从键盘录入订票信息:乘客的…

[Games 101] Lecture 13-16 Ray Tracing

Ray Tracing Why Ray Tracing 光栅化不能得到很好的全局光照效果 软阴影光线弹射超过一次&#xff08;间接光照&#xff09; 光栅化是一个快速的近似&#xff0c;但是质量较低 光线追踪是准确的&#xff0c;但是较慢 Rasterization: real-time, ray tracing: offline生成一帧…

狗屎一样的面试官,你遇到过几个?

做了几年软件开发&#xff0c;我们都或多或少面试过别人&#xff0c;或者被别人面试过。大家最常吐槽的就是面试造火箭&#xff0c;进厂拧螺丝。今天就来吐槽一下那些奇葩&#xff08;gou&#xff09;一样的面试官 A 那是在我刚工作1年的时候&#xff0c;出去面试前端开发。 那…

分布式开源存储架构Ceph概述

概述 k8s的后端存储中ceph应用较为广泛&#xff0c;当前的存储市场仍然是由一些行业巨头垄断&#xff0c;但在开源市场还是有一些不错的分布式存储&#xff0c;其中包括了Ceph、Swift、sheepdog、glusterfs等 什么是ceph&#xff1f; Ceph需要具有可靠性&#xff08;reliab…

C++11标准模板(STL)- 算法(std::partition_point)

定义于头文件 <algorithm> 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 定位已划分范围的划分点 …

线上崩了?一招教你快速定位问题。

&#x1f44f; 背景 正浏览着下班后去哪家店撸串&#xff0c;结果隔壁组同事囧着脸过来问我&#xff1a;大哥&#xff0c;赶紧过去帮忙看个问题&#xff01;客户反馈很多次了&#xff0c;一直找不出问题出在哪里&#xff01;&#xff01;&#xff01; 我&#xff1a;能不能有…

利用WPS功能破解及本地恢复密码

利用WPS功能破解及本地恢复密码 认识WPS功能 ​ WPS&#xff08;Wi-Fi Protected Setup&#xff09;是Wi-Fi保护设置的英文缩写。WPS是由Wi-Fi联盟组织实施的认证项目&#xff0c;主要致力于简化无线局域网安装及安全性能的配置工作。WPS并不是一项新增的安全性能&#xff0c;它…

数据结构之链表(单链表)

文章目录前言一、链表二、链表的八种结构1.单向或者双向2.带头或者不带头&#xff08;头&#xff1a;哨兵位&#xff09;3.循环或者不循环三、单链表1.接口2.接口的实现1.开辟一个新的节点1.打印单链表2.头插3.尾插4.头删5.尾删6.单链表的查找7.在pos位置之前插入数据8.在pos位…

MySQL8.0概述及新特性

文章目录学习资料常见的数据库管理系统排名&#xff08;DBMS&#xff09;SQL的分类DDL&#xff1a;数据定义语言DML&#xff1a;数据操作语言DCL&#xff1a;数据控制语言MySQL8.0新特性性能优化默认字符集DDL的原子化计算列宽度属性窗口函数公用表表达式索引新特性支持降序索引…

面试了20+前端大厂,整理出的面试题

事件是什么&#xff1f;事件模型&#xff1f; 事件是用户操作网页时发生的交互动作&#xff0c;比如 click/move&#xff0c; 事件除了用户触发的动作外&#xff0c;还可以是文档加载&#xff0c;窗口滚动和大小调整。事件被封装成一个 event 对象&#xff0c;包含了该事件发生…

RabbitMQ Windows 安装、配置、使用 - 小白教程

1、配套文件 下载erlang&#xff1a;http://www.erlang.org/downloads/ 下载RabbitMQ&#xff1a;http://www.rabbitmq.com/download.html 2、RabbitMQ服务端代码是使用并发式语言Erlang编写的&#xff0c;安装Rabbit MQ的前提是安装Erlang&#xff0c;双击otp_win64_21.1.ex…

计算机毕业设计springboot+vue+elementUI汽车车辆充电桩管理系统

项目介绍 随着我国汽车行业的不断发展&#xff0c;电动汽车已经开始逐步的领导整个汽车行业&#xff0c;越来越多的人在追求环保和经济实惠的同时开始使用电动汽车&#xff0c;电动汽车和燃油汽车最大的而不同就是 需要充电&#xff0c;同时我国的基础充电桩也开始遍及了大多数…

Java 异常处理

目录 一、异常的基本概念 二 、为何需要异常处理 三 、异常的处理 四 、异常类的继承架构 五 、抛出异常 5.1、程序中抛出异常 5.2、指定方法抛出异常 六 、自定义异常 不管使用的那种语言进行程序设计&#xff0c;都会产生各种各样的错误。 Java 提供有强大的异常处理…

商业银行普惠金融可持续发展综合能力呈现梯队化,专项领域各有所长

易观分析&#xff1a;普惠金融有别于传统的金融体系&#xff0c;强调构建包容性、公平性的金融服务生态&#xff0c;商业银行提升可持续发展的综合能力需关注五个方面的因素&#xff1a;获客能力上以普惠客群的金融需求为锚点&#xff0c;增强银行服务生态的多样性&#xff0c;…

罗正雄:基于展开交替优化的盲超分算法DAN

SFFAI 90—超分辨率专题《罗正雄&#xff1a;基于展开交替优化的盲超分算法》 退化表达式为&#xff1a; 盲超分就是已知y&#xff0c;求x 这个求解过程可以表示为如下最优化问题&#xff1a;求出使得以下表达式最小的k和x值 盲超分存在的挑战 病态&#xff1a;退化过程会损…

Leetcode 891. 子序列宽度之和

一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。给你一个整数数组 nums &#xff0c;返回 nums 的所有非空 子序列 的 宽度之和 。由于答案可能非常大&#xff0c;请返回对 109 7 取余 后的结果。子序列 定义为从一个数组里删除一些&#xff08;或者不删除&#xf…

基于matlab目标雷达横截面建模(附源码)

目录 一、介绍 二、简单点目标 RCS 三、复杂目标RCS 四、四个散射体组成的目标进行建模 五、具有多个散射体的扩展目标的宽带RCS 六、波动目标RCS 七、偏振目标RCS 八、结论 九、程序 此示例演示如何以不断提高的保真度对雷达目标进行建模。该示例介绍了简单点目标的雷…

MYSQL索引详解和优化

索引的定义 我们在看书的时候&#xff0c;都知道有目录&#xff0c;我们可以通过目录快速的找到书中的内容&#xff0c;而书中的目录就是充当书的索引。在数据库中的索引也是一样的。 索引的定义&#xff1a; 索引是帮助存储引擎快速获取数据的一种数据结构&#xff0c;即数据…