目录
简介
NVMe 中有3种复位机制:NVM Subsystem Reset、Controller Level Reset、Queue Level Reset
本文主要参考协议规范 NVMe 1.4 版本。
详细描述
Reset 相关术语关系图
NVM Subsystem Reset
触发方式
- 主电源供给 NVM subsystem 时。
- 当 NSSR.NSSRC field 被写入 4E564D65h (“NVMe”) 的值。
- 使用 NVMe 管理接口规范中定义的方法请求时。
- 一个 vendor specific event 发生时。
作用范围
- 整个 NVM subsystem。
- 构成 NVM subsystem 的所有 controller 上启动 Controller Level Reset。
- 禁用 Persistent Memory Region,在构成 NVM subsystem 的所有 controller 上。
- NVM subsystem 的所有 PCI Express 端口检测 LTSSM 状态。
过程描述
- NVM subsystem 通电过程中发生 NVM Subsystem Reset 可以由 CSTS.NSSRO 字段的初始值来报告。host 软件可以通过该字段来确定控制器突然断开是否因为 NVM Subsystem Reset 还是其他因素。
- host 软件通过写 NSSR.NSSRC field 来触发 NVM Subsystem Reset。不过 NSSR.NSSRC field 只是通过 CAP.NSSRS field 的控制器可选功能。为了保护 NVM subsystem 免受无意的 NVM Subsystem Reset,可以不给 NVM subsystem 的控制器提供该功能。
- 一个 vendor specific event 被用来触发 NVM Subsystem Reset 是允许的。目的是为了从严重的 NVM subsystem 内部错误中恢复过来,因为该错误阻止了正常操作进行。比如,致命的硬件错误或者固件错误。
Controller Level Reset
触发方式
- NVM Subsystem Reset。
- Conventional Reset(详见另一文章 PCIe Reset,包括了 Cold Reset、Warm Reset、Hot Reset)。
- Function Level Reset(详见另一文章 PCIe Reset)。
- Controller Reset,即 CC.EN 从“1”转换为“0”。
过程描述
- 控制器停止处理所有未执行的 Admin 或 I/O 命令。
- 删除所有的 I/O SQ。
- 删除所有的 I/O CQ。
- 控制器进入 Idle 状态。完成后,CSTS.RDY 被清 0。
- 协议规范中 section 3 定义的所有控制器寄存器和内部控制器状态都被重置,除了如下 3 种情况:
- the Admin Queue registers (AQA, ASQ, or ACQ) 不会作为 Controller Reset 的一部分进行复位。
- the Controller Memory Buffer Memory Space Control register (CMBMSC) 作为单独一部分被复位,既不是 Controller Reset,也不是 FLR。
- the Persistent Memory Region Memory Space Control Upper register (PMRMSCU) 和 the Persistent Memory Region Memory Space Control Lower register (PMRMSCL) 并不作为Controller Reset 的一部分进行复位。
CSTS.RDY
CSTS,全称 Controller Status。RDY,全称 Ready。CSTS.RDY 是一个寄存器 bit。
在 CC.EN 被设定为 1 之后 ,当控制器准备好接收 SQ Tail doorbell 写入时,该 bit 被置 1。
因此,当该 bit 被置 1 时,才会向控制器提交命令。不遵循该操作要求则会产生未知结果。
host 软件应该在 CC.EN 被设定为 1 之后,至少等待 CAP.TO 秒,再将该 bit 置 1(从 0 置 1)。
一旦控制器准备好重新启用,CC.EN 被清 0,该 bit 被清 0。
详见下图:
CAP.TO
CAP,全称 Controller Capabilities。TO,全称 Timeout。CAP.TO 是一个寄存器配置,占 8 bit 。
该配置表示:当 CSTS.RDY 状态变化时 ,最差情况下 host 应该等待的时间。
状态变化包括如下 2 种情况:
- ‘0’ to ‘1’ after CC.EN transitions from ‘0’ to ‘1’。
- ‘1’ to ‘0’ after CC.EN transitions from ‘1’ to ‘0’。
最糟糕的情况可能发生在突发事件之后,比如 shutdown 或 激活一个新的 firmware image。
一般情况下,时间预计是短得多的。
该字段的单位是 500 ms。
详见下图:
section 3 定义的所有控制器寄存器
host 行为
在 Controller Level Reset 之后,host 应该:
- 适当地更新寄存器状态。
- Set CC.EN to ‘1’。
- 等待 CSTS.RDY 被设定为‘1’。
- 根据需求,使用 Admin Cmd 配置控制器。
- 根据需求,创建 I/O CQ 和 I/O SQ。
- 进行正常的 I/O 操作。
注意事项
在所有的 Controller Level Reset 中,除了 Controller Reset,
- 其他复位方式 都需要遵循PCI Express Base specification 去复位 PCI register space 。
- 其他复位方式都会导致立即与 host 失去通信. 在所有这些情况下, 控制器无法指示进行任何 aborts 或
update 任何 completion queue entries。
Queue Level Reset
host 可以通过复位 I/O SQ 和 I/O CQ 来重新配置他们。
触发方式
通过删除 queue 和重新创建 queue来实现复位。
过程描述
- host 在触发之前,应该等待所有 I/O SQ 中的 pending cmd 都完成。
- 执行 reset 时,host 将删除 I/O SQ 和 I/O CQ 的命令提交给 Admin Queue,指定要删除的 queue。
- 删除命令成功完成后, host 通过提交 Create I/O SQ 和 Create I/O CQ 来重新创建 queue。host 可能修改 queue 的属性。
注意事项
- host 应确保 I/O SQ 处于 idle 状态,才去删除该 queue。
- 删除 queue 的操作导致所有 pending cmd 被控制器 abort。aborted cmd 可能收到 CQ,也可能不会收到 CQ。
- 在删除 I/O CQ 之前,应该先删除与之对应的 I/O SQ。在 I/O SQ 创建之后,才能创建与之对应的 I/O CQ。