NVMe系统内存结构 - 命令格式
- 1 Submission Queue与Completion Queue定义
- 1.1 空队列
- 1.2 满队列
- 1.3 队列大小
- 1.4 队列标识符
- 1.5 队列优先级
- 2 Submission Queue - 命令格式
- 2.1 Command Dword 0
- 2.2 Command Format – Admin Command Set
- 2.3 Command Format – NVM Command Set
- 2.4 Command Format – Admin and NVM Vendor Specific Commands (可选)
- 3 小结
本文属于《 NVMe协议基础系列教程》之一,欢迎查看其它文章。
本节介绍NVM Express使用的系统内存结构。
1 Submission Queue与Completion Queue定义
Head和Tail条目指针,对应于Completion Queue Head Doorbells和Submission Queue Tail Doorbells。doorbell寄存器由host软件更新。
-
Tail
一个Queue条目的提交者,使用当前Tail条目指针,来标识下一个空闲Queue条目空间。
提交者将新条目,提交到Tail指向的空闲Queue条目空间后,对Tail条目指针加1。
如果Tail条目指针增量,超过Queue大小,则Tail条目指针将归零。
只要Queue未满,提交者可以继续向Queue提交条目。
注意: 提交者应考虑Queue封装条件。 -
Head
Queue上条目的消费者,使用当前的Head条目指针,来标识下一个要从Queue中取出的条目。
在从Queue中取出下一个条目后,消费者对Head条目指针加1。
如果Head条目指针增量,超过Queue大小,则Head条目指针将归零。
只要Queue不为空,消费者就可以继续从Queue中取出条目。
注意: 消费者应考虑Queue封装条件。
Submission Queue和关联的Completion Queue的创建和删除,需要由主机软件正确排序。
- 先创建Completion Queue,后创建Submission Queue
主机软件应在,创建任何关联的Submission Queue之前,创建Completion Queue。Submission Queue可以在,关联的Completion Queue创建后的任何时间创建。 - 先删除Submission Queue,后删除Completion Queue
主机软件应在,删除Completion Queue之前,删除所有相关联的Submission Queue。主机软件应该,只在Submission Queue处于空闲状态,且没有未完成的命令时才删除它。
如果主机软件,将无效值写入Submission Queue Tail Doorbell或Completion Queue Head Doorbell寄存器,并且Asynchronous Event Request命令未完成,则异步事件将以状态码"Invalid Doorbell Write Value"投递到Admin Completion Queue;关联的Queue应该被主机软件删除并重新创建。对于遇到此错误的Submission Queue,控制器可能会完成先前获取的命令;但不会再获取额外的命令。这种情况可能是,由于主机软件试图将条目添加到满的Submission Queue,或从空的Completion Queue中删除条目引起的。
命令被覆盖时的行为是未定义的。
如果Completion Queue中,没有空闲的Completion Queue条目,则控制器不应将状态,投递到该Completion Queue,直到Completion Queue条目变得空闲为止。在这种情况下,控制器可以停止处理,与受影响的Completion Queue关联的其他Submission Queue条目,直到Completion Queue条目空闲可用为止,但控制器可以继续处理其他队列。
1.1 空队列
当Head条目指针等于Tail条目指针时(Head == Tail),队列为空。
1.2 满队列
当Head条目指针比Tail条目指针多1时(Head == Tail + 1),队列已满。满时队列中的条目数比队列Size少一个。
注意:在确定队列是否已满时,应考虑队列封装条件。
1.3 队列大小
Queue大小在一个16位的基于0的字段中表示,该字段表示队列中的条目数。
- I/O Queue大小:2 ~ 64K
包括l/O Submission Queue或I/O Completion Queue。Queue具体大小,受CAP.MQES字段中报告的,控制器支持的最大队列大小的限制。 - Admin Queue大小:2 ~ 4K
包括Admin Submission Queue或Admin Completion Queue。Queue具体大小,受AQA.ACQS和AQA.ASQS字段的限制。
由于Head和Tail条目指针定义,每个队列中的一个条目不可使用。
1.4 队列标识符
每个队列通过创建队列时,分配给队列的16位ID值来标识。
1.5 队列优先级
如果支持带有Urgent优先级仲裁机制的加权轮询,则host软件可以分配一个Urgent、High、Medium或Low的队列优先级服务分类。如果不支持带有紧急优先级仲裁机制的加权轮询,则不使用该优先级设置,并被控制器忽略。
2 Submission Queue - 命令格式
每条命令的大小为64字节。
- 命令Dword 0、Namespace Identifier、Metadata Pointer、PRP Entry 1和PRP Entry 2,对所有Admin命令和NVM命令有共同的定义。
- SGL Entry 1和Metadata SGL Segment Pointer,对所有NVM命令有共同的定义(SGLs不用于Admin命令)。
- Metadata Pointer、PRP Entry 1、PRP Entry 2和Metadata SGL Segment Pointer,不是所有命令都使用的。
2.1 Command Dword 0
命令Dword 0定义,如下表所示。
Bit | Description |
---|---|
31:16 | Command Identifier (CID):当与Submission Queue identifier结合使用时,此字段指定命令的唯一标识符。 |
15 | PRP or SGL for Data Transfer (PSDT):此字段指定与命令相关的任何数据传输,是否使用PRPs或SGLs。 如果清除为’ 0 ‘,则该命令将使用PRPs,来传输任何相关的数据或元数据。 如果设置为’ 1 ',则该命令使用SGLs,来传输任何相关的数据或元数据。 所有Admin命令,应使用PRPs。 |
14:10 | 保留 |
09:08 | Fused Operation (FUSE):在融合操作中,通过将两个简单命令“融合”在一起,来创建复杂命令。 此字段指定,此命令是否是融合操作的一部分,如果是,它是序列中的哪个命令。 |
07:00 | Opcode (OPC):指定要执行的命令的操作码。 |
2.2 Command Format – Admin Command Set
Admin命令集(Admin Command Set)和NVM命令集(NVM Command Set)的64字节命令格式,定义如下表所示。
将来定义的任何其他I/O命令集(I/O Command Set),都可以使用另一种命令大小或格式。
Bytes | Description |
---|---|
63:60 | Command Dword 15 (CDW15):该字段是命令专用的Dword 15。 |
59:56 | Command Dword 14 (CDW14):该字段是命令专用的Dword 14。 |
55:52 | Command Dword 13 (CDW13):该字段是命令专用的Dword 13。 |
51:48 | Command Dword 12 (CDW12):该字段是命令专用的Dword 12。 |
47:44 | Command Dword 11 (CDW11):该字段是命令专用的Dword 11。 |
43:40 | Command Dword 10 (CDW10):该字段是命令专用的Dword 10。 |
39:32 | PRP Entry 2 (PRP2):该字段包含该命令的第二个PRP条目,或者如果数据传输跨越两个以上的内存页,则该字段是一个PRP列表指针。 |
31:24 | PRP Entry 1 (PRP1):该字段包含该命令的第一个PRP条目,或者一个PRP列表指针,具体取决于该命令。 |
23:16 | Metadata Pointer (MPTR):该字段包含元数据的连续物理缓冲区的地址。该字段仅用于元数据与逻辑块数据不交错的情况,如Format NVM命令中指定的。此字段应以Dword对齐。 |
15:08 | 保留 |
07:04 | Namespace Identifier (NSID):这个字段指定了,这个命令应用到的命名空间ID。如果命令中没有使用命名空间ID,则该字段清空为0h。如果一个命令应用到设备上的所有命名空间,那么该字段应该设置为FFFFFFFFh。 除非另有说明,在使用命名空间ID的命令中,指定未激活的命名空间ID,将导致控制器在command中带有状态“Invalid Field”而中止命令。 在使用命名空间ID的命令中,指定无效的命名空间ID,将导致控制器以状态“Invalid Namespace”或“Format”中止命令。 |
03:00 | Command Dword 0 (CDW0):该字段对所有命令都是通用的,见上表Command Dword 0定义。 |
2.3 Command Format – NVM Command Set
Bytes | Description |
---|---|
63:60 | Command Dword 15 (CDW15):该字段是命令专用的Dword 15。 |
59:56 | Command Dword 14 (CDW14):该字段是命令专用的Dword 14。 |
55:52 | Command Dword 13 (CDW13):该字段是命令专用的Dword 13。 |
51:48 | Command Dword 12 (CDW12):该字段是命令专用的Dword 12。 |
47:44 | Command Dword 11 (CDW11):该字段是命令专用的Dword 11。 |
43:40 | Command Dword 10 (CDW10):该字段是命令专用的Dword 10。 |
39:24 | 若将CDW0[15]清除为’0’,则该字段的定义为: - PRP Entry 2 (PRP2):该字段包含该命令的第二个PRP条目,或者如果数据传输跨越两个以上的内存页,则该字段是一个PRP列表指针。 - PRP Entry 1 (PRP1):该字段包含该命令的第一个PRP条目,或者一个PRP列表指针,具体取决于该命令。 若将CDW0[15]设置为’1’,则该字段的定义为: - SGL Entry 1 (SGL1):该字段包含该命令的第一个SGL段。如果SGL段是一个Data Block描述符,那么它描述了整个数据传输。如果需要多个SGL段来描述数据传输,那么第一个SGL段是一个Segment,或最后一个段描述符。 |
23:16 | 若将CDW0[15]清除为’0’,则该字段的定义为: - Metadata Pointer (MPTR):该字段包含元数据的连续物理缓冲区的地址。该字段仅用于元数据与逻辑块数据不交错的情况,如Format NVM命令中指定的。此字段应以Dword对齐。 若将CDW0[15]设置为’1’,则该字段的定义为: - Metadata SGL Segment Pointer (MSGLP):该字段包含一个SGL段的地址,其中包含一个描述要传输的元数据的SGL描述符。该字段仅用于元数据与逻辑块数据不交错的情况,如Format NVM命令中指定的。该字段应Qword对齐。 |
15:08 | 保留 |
07:04 | Namespace Identifier (NSID):这个字段指定了,这个命令应用的命名空间。如果该命名空间未用于该命令,则该字段将被清除为0h。如果命令应用于设备上的所有命名空间,则该值应设置为FFFFFFFFh。 |
03:00 | Command Dword 0 (CDW0):该字段对所有命令都是通用的,见上表Command Dword 0定义。 |
2.4 Command Format – Admin and NVM Vendor Specific Commands (可选)
除了为所有Admin和NVM命令,定义的通用字段外,Admin和NVM Vendor Specific命令可能支持Data Transfer字段中的Dwords数,和MPTR字段中的Dwords数。
如果支持,则Admin Vendor Specific Command和NVM Vendor Specific Command的命令格式,定义在下表中。
Bytes | Description |
---|---|
63:60 | Command Dword 15 (CDW15):该字段是命令专用的Dword 15。 |
59:56 | Command Dword 14 (CDW14):该字段是命令专用的Dword 14。 |
55:52 | Command Dword 13 (CDW13):该字段是命令专用的Dword 13。 |
51:48 | Command Dword 12 (CDW12):该字段是命令专用的Dword 12。 |
47:44 | Number of Dwords in MPTR (NDM):该字段表示,元数据传输中的Dwords数量。 |
43:40 | Number of Dwords in Data Transfer (NDT):这个字段表示,数据传输中的Dwords数量。 |
39:16 | 不同类型命令,此部分含义有所不同,具体参考Admin命令与NVM命令具体定义。 |
15:08 | 保留 |
07:04 | Namespace Identifier (NSID):该字段表示,该命令应用的命名空间ID。如果命令中,没有使用命名空间ID,则该字段清空为0h。如果一个命令,应用到设备上的所有命名空间,那么该字段,应该设置为FFFFFFFFh。 对于Vendor Specific Command,控制器对未激活的命名空间ID的响应行为是厂商指定的。在使用命名空间ID的命令中,指定无效的命名空间ID,将导致控制器以状态“Invalid Namespace”或“Format”中止命令。 |
03:00 | Command Dword 0 (CDW0):该字段对所有命令都是通用的。 |
3 小结
命令需要被提交到Submission Queue中,以便NVMe控制器执行,在执行结束后,会有对应的完成状态,放入到Completion Queue中。
NVMe命令长度均为64Byte,对应的completion消息长度均为16Byte。
因此,在Submission Queue中,每条命令都是64字节,无论是Admin命令,还是NVM命令(IO命令)。
NVMe命令,按如下方式,进行组织:
-
如果是Admin或NVM命令(IO命令),则在Metadata Pointer与Data Pointer这两个部分(39:16),含义有所不同,其他均相同。
-
如果是Vendor Specific Command,除了在Metadata Pointer与Data Pointer这两个部分(39:16)不同外,还有Dword 10和Dword11这两个部分(47:40),含义有所不同,其他均相同。