NVMExpress 4 Data Structure

4 数据结构

本节介绍 NVM Express 使用的数据结构。

4.1 提交队列和完成队列定义 

第4.1、4.1.1 和 4.1.2 节仅适用于基于 PCIe 的 NVMe 实现。有关 NVMe over Fabrics 实现,请参阅 NVMe over Fabrics 规范中的第 2.4 节以及该部分的子部分。

队列条目提交者使用当前的 Tail 条目指针来标识下一个打开的队列slot。提交者在将新条目放置到打开的队列slot后递增 Tail 条目指针。如果 Tail 条目指针增量超过队列大小时,则 Tail 应滚动为零。只要不满足“满队列”条件,提交者就可以继续将条目放入空闲队列slot中(请参阅第 4.1.2 节)。

注意:提交者应考虑队列环绕条件。

队列条目使用者使用当前 Head 条目指针来标识要使用的下一个条目的slot。使用者在使用队列中的下一个条目后递增 Head 条目指针。如果 Head 入口指针增量超过队列大小时,则 Head 入口指针应滚动为零。只要不满足空队列条件,使用者就可以继续使用队列中的条目(请参阅第 4.1.1 节)。

注意:消费者应考虑队列环绕条件。

创建和删除相关联的提交队列SQ和完成队列CQ需要由主机软件正确排序。主机软件应在创建任何关联的SQ之前创建CQ。在创建关联的CQ后,可以随时创建SQ。主机软件应先删除所有关联的SQ,然后再删除CQ。要中止提交到提交队列的所有命令,主机软件应为该队列发出删除 I/O 提交队列命令(请参阅第 7.4.3 节)。

主机软件编写 SQ Tail Doorbell (DB)(请参阅第 3.1.25 节)和CQ Head DB(请参阅第 3.1.26 节),以将相应入口指针的新值传达给控制器。如果主机软件向 SQ Tail DB或 CQ Head DB寄存器写入了无效值,并且异步事件请求命令未完成,则异步事件将发布到 Admin CQ,其状态代码为 Invalid Doorbell Write Value。应由主机软件删除并重新创建关联的队列。对于遇到此错误的提交队列,控制器可能会完成以前使用的命令;不使用其他命令。这种情况可能是由于主机软件尝试将条目添加到完整的提交队列中或从空的完成队列中删除条目引起的。

主机软件检查内存中的CQ条目阶段标记 (P) 位,以确定是否已发布新的CQ条目。CQ Tail 指针仅由控制器在内部使用,对主机不可见。控制器在CQ条目中使用 SQ Head Pointer (SQHD) 字段将 SQ Head Pointer 的新值传达给主机新的 SQHD 值表示CQ条目已被消耗,但不指示执行或完成任何命令。请参阅第 4.6 节。

当主机使用一个新值写入关联的 SQ Tail DB 时,表示SQ条目将提交到控制器,该值指示 SQ Tail 指针已移至或经过放置该 SQ条目的slot。SQ Tail DB写入可能表示已提交一个或多个 SQ条目

在发布 CQ条目时,控制器已使用了 SQ条目,该条目指示 SQ Head 指针已移过放置该 SQ 条目的插槽。CQ条目可能指示已使用一个或多个SQ条目。

当控制器将 CQ 条目写入下一个空闲 CQ slot时,CQ条目将发布到 CQ,从而将相位标记 (P) 位从内存中的先前值反转。控制器可能会向主机生成中断,以指示已发布一个或多个完成队列条目。

当主机使用一个新值写入关联的 CQ Head DB时,主机已使用CQ条目,该值指示 CQ Head 指针已移过放置该CQ条目的插槽。CQ Head DB写入可能表示已消耗一个或多个 CQ 条目。

一旦“提交队列”或“完成队列”条目被用完,放置该条目的插槽就可用并可供重复使用。在发布SQ条目之后但在使用该条目之前更改该条目将导致未定义的行为。在发布CQ条目之后、使用该条目之前更改该条目将导致未定义的行为。

如果CQ中没有空闲slot,则在slot可用之前,控制器不应将状态发布到该CQ。在这种情况下,控制器可能会停止处理与受影响的CQ关联的其他SQ条目,直到slot可用。控制器应继续处理其他队列

4.1.1 空队列

当 Head 入口指针等于 Tail 入口指针时,队列为空。图 103 定义了 Empty Queue 条件。

图 103:空队列定义

4.1.2 满队列

当 Head 等于比 Tail 多 1 时,队列为满。满队列中的条目数比队列大小少 1。图 104 定义了 Full Queue 条件。

注意:在确定队列是否为“已满”时,应考虑队列环绕条件。

图 104:满队列定义

4.1.3 队列大小

队列大小以 16 位 0 为基础的字段表示,该字段表示队列中的slot数量。队列的最小大小为两个slotI/O SQ或 I/O CQ的最大大小定义为 64 Ki slot,受 CAP .MQES 字段中报告的控制器支持的最大队列大小的限制。Admin SQ和Admin CQ的最大大小定义为 4 Ki slot。由于 Head 和 Tail 入口指针定义,每个队列中的一个插槽不可用

4.1.4 队列标识符

每个队列都通过一个 16 位 ID 值来标识,该值在创建队列时分配给队列。

4.1.5 队列优先级

如果支持具有紧急优先级类仲裁机制的加权轮询,则主机软件可以分配队列优先级服务类:紧急、高、中或低。如果不支持具有紧急优先级类仲裁机制的加权轮询,则不会使用优先级设置,并且控制器会忽略该设置。

4.2 提交队列条目 – 命令格式

每个命令的大小为 64 个字节

命令 Dword 0、Namespace标识符、元数据指针、PRP 条目 1、PRP 条目 2、SGL 条目 1 和元数据 SGL 段指针对所有管理员命令和 NVM 命令都有通用定义。元数据指针、PRP 条目 1、PRP 条目 2 和元数据 SGL 段指针并非由所有命令使用。命令 Dword 0 在图 105 中定义。

图 105:命令 Dword 0

31:16bit:命令标识符 (CID)与SQ标识符结合使用时此字段表示命令的唯一标识符。不应使用 FFFFh 的值,因为错误信息日志页面(请参阅第 5.14.1.1 节)使用此值来指示错误未与特定命令关联。

15:14bit:基于 PRP 或 SGL的数据传输 (PSDT) :此字段指定是使用 PRP 还是 SGL 进行与命令关联的任何数据传输。PRP 应用于 NVMe over PCIe 实施的所有管理员命令。SGL 应用于 NVMe over Fabrics 实现的所有 Admin 和 I/O 命令(此字段设置为 01b)。下表描述了该定义。00b:基于PRP传输;01b:基于SGL传输。如果使用,元数据指针 (MPTR) 将包含字节对齐的单个连续物理缓冲区的地址。10b:基于SGL传输。如果使用,元数据指针 (MPTR) 包含 SGL 段的地址,该段正好包含一个 qword 对齐的 SGL 描述符。  如果存在未与逻辑块数据交错的元数据(如格式化 NVM 命令中指定的那样),则使用元数据指针 (MPTR) 字段指向元数据。“元数据指针”字段的定义取决于此字段中的设置。请参阅图 106。

09:08bit:融合操作 (FUSE):在融合操作中,通过将两个更简单的命令“融合”在一起来创建复杂的命令。请参阅第 4.12 节。此字段指定此命令是否是融合操作的一部分,如果是,则指定该命令在序列中的第几个命令。00b:正常操作;01b:融合操作,第一个命令;10b:融合操作,第二个指令。

07:00bit:操作码 (OPC):此字段指定要执行的命令的操作码。


Admin Command Set 和 NVM Command Set 的 64 字节命令格式在图 106 中定义。将来定义的任何其他 I/O 命令集都可能使用备用命令大小或格式。

SGL 不得用于 NVMe over PCIe 实施中的管理员命令。

图 106:命令格式 – 管理员和 NVM 命令集

03:00字节  :命令 Dword 0 (CDW0):此字段是所有命令的通用字段,如图 105 所示。

07:04字节:Namespace标识符 (NSID):此字段指定此命令作用的NS。如果NSID未用于命令,则应将此字段清除为 0h。此字段中的值 FFFFFFFFh 是一个广播值(请参阅第 6.1 节),其中范围(例如,NVM 子系统、所有连接的NS或 NVM 子系统中的所有NS)取决于命令。请参阅图 141、图 142 和图 350,了解支持在此字段中使用值 FFFFFFFFh 的命令。  除非另有说明,否则在使用NSID的命令中指定非活动NSID(请参阅第 6.1.4 节)将导致控制器中止状态为“命令中无效字段”的命令。除非另有说明,否则在使用NSID的命令中指定无效的NSID(请参阅第 6.1.2 节)将导致控制器中止状态为“Namespace或格式无效”的命令。  如果NSID用于命令(请参阅图 141 和图 142),则该命令不支持值 FFFFFFFFh,并且主机指定值 FFFFFFFFh,则控制器应中止状态为 Invalid Field in Command 的命令,除非另有指定。如果NSID未用于命令,并且主机指定了一个从 1h 到 FFFFFFFFh 的值,则控制器应中止状态为“命令中无效字段”的命令,除非另有指定。

 23:16字节:元数据指针 (MPTR):当在Format NVM 命令中指定的元数据未与逻辑块数据交错时,此字段才有效。这是 NVMe over Fabrics 实现中的保留字段。如果 CDW0.PSDT(参见图 105)被清除到 00b,则此字段应包含连续的元数据物理缓冲区的地址,并且该地址应与 dword 对齐(即,位 1:0 清除到 00b)。控制器不需要检查位 1:0 是否已清除到 00b。如果位 1:0 未清除到 00b,控制器可能会报告命令中无效字段的错误。如果控制器未报告命令中无效字段的错误,则控制器应像将 1:0 位清除到 00b 一样运行。 如果 CDW0.PSDT 设置为 01b,则此字段应包含元数据的连续物理缓冲区的地址。请参阅 Identify Controller 数据结构中 SGLS 字段的第 17 位,了解对齐要求。如果 CDW0.PSDT 设置为 10b,则此字段是一个包含 SGL 描述符的 SGL 段的地址。该 SGL 段的地址应与 qword 对齐(即,位 2:0 清除到 000b)。该 SGL 段中包含的 SGL 描述符是命令元数据的第一个 SGL 描述符。如果该 SGL 段中包含的 SGL 描述符是 SGL 数据块描述符,则该 SGL 数据块描述符是唯一的 SGL 描述符,因此描述了整个元数据数据传输。请参阅第 4.4 节。控制器不需要检查位 2:0 是否已清除到 000b。如果未将位 2:0 清除到 000b,控制器可能会报告命令中无效字段的错误。如果控制器没有报告命令中无效字段的错误,则控制器应像将 2:0 位清除到 000b 一样运行。

39:24字节:数据指针 (DPTR):此字段指定命令中使用的数据。如果 CDW0.PSDT 被清除到 00b,则此字段的定义为:

  • 39:32字节:PRP 条目 2 (PRP2):此字段:a) 如果数据传输未跨越内存页边界,则保留; b) 如果数据传输正好跨越一个内存页边界,则指定第二个内存页的页基址。例如,i. 命令数据传输长度的大小等于一个内存页,并且PRP1的PBAO字段的偏移部分为非零; 或 ii.PRP1的PBAO字段的偏移部分等于0h,命令数据传输长度大于1个内存页且小于等于2个内存页; c) 如果数据传输跨越多个内存页边界,则为 PRP 列表指针。例如,i. 命令数据传输长度大于或等于两个内存页,但PRP1的PBAO字段的偏移部分不为零; 或 ii.命令数据传输长度等于两个以上的内存页,PRP1 的 PBAO 字段的偏移部分等于 0h。
  • 31:24 字节:PRP 条目 1 (PRP1):此字段包含命令的第一个 PRP 条目或 PRP 列表指针,具体取决于命令。

        如果 CDW0.PSDT 设置为 01b 或 10b,则此字段的定义为:

  • 39:24字节:SGL条目1 (SGL1):此字段包含命令的第一个 SGL 段。如果 SGL 段是 SGL 数据块或键控 SGL 数据块或传输 SGL 数据块描述符,则它描述整个数据传输。如果需要多个 SGL 段来描述数据传输,则第一个 SGL 段是一个段或最后一个段描述符。请参阅 4.4 节,了解 SGL 段和描述符类型的定义。NVMe 传输可能支持 NVMe 传输绑定规范中定义的 SGL 描述符类型和功能的子集。

43:40字节:CDW10,特定命令Dword10; 47:44:CDW11、51:48:CDW12、55:52:CDW13、59:56:CDW14、63:60:CDW15;


除了通常为所有 Admin 和 NVM 命令定义的字段外,Admin 和 NVM 供应商特定命令还可能支持“数据传输中的 Dwords 数”和“元数据传输中的 Dwords 数”字段。如果支持,Admin Vendor Specific Command 和 NVM Vendor Specific Commands 的命令格式在图 107 中定义。有关详细信息,请参阅第 8.7 节。

---------------------------------------------------------------------------------------------------------------------------------

4.6 完成队列条目

完成队列中的条目大小至少为 16 个字节。图 123 描述了CQ Entry 数据结构的前 16 个字节的布局。Dword0的内容是特定于命令的。如果命令使用 Dword 0,则此 dword 的定义包含在关联的命令定义中。如果命令不使用 Dword0,则保留该字段。Dword1是保留的。Dword 2 在图 124 中定义,Dword 3 在图 125 中定义。将来定义的任何其他 I/O 命令集都可能使用备用的完成队列条目大小或格式。

如果完成队列条目是通过多次写入构造的,则应在该完成队列条目的最后一次写入中更新 Phase Tag 位

图 123:完成队列条目布局 – 管理员和 NVM 命令集

图 124:完成队列条目:DW 2

31:16b:SQ 标识符 SQID):指示向其发出命令的关联SQ。当多个SQ共享单个CQ时,主机软件使用此字段与命令标识符 (CID) 结合来唯一确定完成的命令。这是 NVMe over Fabrics 实现中的保留字段。

15:00b:SQ Head Pointer (SQHD):指示SQID字段中的SQ当前的SQ Head 指针。这用于向主机指示已使用并可能重新用于新条目的提交队列条目。注意:返回的值是创建CQ条目时SQ Head 指针的值。当主机软件使用CQ条目时,控制器可能有一个SQ Head 指针,该指针已超出指示的值主机通过读取CQ entry中的SQHD和SQ Tail DB(主机写入)来获取SQ entry的数量。


图 125:完成队列条目:DW 3

31:17b:状态字段 (SF):指示正在完成的命令的状态。请参阅第 4.6.1 节。

16b:阶段标记 (P)标识CQ条目是否为新条目。在将 CC.EN 设置为“1”之前,主机软件应将所有CQ条目的 Phase Tag 值初始化为“0”。当控制器将一个条目放入CQ时,控制器应反转相位标签,以使主机软件能够区分新的条目。具体来说,对于 CC.EN 设置为“1”之后的第一组CQ条目,所有阶段标签在发布时都设置为“1”。对于第二组完成队列条目,当控制器绕到CQ的顶部时,所有阶段标记在发布时都会被清除为“0”。Phase Tag 的值在每次通过CQ时都会反转。这是 NVMe over Fabrics 实现中的保留位。

15:00b:命令标识符 (CID):指示正在完成的命令的标识符。当命令提交到SQ时,主机软件会分配此标识符。SQID和CID的组合唯一标识正在完成的命令。SQ一次未完成的请求数上限为 64 Ki。 


4.6.1 状态字段定义

状态字段定义了CQ条目中指示的命令的状态,如图 126 所示。

Status Field 的值为 0h 表示命令成功完成,没有致命或非致命错误情况。除非另有说明,否则如果命令由于多种原因而无法成功完成,则供应商会选择返回的特定状态代码。

图 126:完成队列条目:状态字段

31b:请勿重试 (DNR):如果设置为“1”,则表示在此NVM subsystem中如果任何一个控制器对一条命令进行了重新申请,则该重新申请的命令预计会失败。如果清除为“0”,则表示如果重试同一命令可能会成功。如果命令由于有时间限制的错误恢复而中止(请参阅第 5.21.1.5 节),则应将此位清除为“0”。如果 SCT 和 SC 字段被清除到 0h,则此位应被清除到 '0'。

30b:更多 (M):如果设置为“1”,则此命令的更多状态信息作为错误信息日志的一部分,可以使用“获取日志页”命令检索。如果清除为“0”,则此命令没有其他状态信息。请参阅第 5.14.1.1 节。

29:28b:命令重试延迟 (CRD):如果 DNR 位被清除为“0”,并且主机在主机行为支持功能中将高级命令重试启用 (ACRE) 字段设置为 1h(请参阅第 5.21.1.22 节),则: a) 00b CRD 值表示命令重试延迟时间为零(即,主机可以立即重试命令);  b) 非零 CRD 值在识别控制器数据结构中选择一个字段(参见图 251),该字段指示命令重试延迟时间:

  • • 01b CRD 值选择命令重试延迟时间 1 (CRDT1) 字段;
  • • 10b CRD 值选择命令重试延迟时间 2 (CRDT2) 字段;
  • • 11b CRD 值选择命令重试延迟时间 3 (CRDT3) 字段。

        至少在所选字段指示的时间量过去之前,主机不应重试该命令。主机在此时间之前重试该命令不会出错。如果在“状态”字段中将 DNR 位设置为“1”,或者在“主机行为支持”功能中将 ACRE 字段清除为 0h,则将保留此字段。如果 SCT 和 SC 字段被清除到 0h,则此字段应被清除到 00b。

27:25b:状态代码类型 (SCT):指示CQ条目的状态代码类型。这表示控制器返回的状态类型。

24:17b:状态代码 (SC):表示状态代码,用于标识所指示命令的任何错误或状态信息。


4.6.1.1 状态代码类型 (SCT)

CQ条目表示所报告的完成类型的状态代码类型。图127指定了状态代码类型值和说明。

4.6.1.2 状态代码 (SC)

完成队列条目中的状态代码 (SC) 字段表示有关正在报告的完成的更详细的状态信息。每个状态代码值集都分为三个范围:

  • • 00h 到 7Fh:适用于管理员命令集,或跨多个命令集;
  • • 80h 至 BFh:I/O 命令集特定状态代码;
  • • C0h 到 FFh:供应商特定状态代码。

除非另有说明,否则如果应用了多个状态代码,则控制器将选择返回的状态代码。

4.6.1.2.1 通用命令状态定义

CQ条目的状态代码类型为“通用命令状态”,表示与命令关联的状态值,该值在许多不同类型的命令中是通用的。

4.6.1.2.2 命令特定状态定义

带有状态代码的完成队列条目 “命令特定错误类型”表示特定于特定命令操作码的错误。状态代码 00h 到 7Fh 表示管理员命令错误。80h 到 BFh 的状态代码特定于选定的 I/O 命令集。

4.6.1.2.3 介质和数据完整性错误定义

带有状态代码的完成队列条目 介质和数据完整性错误类型表示与命令关联的错误,该错误是由于与 NVM 介质关联的错误或数据完整性类型错误造成的。

--------------------------------------------------------continue----------------------------------------------------------

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值