NVMe 协议

NVMe 协议NVME 设备

大家好,欢迎来到IT知识分享网。

NVMe是一个针对基于PCIe的固态硬盘的高性能的、可扩展的主机控制器接口。

NVMe的显著特征是提供多个队列来处理I/O命令。单个NVMe设备支持多达64K个I/O 队列,每个I/O队列可以管理多达64K个命令。

当主机发出一个I/O命令的时候,主机系统将命令放置到提交队列(SQ),然后使用门铃寄存器(DB)通知NVMe设备。

 当NVMe设备处理完I/O命令之后,设备将处理结果写入到完成队列(CQ),并引发一个中断通知主机系统。

NVMe使用MSI/MSI-X和中断聚合来提高中断处理的性能。

NVMe驱动是一个C函数库,可直接链接到应用程序从而在应用与NVMe固态硬盘之间提供直接的、零拷贝的数据传输。这是完全被动的,意味着不会开启线程,只是执行来自应用程序本身的函数调用。这套库函数直接控制NVMe设备,通过将PCI BAR寄存器直接映射到本地进程中然后执行基于内存映射的I/O(MMIO)。I/O是通过队列对(QP)进行异步提交,其一般的执行流程跟Linux的libaio相比起来,并非完全不同。

NVMe 协议

NVMe协议

NVMe概述

               NVMe是一个针对基于PCIe的固态硬盘的高性能的、可扩展的主机控制器接口。

               NVMe的显著特征是提供多个队列来处理I/O命令。单个NVMe设备支持多达64K个I/O 队列,每个I/O队列可以管理多达64K个命令。

               当主机发出一个I/O命令的时候,主机系统将命令放置到提交队列(SQ),然后使用门铃寄存器(DB)通知NVMe设备。

               当NVMe设备处理完I/O命令之后,设备将处理结果写入到完成队列(CQ),并引发一个中断通知主机系统。

               NVMe使用MSI/MSI-X和中断聚合来提高中断处理的性能。

 

NVMe驱动概述

NVMe驱动是一个C函数库,可直接链接到应用程序从而在应用与NVMe固态硬盘之间提供直接的、零拷贝的数据传输。这是完全被动的,意味着不会开启线程,只是执行来自应用程序本身的函数调用。这套库函数直接控制NVMe设备,通过将PCI BAR寄存器直接映射到本地进程中然后执行基于内存映射的I/O(MMIO)。I/O是通过队列对(QP)进行异步提交,其一般的执行流程跟Linux的libaio相比起来,并非完全不同。

 NVM Express(NVMe)是一个寄存器级接口,允许带内主机软件与NVM子系统通信。NVMe管理界面(NVMe-MI)允许管理控制器通过一个或多个外部接口与NVMe NVM子系统进行带外通信。

NVMe是一种Host与SSD之间通讯的协议

图1:NVMe管理接口协议分层

 NVMe 协议

NVMe有三宝:Submission Queue (SQ),Completion Queue(CQ)和Doorbell Register (DB)。 SQ和CQ位于Host的内存中,DB则位于SSD的控制器内部。

NVMe 协议

DB又是干什么用的呢?Host发送命令时,不是直接往SSD中发送命令的,而是把命令准备好放在自己的内存中,那怎么通知SSD来获取命令执行呢?Host就是通过写SSD端的DB寄存器来告知SSD的。

NVM Express基于配对的提交和完成队列机制

  •  命令由主机软件放入提交队列。完成被放入控制器关联的完成队列。多个提交队列可以使用相同的完成队列。提交和完成队列在内存中分配。    
  •  存在管理员提交和关联的完成队列以用于控制器管理和控制(例如,创建和删除I / O提交和完成队列,中止命令,等等)。只有属于管理员命令集的命令才可以提交给管理员提交队列。  
  •  I / O命令集与I / O队列对一起使用。该规范定义了一个I / O命令集,命名为NVM命令集。主机选择一个用于所有I / O队列的I / O命令集对。  
主机软件创建队列,最高可达控制器支持的最大值。通常的数量创建的命令队列基于系统配置和预期的工作负载。例如, 在基于四核处理器的系统上,每个核心可能有一个队列对,以避免锁定和确保数据结构在适当的处理器核心缓存中创建。

NVME命令

命令执行: 1. Host写命令到SQ 2. Host更新SQ的TailDB, 通知SSD取命令 3. SSD收到命令,于是从SQ中取出命令 4. SSD执行命令 5. 命令执行完成后,SSD往CQ中写入命令执行结果,同时修改CQ的TailDB 6. SSD发短信通知Host命令已经执行完成 7. Host收到命令后,到CQ中查看命令完成状态 8. Host处理完CQ中的命令执行结果,更新CQ中的HeadDB, 回复SSD, "命令执行结果已经处理完毕"

NVMe有两种命令,制定了Host与SSD之间通讯的命令,以及命令如何执行的。 一种叫Admin Command,用以Host管理和控制SSD; 一种就是I/O Command,用以Host和SSD之间数据的传输。

NVMe 协议

NVMe 协议

NVMe 协议

Admin 指令

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

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

操作码 指令 作用
00h 删除I/O SQ, 释放SQ空间
01h 创建 I/O SQ, 保存host分配给SQ的地址、队列优先权、队列大小
02h 获取日志, 返回所选日志页于缓冲区
04h 删除 I/O CQ, 释放CQ空间
05h 创建 I/O CQ, 保存host分配给CQ的地址、中断向量、队列大小等
06h Identify 返回关于controller与namespace能力和状态的数据结构(2k字节)
08h 撤销, 用来撤销之前完成的指令,best-effort
09h 设置features 根据FID设置相应的features
0Ah 获取 features, 根据FID返回队列数量、仲裁信息等
0Ch 异步事件请求, Controller向host报告运行信息(error or health)
10h 固件激活, 验证下载的镜像,提交到Firmware Slot(1-7)中
11h 固件镜像下载, 下载固件镜像

NVM指令

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

操作码 指令 作用
00h Flush 将数据(和元数据)提交到NVM中,所有命令都要执行
01h Write 将数据(和元数据)写入NVM中
02h Read 读NVM中的数据(和元数据)
04h Wirte Uncorrectable 标记无效数据块
05h Compare 比较从NVM端读出的数据和比较数据缓冲区的数据
09h Dataset Management 标识一定范围数据的特点,eg,频繁读、频繁写(提升性能)

寄存器

寄存器定义

NVMe寄存器主要分为两部分,一部分定义了Controller整体属性,一部分用来存放每组队列的头尾DB寄存器。

  1. CAP——控制器能力,定义了内存页大小的最大最小值、支持的I/O指令集、DB寄存器步长、等待时间界限、仲裁机制、队列是否物理上连续、队列大小;
  2. VS——版本号,定义了控制器实现NVMe协议的版本号;
  3. INTMS——中断掩码,每个bit对应一个中断向量,使用MSI-X中断时,此寄存器无效;
  4. INTMC——中断有效,每个bit对应一个中断向量,使用MSI-X中断时,此寄存器无效;
  5. CC——控制器配置,定义了I/O SQ和CQ队列元素大小、关机状态提醒、仲裁机制、内存页大小、支持的I/O指令集、使能;
  6. CSTS——控制器状态,包括关机状态、控制器致命错误、就绪状态;
  7. AQA——Admin 队列属性,包括SQ大小和CQ大小;
  8. ASQ——Admin SQ基地址;
  9. ACQ——Admin CQ基地址;
  10. 1000h之后的寄存器定义了队列的头、尾DB寄存器。

寄存器理解

  1. CAP寄存器标识的是Controller具有多少能力,而CC寄存器则是指当前Controller选择了哪些能力,可以理解为CC是CAP的一个子集;如果重启(reset)的话,可以更换CC配置;
  2. CC.EN置一,表示Controller已经可以开始处理NVM命令,从1到0表示Controller重启;
  3. CC.EN与CSTS.RDY关系密切,CSTS.RDY总是在CC.EN之后由Controller改变,其他不符合执行顺序的操作都将产生未定义的行为;
  4. Admin队列有host直接创建,AQA、ASQ、ACQ三个寄存器标识了Admin队列,而其他I/O队列则有Admin命令创建(eg,创建I/O CQ命令);
  5. Admin队列的头、尾DB寄存器标识为0,其他I/O队列标识由host按照一定规则分配;只有16bit的有效位,是因为队列深度最大64K。

性能提升

如果要完全释放NVMe SSD的IOPS性能,设计人员要先做好评估呢,因为当队列深度达到一定程度后,NVMe SSD的IOPS才会达到最佳。如下图(来自Tom’Hardware),六块NVMe SSD均在队列深度128以上才达到最佳的性能。

NVMe 协议

NVMe白皮书中对企业级SSD和消费级SSD设计时需要的队列深度的建议是:

  • 企业级SSD: 16~128 Queues;
  • 消费级SSD: 2-8 Queues.

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/110373.html

(0)
上一篇 2026-02-01 07:45
下一篇 2026-02-01 08:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信