本文是个人学习NVMe的一个总结,借鉴网络资料https://cloud.tencent.com/developer/article/1458759和个人实践经历一共分四篇阐述NVMe。
可乐学习NVMe之二:三只熊SQ/CQ/DB
可乐学习NVMe之三:深入解读PRP/SGL
可乐学习NVMe之四:粗茶淡饭NameSpace

1. NVMe SSD 结构简图

整体来看,NVMe SSD可以分为三部分,host端的驱动NVMe Driver、PCIe+NVMe实现的控制器以及NAND Flash+DDR4/DDR5存储介质。
在这里插入图片描述

芯片回片后Host侧软件或者驱动开发主要在应用层,通过一些测试工具进行benchmark跑分测试,performance性能分析,latency分析、stress-testing等等:
在这里插入图片描述
那么,接下来阐述为什么SSD需要NVMe,并再后续的文章介绍NVMe协议分析,个人针对协议的理解,如果有不当之处,还请各位大侠们留言指出。

2. 为什么SSD需要NVMe ?

NVMe是一种Host与SSD之间通讯的协议,它在协议栈中隶属高层。
在这里插入图片描述
NVMe在协议栈中处于应用层或者命令层, NVMe的附属就是PCIe,它所制定的任何命令,都交由PCIe去完成。虽然NVMe的命令可能可以由别的接口协议完成,但NVMe与PCIe合作形成的战斗力无疑是最强的。

NVMe是为SSD所生的。NVMe出现之前,SSD绝大多数走的是AHCI和SATA的协议,后者其实是为传统HDD服务的。与HDD相比,SSD具有更低的延时和更高的性能,AHCI已经不能跟上SSD性能发展的步伐了,已经成为制约SSD性能的瓶颈。所有SATA接口的SSD,你去看性能参数,会发现都不会超过600MB/s。如果碰到有人跟你说它的SATA SSD读取性能可以超过600MB/s,直接拨打110报警。不是底层Flash带宽不够,是SATA接口速度限制了,因为SATA现在最高带宽就是600MB/s。那么既然SATA接口速度太慢,我用PCIe好了,不过上层协议还是AHCI。但是AHCI只有一个命令队列,最多同时只能发32条命令,HDD时代(群雄逐鹿)还能混混,SSD时代(三足鼎立)就只有被灭的份。所以同样,SSD需要PCIe,更需要NVMe。

3. NVMe 命令分类

NVMe主要常用的有两种命令。一种Admin Command,用以Host管理和控制SSD; 另外一种是IO Command 即为NVM Command,用以Host和SSD之间的数据传输。NVM层次关系如下,最小的操作单元为LB。
在这里插入图片描述

下面是NVMe1.3的指令集。

  1. NVMe支持的Admin Command:

在这里插入图片描述
在这里插入图片描述

NVM Command Set Specific:
在这里插入图片描述

2. NVMe支持的I/O Command:
在这里插入图片描述
上述命令集了解一下就好,真正干活的时候再查表效果更佳。

有了上述命令,那么Host是如何把这些个命令发送给SSD执行的呢?

NVMe有三个宝贝。大宝是Submission Queque(SQ)、二宝是Completion Queque(CQ)、三宝是Doorbell Register (DB), 其中SQ和CQ位于host的内存中,DB位于SSD的控制器内部。如图:
在这里插入图片描述

这张图信息量比较大,除了让我们知道SQ和CQ在Host的memory中以及DB在SSD端外,而且让我们对一个PCIe系统有一个具体的认识。上图中的NVMe Subsystem一般就是SSD。请看这张图几秒钟,然后闭上眼,脑补SSD所处的位置:SSD作为一个PCIe Endpoint通过PCIe连着Root Complex (RC), 然后RC连接着CPU和内存。RC是什么?我们可以认为RC就是CPU的代言人,作为系统中最高层,SQ位于Host内存中,Host要发送命令时,先把准备好的命令放在SQ中,然后通知SSD来取;CQ也是位于Host内存中,一个命令执行完成,成功或失败,SSD总会往CQ中写入命令完成状态。DB又是干什么用的呢?Host发送命令时,不是直接往SSD中发送命令的,而是把命令准备好放在自己的内存中,那怎么通知SSD来获取命令执行呢?Host就是通过写SSD端的三宝寄存器来告知SSD的。

OK,具体的我们来看看NVMe是如何处理命令的,看图说话:

在这里插入图片描述

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

  2. Host写SQ对应的DB寄存器,通知SSD取指;

  3. SSD收到通知,于是从SQ中取指(通过HDB或者TDB可以判断是否有未完成命令);

  4. SSD执行指令;

  5. 指令执行完成,SSD往CQ中写指令执行结果(结果可能是失败,也可能是成功);

  6. 然后SSD根据实现的中断方式发短信通知Host指令完成;

  7. host响应中断收到短信,Host处理CQ,查看指令完成状态;

  8. Host处理完CQ中的指令执行结果,通过DB回复SSD:指令执行结果已处理,辛苦您了!

后续关于这个话题,采用连载的方式推出,后续还有可乐学习NVMe之二,之三…

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐