nvme doorbell机制

https://nvmexpress.org/wp-content/uploads/2013/04/FMS-2012-How-the-Streamlined-Architecture-of-NVM-Express-Enables-High-Performance-PCIe-SSDs.pdf
在这里插入图片描述
在这里插入图片描述

https://www.flashmemorysummit.com/English/Collaterals/Proceedings/2013/20130812_PreConfD_Marks.pdf
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


SQ/CQ中的”Q”,是Queue,队列的意思,无论SQ还是CQ,都是队列,并且是环形队列。队列有几要素,除了队列深度,队列内容,还有两个重要的,就是队列的头(Head)和尾巴(Tail)。大家都排过队,你加入队伍的时候,都是站到队伍的最后,如果你插队,蛋蛋就会鄙视你。队伍最前头的那个,正在被服务或者等待被服务,一旦完成,就离开队伍。队列的头尾很重要,头决定谁会被马上服务,尾巴决定了新来的人站的位置。
DB,就是用来记录了一个SQ或者CQ的Head和Tail。每个SQ或者CQ,都有两个对应的DB: Head DB和Tail DB。DB是在SSD端的寄存器,记录SQ和CQ的头和尾巴的位置。

在这里插入图片描述

上面是一个队列的生产/消费模型。生产者往队列的Tail写入东西,消费者往队列的Head取出东西。对一个SQ来说,它的生产者是Host,因为它往SQ的Tail位置写入命令,消费者是SSD,因为它往SQ的Head取出指令执行;对一个CQ来说,刚好相反,生产者是SSD,因为它往CQ的Tail写入命令完成信息,消费者则是Host,它从CQ的Head取出命令完成信息。

举个例子,看图说话.

  1. 开始假设SQ1和CQ1是空的,Head = Tail = 0.
    在这里插入图片描述

  2. 这个时候,Host往SQ1中写入了三个命令,SQ1的Tail则变成3。 Host在往SQ1写入三个命令后,同时漂洋过海去更新SSD Controller端的SQ1 Tail DB寄存器,值为3。Host更新这个寄存器的同时,也是在告诉SSD Controller:有新命令了,需要你去取。

在这里插入图片描述

  1. SSD Controller收到通知后,于是派人去SQ1把3个命令都取回来执行。SSD把SQ1的三个命令都消费了,SQ1的Head从而也调整为3,SSD Controller会把这个Head值写入到本地的SQ1 Head DB寄存器。

在这里插入图片描述

  1. SSD执行完了两个命令,于是往CQ1中写入两个命令完成信息,同时更新CQ1对应的Tail DB 寄存器,值为2。SSD并且发消息给Host:有命令完成,请注意查看。

在这里插入图片描述

  1. Host收到SSD的短信通知,于是从CQ1中取出那两条完成信息处理。处理完毕,Host又漂洋过海的往CQ1 Head DB寄存器中写入CQ1的head,值为2。

在这里插入图片描述

看完这个例子,又重温了一下命令处理流程。之前我们也许只记住了命令处理需要8步(距离曹植一步之遥),看完上面的例子,我们应该对命令处理流程有个更深入具体的认识。

那么,DB在命令处理流程中起了什么作用呢?

首先,如前所示,它记住了SQ和CQ的头和尾。对SQ来说,SSD是消费者,它直接和队列的头打交道,很清楚SQ的头在哪里,所以SQ head DB由SSD自己维护;但它不知道队伍有多长,尾巴在哪,后面还有多少命令等待执行,相反,Host知道,所以SQ Tail DB由Host来更新。SSD结合SQ的头和尾,就知道还有多少命令在SQ中等待执行了。对CQ来说,SSD是生产者,它很清楚CQ的尾巴在哪里,所以CQ Tail DB由自己更新,但是SSD不知道Host处理了多少条命令完成信息,需要Host告知,因此CQ Head DB由Host更新。SSD根据CQ的头和尾,就知道CQ能不能以及能接受多少命令完成信息。

DB的另外一个作用,就是通知作用:Host更新SQ Tail DB的同时,也是在告知SSD有新的命令需要处理;Host更新CQ Head DB的同时,也是在告知SSD,你返回的命令完成状态信息我已经处理,同时表示谢意。

这里有一个对Host不公平的地方,Host对DB只能写,还仅限于写SQ Tail DB和CQ Head DB,不能读取DB。蛋蛋突然想唱首歌:

我俩太不公平
爱和恨全由你操纵
可今天我已离不开你
不管你爱不爱我

Host就是这样痴情。在这个限制下,我们看看Host是怎样维护SQ和CQ的。SQ的尾巴没有问题,Host是生产者,对新命令来说,它清楚自己应该站在队伍哪里。但是Head呢?SSD在取指的时候,是偷偷进行的,Host对此毫不知情。Host发了取指通知后,它并不清楚SSD什么时候去取命令,取了多少命令。怎么破?机智如你,如果是你,你会怎么做?山人自有妙计。给个提示:

在这里插入图片描述

这是什么鬼东西?这是SSD往CQ中写入的命令完成状态信息(16字节)。

是的,SSD往CQ中写入命令状态信息的同时,还把SQ Head DB的信息告知了Host!!这样,Host对SQ中Head和Tail的信息都有了,轻松玩转SQ。

CQ呢?Host知道Head,不知道Tail。那怎么能知道Tail呢?思路很简单,既然你SSD知道,那你告诉我呗!SSD怎么告诉Host呢?还是通过SSD返回命令状态信息中。哈哈,看到上图中的“P”吗?干什么用,做标记用。

在这里插入图片描述

具体是这样的:一开始CQ中每条命令完成条目中的”P” bit初始化为0,SSD在往CQ中写入命令完成条目时,会把”P”写成1。记住一点,CQ是在Host端的内存中,Host可以检查CQ中的所有内容,当然包括”P”了。Host记住上次的Tail,然后往下一个一个检查”P”,就能得出新的Tail了。就是这样。

最后,给大宝做个小结:

  1. DB在SSD Controller端,是寄存器
  2. DB记录着SQ和CQ的Head和Tail
  3. 每个SQ或者CQ有两个DB: Head DB 和Tail DB
  4. Host只能写DB,不能读DB
  5. Host通过SSD往CQ中写入的命令完成状态获取Head或者Tail

相关推荐

  1. CAS<span style='color:red;'>机制</span>

    CAS机制

    2024-02-20 16:10:04      40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-20 16:10:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-20 16:10:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-20 16:10:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-20 16:10:04       18 阅读

热门阅读

  1. 开源BLHELI-S 代码详细解读(四)

    2024-02-20 16:10:04       22 阅读
  2. Vue3中watch与watchEffect的区别

    2024-02-20 16:10:04       24 阅读
  3. OSS业务存储适配器模式

    2024-02-20 16:10:04       21 阅读
  4. python数据分析numpy基础之var求数组方差

    2024-02-20 16:10:04       26 阅读
  5. 缓存使用常见思路及问题

    2024-02-20 16:10:04       18 阅读
  6. BUG:required a single bean, but 2 were found:

    2024-02-20 16:10:04       22 阅读
  7. Prompt Engineering 提示工程教程详情

    2024-02-20 16:10:04       29 阅读
  8. LeetCode_20_简单_有效的括号

    2024-02-20 16:10:04       31 阅读
  9. Github 2024-02-19 开源项目日报 Top10

    2024-02-20 16:10:04       31 阅读