声明

主页: 元存储的博客_CSDN博客

https://blog.csdn.net/vagrant0407?type=blog
本文依据公开知识及个人经验整理而成,如有错误请留言。
文章为个人辛苦整理,付费内容,禁止私自转载。


内容摘要

PRP 介绍

PRP List格式

SGL 介绍

SGL Descriptor 分类


前言

有个人一直在思考三个问题:我是谁?我从哪里来?我要去哪里?

你猜这个人最后怎么着?

成了哲学家?

疯了?

疯了的哲学家?

我觉得无外乎这三种结果了。

相比人的世界,这三个问题在NVMe的世界就很容易得到答案了,至少不会把人逼疯。

我是数据,我从Host来,要到SSD去,或者,我从SSD来,要去到Host。

Host如果想往SSD上写入用户数据,需要告诉SSD写入什么数据,写入多少数据,以及数据源在内存中的什么位置,这些信息包含在Host向SSD发送的Write命令中。每笔用户数据对应着一个叫做LBA(Logical Block Address)的东西,Write命令通过指定LBA来告诉SSD写入的是什么数据。对NVMe/PCIe来说,SSD收到Write命令后,通过PCIe去Host的内存数据所在位置读取数据,然后把这些数据写入到闪存中,同时得到LBA与闪存位置的映射关系。

Host如果想读取SSD上的用户数据,同样需要告诉SSD需要什么数据,需要多少数据,以及数据最后需要放到Host内存的哪个位置上去,这些信息包含在Host向SSD发送的Read命令中。SSD根据LBA,查找映射表,找到对应闪存物理位置,然后读取闪存获得数据。数据从闪存读上来以后,对NVMe/PCIe来说,SSD会通过PCIe把数据写入到Host指定的内存中。这样就完成了Host对SSD的读访问。

在上面的描述中,大家有没有注意到一个问题,那就是Host在与SSD的数据传输过程中,Host是被动的一方,SSD是主动的一方。你Host需要数据,是我SSD主动把数据写入到你的内存中;你Host写数据,同样是我SSD主动去你Host的内存中取数据,然后写入到闪存。SSD跟快递小哥一样辛劳,不仅送货上门,还上门取件。之前蛋蛋还为Host不能读取DB打抱不平,现在看来,Host不值得同情,太懒了。

无论送货上门,还是上门取件,你都需要告诉快递小哥你的地址,不然茫茫人海,快递小哥怎么就能找到你呢?同样的,Host你不亲自传输数据,那总该告诉我SSD去你内存中什么地方取用户数据,或者要把数据写入到你内存中的什么位置。你在告诉快递小哥送货地址或者取件地址时,会说XX路XX号XX弄XX楼XX室,也可能会说XX小区XX楼XX室,anyway,快递小哥能找到就行。Host也有两种方式来告诉SSD数据所在内存位置,一是PRP (Physical Region Page, 不是P2P!),二是SGL (Scatter/Gather List)。不过,后者感觉不怎么友善,因为怎么听起来都像”死过来”(SGL)。当然了,也可能是我误会了,人家只是在说”送过来”。

先说PRP。

NVMe把Host的内存划分为一个一个页(Page),页的大小可以是4KB,8KB,16KB… 128MB。

PRP是什么,长什么样呢?

PRP Entry本质就是一个64位内存物理地址,只不过把这个物理地址分成两部分:页起始地址和页内偏移。最后两bit是0,说明PRP表示的物理地址只能四字节对齐访问。页内偏移可以是0,也可以是个非零的值。

PRP Entry描述的是一段连续的物理内存的起始地址。如果需要描述若干个不连续的物理内存呢?那就需要若干个PRP Entry。把若干个PRP Entry链接起来,就成了PRP List。

是的,正如你所见,PRP List中的每个PRP Entry的偏移量都必须是0,PRP List中的每个PRP Entry都是描述一个物理页。它们不允许有相同的物理页,不然SSD往同一个物理页写入几次的数据,导致先写入的数据被覆盖。

每个NVMe命令中有两个域:PRP1和PRP2,Host就是通过这两个域告诉SSD数据在内存中的位置或者数据需要写入的地址。

PRP1和PRP2有可能指向数据所在位置,也可能指向PRP List。类似C语言中的指针概念,PRP1和PRP2可能是指针,也可能是指针的指针,还有可能是指针的指针的指针。别管你包的有多严实,根据不同的命令,SSD总能一层一层的剥下包装,找到数据在内存的真正物理地址。SSD善解人衣。

假如一个PRP List 不够用, 则将 PRP list 的最后一个 entry 设为下一个 PRP list 的 address.

下面是一个PRP1指向PRP List的示例:

PRP1指向一个PRP List,PRP List位于Page 200,页内偏移50的位置。SSD确定PRP1是个指向PRP List的指针后,就会去Host内存中(Page 200,Offset 50)把PRP List取过来。获得PRP List后,就获得数据的真正物理地址,SSD然后就会往这些物理地址读入或者写入数据。

对Admin命令来说,它只用PRP告诉SSD内存物理地址;对I/O 命令来说,除了用PRP,Host还可以用SGL的方式来告诉SSD数据在内存中写入或者读取的物理地址。

Host在命令中会告诉SSD采用何种方式。具体来说,如果命令当中DW0[15:14]是0,就是PRP的方式,否则就是SGL的方式。

SGL是什么?SGL是一个数据结构,用以描述一段数据空间,这个空间可以是数据源所在的空间,也可以是数据目标空间。SGL(Scatter Gather List)首先是个List,是个链表,由一个或者多个SGL Segment组成,而每个SGL Segment又由一个或者多个SGL Descriptor组成。SGL Descriptor是SGL最基本的单元,它描述了一段连续的物理内存空间:起始地址+空间大小。

每个SGL Descriptor大小是16字节。一块内存空间,可以用来放用户数据,也可以用来放SGL Segment,根据这段空间的不同用途,SGL Descriptor也分几种类型。

有4种SGL Descriptor,一种是Data Block,这个好理解,就是描述的这段空间是用户数据空间;一种是Segment描述符。SGL不是由SGL Segment组成的链表吗?既然是链表,前面一个Segment就需要有个指针指向下一个Segment,这个指针就是SGL Segment描述符,它描述的是它下个Segment所在的空间。特别地,对链表当中倒数第二个Segment,它的SGL Segment描述符我们把它叫做SGL Last Segment描述符。它本质还是SGL Segment描述符,描述的还是SGL Segment所在的空间。为什么需要把倒数第二个SGL Segment描述符单独的定义成一种类型呢?我认为是让SSD在解析SGL的时候,碰到SGL Last Segment描述符,就知道链表快到头了,后面只有一个Segement了。那么,SGL Bit Bucket是什么鬼?它只对Host读有用,用以告诉SSD,你往这个内存写入的东西我是不要的。好吧,你既然不要,我也就不传了。

说了这么多,可能有点晕,结合下张图,可能会更明白点。

如果还是晕,看个例子吧。

这个例子中,假设Host需要往SSD中读取13KB的数据,其中真正只需要11KB数据,这11KB的数据需要放到3个大小不同的内存中,分别是:3KB,4KB和4KB。

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

大家也许跟我有个同样的疑问(自作多情?),那就是,既然有PRP,为什么还需要SGL?事实上,NVMe1.0的时候的确只有PRP,SGL是NVMe1.1之后引入的。看看SGL和PRP有什么不同。

(1)SGL不仅提供了一个内存基地址,还提供了该段内存的大小信息(length),PRP只提供了一个基地址,内存大小需要SSD根据命令上下文去猜;

(2)SGL可描述任意的内存空间,相对PRP来说更灵活,后者基本按页访问内存;

(3)另外SGL提供了一个Bit Bucket的东西,一段连续的LBA空间,其中的一些数据我可以不需要传输,PRP好像做不到这点。

本文转载来自SSD技术学习网,本文地址:http://www.ssdfans.com/?p=1177

如有侵权,请联系删除。

[NVME协议8] 解读PRP/SGL相关推荐

  1. 可乐学习NVMe之三:解读PRP/SGL

    原文来自https://cloud.tencent.com/developer/article/1458759,前两个章节解释了总体框架和命令分析. NVMe学习之一:为什么SSD需要NVMe? NV ...

  2. NVME协议解读(三)

    NVMe协议详解(三) 4.内存数据结构 4.1 SQ与CQ的详细定义 4.1.1 空队列 4.1.2 满队列 4.1.3 队列性质 4.2 仲裁机制 4.2.1 RR 带有优先权的RR 4.2.3 ...

  3. NVME协议解读(四)

    NVMe详解(四) 5. NVMe协议定义的命令 5.0 命令执行过程 5.1 命令分类 5.2 命令通用格式 5.3Admin 指令 5.4 NVM指令 6 控制器结构 6.1 命令执行过程 6.2 ...

  4. NVMe协议详解(一)

    参考文档:NVME手册1.4a,下载网站. NVMe相关定义 queue pair 一对用来承载NVMe命令的队列对,由一个Submission Queue和一个Completion queue组成, ...

  5. 基于PCIe的NVMe协议在FPGA中实现方法

    NVMe协议是工作在PCIE的最上层协议层的,故需要先搞清楚PCIE.本文基于Xilinx的UltraScale+,开发工具为Vivado2021.2.学习中以spec为主,其它资料辅助参考(重点介绍 ...

  6. 收藏:NVMe协议基础原理介绍

    概述:NVM Express(NVMe),或称非易失性内存主机控制器接口规范(英语:Non Volatile Memory Host Controller Interface Specificatio ...

  7. NVMe协议详解(三)

    NVMe协议详解(三) 4.内存数据结构 4.1 SQ与CQ的详细定义 4.1.1 空队列 4.1.2 满队列 4.1.3 队列性质 4.2 仲裁机制 4.2.1 RR 带有优先权的RR 4.2.3 ...

  8. NVMe协议SSD控制器端实现浅析

    http://www.dostor.com/p/48121.html 一.NVMe 协议 NVMe协议是在PCIe SSD开始大量出现在市场上后,因为各个厂家的私有协议不具有兼容性,无法和现有操作系统 ...

  9. 群联固态硬盘修复工具_固态硬盘掉速修复小教程,SATA和NVMe协议通用

    不做云评测,只聊真体验,大家好,我是肉包爸爸. 近日,被我拿来做高速移动硬盘的一块海力士PC401 1T固态硬盘出现严重掉速,格式化后故障依旧. 由于硬盘盒接口为USB3.1 Gen2,所以理论速度被 ...

最新文章

  1. 【CV中的注意力机制】史上最强ResNet变体--ResNeSt
  2. 如何毕业后继续白嫖知网
  3. BAPI_GOODSMVT_CREATE 移动类型311 CODE = '04' 代码
  4. Arraylist线程不安全原因
  5. php传递参数给asp.net,asp.net 传值总结
  6. 【引用】IP地址已经分配给另一个适配器问题的解决方法
  7. Egret之粒子系统
  8. 集合Collection以及泛型
  9. php post 视频教程,PHP教程:POST数据的三种方法
  10. html中继承加载不出css,javascript - 动态加载 html 中 td标签 的css样式 不起作用
  11. android开发利用传感器实现微信的摇一摇功能(zz)
  12. C++:以空格分隔的字符串的输入输出
  13. ES6、7学习笔记(尚硅谷)-3-变量的解构赋值
  14. PHP限制字符串显示长度
  15. android miui连接开发者选项,(最详细)MIUI11系统的Usb调试模式在哪里开启的步骤
  16. 佩尔方程(超详细推导+例题讲解) 每日一遍,算法再见!
  17. JavaScript正则表达式账号密码验证练习
  18. 2017年10月WEB前端开发实习生面试题总结
  19. 通讯录号码不见了怎么办?手机联系人不见了怎么恢复?
  20. VR/AR是什么,有什么差别,5G与VR/AR到底有没有关系呢?

热门文章

  1. 李宇春 周笔畅 ... 2007娱乐猜想
  2. qsv如何转换AVI格式 如何将qsv转换成AVI
  3. 【解决方案】AI视频结构化智能安防平台EasyCVR实现检察院大楼智能安防监控方案
  4. UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels
  5. linux 数字转盘,HiFi科普之数字转盘篇#音乐发烧友的真爱
  6. 尘埃落定,纪念我的校招(附腾讯,京东,YY,唯品会的面试题+个人前端心得体会)...
  7. 云存储服务的可用性——从又拍网看云存储服务
  8. 缓存机制(一级缓存)
  9. 微型计算机H535内存,微型计算机技术-中国大学mooc-题库零氪
  10. Docker Note(2): 配置镜像加速器与常用指令