问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

NVMe 协议详解

创作时间:
作者:
@小白创作中心

NVMe 协议详解

引用
CSDN
1.
https://m.blog.csdn.net/chenzhjlf/article/details/138520384

NVMe(Non-Volatile Memory Express)是一种针对基于PCIe的固态硬盘的高性能、可扩展的主机控制器接口。它通过提供多个队列来处理I/O命令,单个NVMe设备支持多达64K个I/O队列,每个队列可以管理多达64K个命令。本文将详细介绍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有三宝:Submission Queue (SQ),Completion Queue(CQ)和Doorbell Register (DB)。 SQ和CQ位于Host的内存中,DB则位于SSD的控制器内部。

SQ和CQ在Host的memory中以及DB在SSD端,上图中的NVMe Subsystem一般就是SSD。

SQ位于Host内存中,Host要发送命令时,先把准备好的命令放在SQ中,然后通知SSD来取;CQ也是位于Host内存中,一个命令执行完成,成功或失败,SSD总会往CQ中写入命令完成状态。

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之间数据的传输。


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白皮书中对企业级SSD和消费级SSD设计时需要的队列深度的建议是:

  • 企业级SSD: 16~128 Queues;
  • 消费级SSD: 2-8 Queues.
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号