注意:本文翻译仅为学习交流用,版权归原文作者所有。
原文出处。
控制器架构
控制器是Host和NVM子系统之间的接口。有三种控制器:
- IO控制器,普通意义上的控制器,支持访问NVM子系统非易失介质上的逻辑块data、meta和提供管理cap的命令。
- Administrative控制器,支持命令管理,不支持访问。
- discovery控制器,在NVMe over Fabrics中是实现,能访问Discovery Log Page.
Identify Controller
中的controller type
指定控制器类型。所有控制器均实现一个AdminSQ和AdminCQ,不同控制器可能支持实现多个IO提交队列和完成队列。
Host软件向提交队列中提交命令给控制器,通过写SQ Tail DB,控制器被通知新提交命令。之前DB寄存器值和当前DB寄存器的值的差值表示提交了多少命令。
控制器从提交队列中取回命令,并执行命令。除了Fused Op,从多个提交队列中取出的命令在执行上是可以乱序的。命令下发的顺序与数据在非易失介质上存放的顺序,因为乱序执行的存在,并没有必然的联系。
主机软件将更高优先级的命令提交到适当的提交队列。优先级与提交队列本身相关联,因此命令的优先级基于该命令被提交到的提交队列。控制器通过公平和优先级策略仲裁提交队列。
一旦命令被NVM子系统执行完毕,控制器将完成队列项CQE通过完成队列提交至Host。若MSI-X或者多个MSI被使用,那么中断向量指示完成队列有新的命令完成需要Host处理。Host更新CQ head DB寄存器释放提交队列项CQEs,并清除相应中断。
7.1.1 IO 控制器
I/O控制器是一种通用控制器,它支持对NVM子系统的非易失性存储介质提供访问的命令,并可能支持提供管理功能的命令。
IO控制器、命令空间关系:
7.2 提交队列和完成队列
命令下发和完成机制,Host构建命令,和命令完成。
7.2.1 命令处理
命令提交和完成步骤:
- Host将要处理的多个cmd放在下一个提交队列槽位(next SQ slots);
- Host用新的提交队列尾指针更新提交队列尾部DB寄存器,告知控制器新cmd被提交,需要处理;
- 控制器将cmd从提交队列槽位传输至控制器,仲裁机制用于决定控制器执行哪一个提交队列下发的cmd;
- 控制器处理下一个cmd的执行,cmd可能乱序执行;
- 在cmd执行完成后,控制器在关联的完成队列中放cqe,在cqe中,控制器记录提交队列头指针位置sqhd(cqe:cdw2(15:00)),每个新cqe会反转Phase Tag表示这个cqe是新的;
- 控制器向Host产生中断,告知Host有新cqe要被处理。
- Host处理cqe,包括对错误产生动作;
- Host写cqhd(完成队列头DB寄存器)告知cqe被消耗。Host在消耗cqe后更新关联的cqhd.
7.2.2 构建命令基础步骤
Host软件在SQx[pFreeSlot]
构建cmd:
- CDW0.OPC设置为合适的cmd;
- CDW0.FUSE 是否为fused op;
- CDW0.CID 与sq组合形成唯一的cmd id;
- NSID
- MPTR, 记录Meta Region偏移。
- PRP1/2记录数据传输的src/dst
- CDW10-15 cmd spec info
Host软件写相应提交队列DB寄存器(SQxTDBL),提交多个cmd处理。
对提交队列DB寄存器写操作会触发控制器从提交队列中取sqe,控制器将在完成项cqe中反馈最近处理的sqe。
7.2.3 处理完成命令
Host软件处理控制器因为命令完成产生的中断。
- Host软件从完成队列中读取cqe;
- Host软件处理cqe,
DW2.SQID
指示提交队列ID,DW3.CID
指示完成cmd; - DW3.SF指示cmd完成状态;
- Host软件通过更新相应的完成队列Head DB寄存器(
CQyHDBL
)指示可用的完成队列槽位。更新CQyHDBL
,相应的中断也会被清除; - 如果有错误,
DW3.SF
中会记录错误,Host软件会执行错误恢复动作。
7.3 Resets
…
7.4 Queue Mgnt.
建立IO提交队列和完成队列:
- 初始化AdminQueue属性(
AQA
),AdminQueue基地址(ASQ
),完成队列基地址寄存器; - 配置IO提交队列和完成队列大小
CC.IOSQES
和CC.IOCQES
; - 对IO SQ/CQ下发
set feature
设置队列属性,set feature
的cqe指示IO提交队列和完成队列的个数; - 设置每个队列支持的最大qe个数(
cap.mqets
)和是否需要队列在物理上连续(cap.cqr
); - 创建IO完成队列;
- 创建IO提交队列
7.4.3 Queue Abort
终止下发命令的推荐步骤是:删除IO提交队列,然后重新创建IO提交队列。
7.5 Interrupts
spec允许控制器配置4种模式的中断:1)pin-base interrupt, 2) single message MSI, 3) multiple message MSI, 4) MSI-X。 其中推荐使用MSI-X,高性能、低延时、处理中断时低CPU利用率。
中断聚合,也被称为中断合并,通过降低控制器生成中断请求的速率来减轻主机中断开销。
7.5.1.1.1 Interrupt Example (Informative)
软件处理中断流程:
- 处理器将cqe放入IO完成队列,控制设置
IS
寄存器,控制器向主机断言一个中断。 - 触发中中断服务例程;
- Host软件扫描IO完成队列,判断cqe的位置;
- Host软件写
xxh
到INTMS
寄存器,对中断向量做掩码处理; - 处理器对中断向量做掩码;
- 主机软件安排一个延迟过程调用(DPC)来处理完成的命令;
- 触发延迟过程调用(DPC);
- 主机软件处理I/O完成队列3的新完成队列条目,完成与操作系统相关的命令,Host软件更新
CQyHDBL
应答处理的cqe,并且清除中断。 - Host软件解除掩码。
7.6 Controller Initialization and Shutdown Processing
7.6.1 Initialization
Host执行命令前的初始化:
- 根据系统配置设置PCI/PCI Express寄存器,包括电源管理配置;
- Host等待控制器完成前一个reset操作,
CSTS.RDY
变成0; - 配置AdminQueue,Admin Queue Attributes(AQA), Admin SQ Base Address(ASQ), Admin Completion
Queue Base Address (ACQ); - 配置控制器,1) 仲裁机制,
cc.ams
2) 内存页大小,cc.mps
3)设置被使用的IO CMD set,或者设置CC.CSS
使得只有Admin Command Set被支持。 - 控制器使能,
cc.en=1
; - host等待,直到控制器准备处理cmd,
csts.rdy=1
; - 主机应该通过发出
Identify
命令来确定控制器的配置,并指定控制器数据结构。然后,主机应该为每个Namespace
发出Identify
命令,指定名称空间数据结构,从而确定每个Namespace
的配置; - 如果控制器实现了I/O队列,那么主机应该使用带有队列数量特征标识符的
Set Features
命令来确定I/O提交队列和I/O完成队列的数量。在确定I/O队列的数量后,应该配置MSI和/或MSI-x寄存器; - 如果控制器实现了I/O队列,那么主机应该根据系统配置所需的数量和控制器支持的数量分配适当数量的I/O完成队列。使用
Create I/O Completion Queue
命令分配I/O完成队列; - 同上,IO SQ;
- 要启用可选事件的异步通知,主机应该发出
Set Features
命令,指定要启用的事件。要启用事件的异步通知,主机应该提交适当数量的异步事件请求命令。这个步骤可以在控制器发出控制器准备好了的信号之后的任何时刻执行(CSTS.RDY=1
)。
7.6.2 Shutdown
Host执行shutdown操作:
- 停止向控制器提交任何新的I/O命令,并允许任何未完成的命令完成;
如果控制器实现了I/O队列,那么主机应该使用delete I/O Submission Queue命令删除所有I/O提交队列。 - 成功完成Delete I/O Submission Queue命令的结果是,剩余的未执行命令将被中止;
- 如果控制器实现了I/O队列,那么主机应该删除所有I/O完成队列,使用
delete I/O Completion Queue
命令; - 主机应该将
Shutdown Notification
字段设置为CC.SHN=01b
,以表示正常关闭操作。控制器通过将shutdown Status (CSTS.SHST)
字段更新到10b来指示shutdown处理何时完成。
7.7 Asynchronous Event Request Host Software Recommendations (Informative)
Host软件处理异步事件请求(AER)
- 如果报告的日志页面中的事件可能被异步事件配置特性禁用(参考章节5.21.1.11),那么主机软件为异步事件配置特性发出
Set Features
命令,指定禁用报告所有使用日志页面报告的事件。主机软件应等待Set Features命令完成; - 主机软件发出
Get Log Page
命令,请求作为异步事件命令完成的一部分报告的日志页面。主机软件应该等待Get Log Page
命令完成; - 主机软件解析返回的
Log Page
。如果条件不是持久的,那么主机软件应该重新启用所有利用Log Page
的异步事件。如果条件是一致性,那么主机软件应该重新启用所有利用Log Page
的异步事件,除了Log Page
中报告的事件。主机通过为异步事件配置特性发出Set Features
命令重新启用事件; - 主机软件应该发出一个异步事件请求命令到控制器(恢复到n个这些命令未完成的数量);
- 如果事件报告被禁用,主机软件应该使用
Asynchronous Event Configuration
来启用事件报告。如果报告的情况可能持续存在,主机软件应该继续监视事件(例如,spare below threshold),以确定是否应该重新启用事件报告。