Doorbell寄存器——NVMe队列管理的异步指挥家
发布日期:2025-05-02 16:31:12      浏览次数:789

在此前的NVMe相关文章中,我们介绍了NVMe SSD格式化的基本原理和操作。本文将进一步探讨NVMe系统中的另一个关键组件——Doorbell寄存器。


为了更好地理解Doorbell寄存器,我们先来介绍一些NVMe队列的基本操作。在NVMe协议中,队列是主机与控制器进行信息交换的桥梁。主机通过队列向控制器发送请求命令,控制器则通过队列向主机反馈响应。

主机和控制器之间通过队列来完成信息交互,如下图所示:


1)主机写命令到SQ;

2)主机写SQ的Tail Doorbell寄存器,通知控制器取指;

3)控制器收到通知后,到SQ中取指;

4)控制器执行指令;

5)指令执行完成,控制器往CQ中写指令执行结果;

6)控制器发中断通知主机指令完成;

7)主机收到中断,到CQ中取执行结果,查看指令完成状态;

8)主机处理完指令执行结果,通过写CQ的Head Doorbell寄存器通知控制器指令执行结果已处理。


在此过程中,Doorbell寄存器起到了关键作用,负责实现主机与控制器的异步通知机制,从而显著提升了主机与SSD之间的通信效率


1、Doorbell寄存器关键作用


Doorbell寄存器是SSD控制器内的专用寄存器,每个队列对应两个Doorbell寄存器,分别用于记录队列的头(Head)、尾(Tail)位置。以下以提交队列(SQ)为例,说明如果没有Doorbell寄存器,队列使用可能出现的问题。


主机作为写入方,负责维护Tail指针。每次发送命令时,主机将命令写入Tail指针所指的位置。主机和控制器之间没有其他通信途径,主机只负责写入,控制器无法得知何时有新命令到达,因此无法准确读取命令。


控制器作为读取方,负责维护Head指针。每次读取命令时,控制器从Head指针所指的位置获取命令然而,由于无法预知新命令何时到达,控制器可能会进行无效读取。此外,控制器也无法将Head指针的位置通知主机,因此主机无法得知控制器已读取到哪个命令位置。


这种情况下,主机持续向队列写入命令,但由于它不知道控制器读取了多少命令,可能导致新命令覆盖尚未读取的旧命令,从而造成数据丢失或命令执行错误。


为了解决上述问题,NVMe协议引入了Doorbell寄存器,用于同步主机和控制器对队列的读写操作,以确保数据一致性和正确性。


2、Doorbell寄存器的基本原理



主机对Doorbell寄存器仅进行写操作:

  • 当主机向提交队列(SQ)写入命令后,会更新SQ的Tail Doorbell寄存器,以指示新命令的末尾位置。
  • 当主机处理完成队列(CQ)中的响应消息后,会更新CQ的Head Doorbell寄存器,以指示下一次获取响应消息的起始位置。


对于控制器写入的Doorbell寄存器(SQ的Head寄存器和CQ的Tail寄存器),主机不会直接读取这些寄存器,相应的队列指针位置(SQ的Head和CQ的Tail),由主机从响应消息中直接或间接获取。这是为什么呢?


由于寄存器在SSD控制器内部,主机访问寄存器需要通过额外的PCIe命令进行传输。而在控制器提交CQE(完成队列条目)时,SQ的head和CQ的Tail必然是最新值。因此,通过在CQE携带SQ的head和CQ的Tail信息,主机即可从中获取相关指针位置,避免额外的消息交互和信息同步需求。


为了简化协议设计并提升处理性能,主机对控制器的寄存器采取“只写不读”策略。


控制器对Doorbell寄存器进行读写操作:

  • 控制器通过读取SQ的Tail Doorbell寄存器,确定可以读取的新命令;

  • 控制器从SQ获取命令后,会更新SQ的Head Doorbell寄存器,以指示下一次读取的起始位置;

  • 控制器处理完命令并将响应消息写入CQ后,会更新CQ的Tail Doorbell寄存器,以指示新响应的末尾位置。

3、Doorbell寄存器的处理流程下表列出了主机和控制器同步SQ和CQ头尾指针信息的方式,从而实现队列的读写同步。




主机如何通过CQE的P标识位确定CQ当前Tail位置?

CQE中的P(Phase)标识是一个位(bit)字段,用于指示该CQE是否是新一轮的队列循环,以帮助主机区分CQE是属于前一轮的完成通知还是当前轮的完成通知。


在CQ创建时,P标识初始化为0。当写入CQ的第一个entry,无论是首次写入还是队列循环后的写入,P标识都会翻转(初始为0,写第一个entry时翻转为1;初始为1,则翻转为0)。


主机在收到中断时,初始的期望P值就是Head指针所指的entry中的P值。在准备读取CQ的第一个entry位置时,期望值随之翻转。由于控制器支持中断聚合功能,当主机收到CQ中有entry可以读取的中断时,控制器可能已经提交多个CQE到CQ中。


主机从其维护的CQ head指针处依次读取CQ中的entry。如果读取到的entry中P标识位符合预期,则处理该entry并移动head指针;如果读P标识位不符合预期,则表示已经读取到了队列Tail位置,队列中内容已空。



上图中,“中断发生时”主机收到中断,读取Head指针所指entry,并将当前期望P值设为1。从head指针位置(slot 0)开始处理CQE,依次向后读取CQE。由于CQE P值均为1,符合预期,主机逐一处理CQE并移动Head指针。


当处理完slot 3,主机准备处理slot 4时,读取slot 4的P值为0,不符合预期,说明已经到达队列Tail位置,本轮处理结束。处理完成后,指针位置如图中“主机处理完成后”所示。


上图中,“中断发生时”主机收到中断,读取Head指针所指entry,并将当前期望P值设为1。主机从head所在位置(slot 4)开始处理CQE,处理到slot 5,再循环到slot 0。主机随后调整期望P值为0,继续处理slot 0和slot 1。当读取到slot 2时,发现P位不符合预期,说明已经到达Tail,主机结束本轮处理操作。处理完成后,指针状态如图中“主机处理完成后”所示。


当然,主机也可以在到达Tail之前的任何时刻停止本轮处理,此处不再赘述。


从上面例子可以看出,主机无法通过CQE的P标识位直接判断Tail位置。在未到达Tail位之前,主机不能确定Tail具体位置。然而,当主机处理完CQ中所有entry并遇到Tail时,可以及时停止,从而实现了队列操作的同步和互斥


以上是Doorbell寄存器在NVMe队列操作中关键作用和基本原理介绍。Doorbell寄存器不仅简化了主机与SSD控制器之间的通信流程,还通过高效的异步通知机制显著提升了数据处理的速度和效率。


云海芯科将继续紧跟SSD技术的发展趋势和应用,立足技术前沿,持续推动产品创新,提供高可靠的存储解决方案,助力存储技术的进步和推广应用。


关于云海芯科

四川云海芯科微电子科技有限公司是一家业界领先的数据存储解决方案提供商,团队核心成员深耕存储行业15+年,拥有成熟的存储产品研发上市经验。公司扎根国产存储,坚持产品和技术创新发展,拥有闪存管理、数据保护、硬件设计等多项SSD关键技术专利,具备存储产品设计到开发的全流程交付能力,已推出NVMe和SATA全系列SSD产品,在HPC/HPDA、云计算、数据中心、虚拟化、人工智能等领域广泛应用,为金融、交通、通信、智能制造、互联网、能源等行业提供高稳定、高可靠的存储解决方案。




相关推荐