浅析NVMe协议:PRP/SGL数据传输格式 文章目录概述PRPPRP EntryPRP ListSGLSGL描述符SGL描述符类型SGL Data Block描述符SGL BitBucket描述符SGL Segment描述符SGL Last Segment描述符Keyed SGL Data Block描述符Transport SGL Data Block描述符SGL Segment相关参考概述NVMe支持PRPPhysical Region Page和SGLScatter-Gather List两种方式描述数据的位置和长度等信息其中PRP是以主机物理页面为基本单位来描述数据的位置信息存放在PRP里的地址需要满足主机物理页面对齐配合页面偏移描述数据的实际地址SGL适合描述多个分散的数据区域相对于PRPSGL在使用上要相对灵活一些地址对齐粒度通常可以是Byte或Dword。PRPNVMe协议使用PRP描述数据的示意如下PRP EntryPRP Entry是PRP格式的基本描述单元指向主机中的一个物理内存页面。NVMe协议定义的PRP Entry格式如下PRP Entry包含Page Base Address和OffsetPage Base Address物理内存页面的地址Offset数据在物理内存页面中的偏移需要满足Dword对齐通常只有命令中的第一个PRP Entry需要使用Offset来指示数据偏移。上面的n取决于物理内存页面的大小典型场景是4KB那么n的值就是11主机驱动可以通过CC.MPS字段配置物理内存页面大小到NVMe控制器。PRP ListPRP List是一系列PRP Entry的数组用于描述使用多个物理页面的数据协议定义如下SGLNVMe命令使用SGL描述数据示意如下SGL描述符通用SGL描述符的格式定义如下SGL描述符是一个16Byte的表项其中最高位的Byte描述了SGL的类型信息包括SGL描述符类型和SGL描述符子类型。协议支持的SGL描述符类型如下对于SGL描述符子类型主要用于对不同类型SGL描述符的Address字段进一步做解释。协议主要使用的SGL描述符子类型主要是0和1其它值取决于传输层特殊定义或保留对于0和1子类型的含义说明如下0指示Address字段包含了64位的内存地址1指示Address字段包含了从特定位置的偏移通常是用于NoF Capsule同时携带了SQE和数据的场景下描述数据在Capsule中的偏移位置。SGL描述符类型SGL Data Block描述符SGL Data Block描述符记录数据在主机中的位置信息包含数据起始地址和长度是SGL中描述数据的基本单元。SGL Data Block描述符记录的地址和长度需要满足NVMe Controller对于地址对齐粒度的要求通常可以是Byte或DWord最终取决于NVMe Controller Identify里的配置。SGL BitBucket描述符SGL BitBucket描述符只携带了长度信息自身不指向数据通常用于读写命令中指示NVMe Controller跳过对应长度的数据不处理。SGL Segment描述符SGL Segment描述符记录的是SGL Segment在内存中的地址和长度。SGL Last Segment描述符SGL Last Segment描述符用于记录SGL List中最后一级SGL Segment的位置信息。Keyed SGL Data Block描述符Keyed SGL Data Block描述符相较于常规的SGL Data Block描述符额外携带了Key的信息主要用于RDMA场景访问内存时作权限校验。Transport SGL Data Block描述符Transport SGL Data Block描述符提供了特定于NVMe传输层的数据描述方式描述符本身只描述数据的长度至于数据的位置以及传输方式则由对应的传输层进行处理。SGL SegmentSGL Segment是SGL描述符的数组用于描述单一SGL描述符无法描述的多个数据区域。相关参考《NVM Express Base SpecificationRevision 2.3》