6.4 寻址双雄:PRP 和 SGL
1. 主机往 SSD 写入用户数据
2. 主机读取 SSD 上的用户数据
在上面两个过程中,主机在与 SSD 的数据传输过程中,主机是被动的一方,SSD 是主动的一方。即,主机需要数据(读数据),是 SSD 主动把数据写入主机的内存中;主机写数据,是 SSD 主动去主机的内存中取数据,然后写入内存。
那么,SSD 是如何知道在哪里取数据的呢????其实,主机有两种方式来告诉 SSD 数据所在的内存位置。一种是 PRP(Physical Region Page,物理区域页);一种是 SGL(Scatter / Gather List,分散 / 聚集列表)。
3. PRP
NVMe 把主机端的内存划分为一个一个物理页(Page),页的大小可以是 4KB、8KB、16KB、……、128MB。
4. SGL
SGL(Scatter Gather List),是个链表,由一个或者多个 SGL段(Segment)组成,而每个SGL段又由一个或多个SGL描述符(Descriptor)组成。
SGL描述符是SGL最基本的单元,描述了一段连续的物理内存空间:起始地址 + 空间大小。
每个SGL描述符大小是16字节。
6.5 Trace 分析
Trace:追踪。
下图中,PCIe 和 NVMe 一起构成了一个完整的主机与 SSD 通信的协议。
NVMe层中,有 64 字节的命令、16 字节的命令返回状态以及跟命令相关的数据;
PCIe事务层中,有事务层数据包TLP。
为实现不同的目的,事务层中的 TLP 可以分为以下几种类型:
(1)Configuration Read / Write;
(2)I / O Read / Write;
(3)Memory Read / Write;
(4)Message;
(5)Completion。
注意:此处的 Completion 和 NVMe 层的 Completion 不是同一个东西,它们处于不同的层。PCIe 层的 Completion TLP,是对所有Non-Posted 型 TLP 的响应;NVMe 层的 Completion,是对每个 SQ 中的命令的响应。
在 NVMe 命令处理过程中,PCIe 事务层基本只用 Memory Read / Write TLP 来为 NVMe 服务,不会用到其他类型的 TLP。
1. 下面以主机发送一个 Read 命令为例,学习 PCIe 是如何服务的??完整的 Trace 如下:
(1)第一步,主机准备了一个 Read 命令给 SSD。主机把该命令准备好之后,会放到 SQ 中;
(2)第二步,主机通过写 SQ 的 Tail DB,通知 SSD 来取命令。PCIe 是通过一个 Memory Write TLP 来实现主机写 SQ 的 Tail DB 的。
一个主机,下面可能连接着若干个 Endpoint(EP),该 SSD 只是其中一个 EP 而已,那么主机是怎么准确更新该 SSD 控制器中的 Tail DB 寄存器的呢?怎么寻址?
(3)第三步,SSD 收到通知,去主机端的 SQ 中取指。SSD 通过向主机端发送一个 Memory Read TLP 到主机的 SQ 中取指,主机通过 Completion 的方式把命令数据返回给 SSD;
(4)第四步,SSD 执行主机发送的 Read 命令,把数据从闪存中读到缓存中,然后把数据传给主机;
数据从闪存到缓存中,是 SSD 内部的操作,与 PCIe 和 NVMe 没有关系。
(5)第五步,SSD 一旦把数据返回给主机,就会认为命令处理完毕。之后,SSD 会往主机的 CQ 中返回状态。
SSD 通过 Memory Write TLP 把完成状态信息写入到主机的 CQ 中。
(6)第六步,SSD 采用中断的方式告诉主机命令执行完毕,让主机去处理 CQ;
(7)第七步,主机收到中断后,主机处理相应的 CQ。
这是主机端内部发生的事情,在 Trace 上捕捉不到这个过程。
(8)第八步,主机处理完相应的 CQ,通过 Memory Write TLP 更新 SSD 端的 CQ 的 Head DB。
6.6 端到端数据保护,即 NVMe 的数据保护机制
端到端:一端是主机的内存空间,一端是 SSD 的闪存空间。
即,NVMe 中端到端的数据保护功能。
需要保护的是用户数据。
主机和 SSD 之间,数据传输的最小单元是逻辑块(Logical Block,LB)。
数据从主机到闪存,首先要经过 PCIe 传输到 SSD 的控制器,然后控制器把数据写入闪存;
主机想从闪存上读数据,首先要由 SSD 控制器从闪存上获取数据,然后经过 PCIe 把数据传送给主机。
主机与 SSD 之间传输数据时,由于信道噪声的存在,可能会使数据出错。因此,为了保持数据的一致性,NVMe 提供了一个端到端的数据保护功能。
1. 元数据Meta Data
除了逻辑数据块本身,NVMe 还允许逻辑数据块携带元数据,元数据可以起保护数据的作用。
元数据有两种存在方式:
(1)作为逻辑块的扩展,和逻辑块一起传输。
(2)逻辑块与元数据分别传输。
2. 元数据是如何保护逻辑数据块的???
通过在逻辑数据块上携带下面的保护信息(Protection Information,PI)来保护逻辑数据块。
其中,
1)主机向 SSD 写入数据,不带保护信息的情况
2)主机向 SSD 写入信息,全程带保护信息的情况
3)主机向 SSD 写入信息,半程带保护信息的情况
6.7 Namespace
Namespace,简称 NS。
NS 由主机创建和管理,每个 NS 是独立的,逻辑块大小可以不同,端到端的数据保护配置也可以不同。
对一个 NVMe 子系统来说,除了包含若干个 NS,还可以有若干个 SSD 控制器。注意,不是说一个 SSD 控制器有多个 CPU,而是说一个 SSD 有好几个实现了 NVMe 功能的控制器。如,下图中的 NVMe 子系统包含了两个控制器,分别实现不同的功能(或相同的功能)。
一个 NVMe 子系统,除了可以有若干个 NS 和若干个控制器,还可以有若干个 PCIe接口。