中断的描述符如上所述。作为背景知识,可以理解下面的内容,本文讨论基于的内核版本信息如下:
我们知道,nvme的多队列,默认按照核数的多少来设置,目前nvme的队列有两种,admin队列,IO队列,两者都属于nvme_queue对象,submit queue,complete queue是一个nvme_queue对象的一个成员,其中submit queue在代码中会简写为sq,complete queue会简写成cq。两者是Queue Pair(QP),也就是submitqueue·completequeue和admin queue不是同一个级别的对象,对于admin队列来说,它也有自己的submitquque和completequeue,第一次看代码时往往容易混淆。
首先,我们来看一下nvme总共用的中断数。
该系统上一共4块盘,80个核,就有320个中断,一个核对应一个队列,一个中断号。按道理IOqueue有80个,adminqueue也需要用中断,
那么中断数应该是81*4=324才对。
我们发现,nvme0q0 和 nvme0q1 是共享中断的。而其他的sq都是虽然带的参数也是共享,但是从实际情况看,是独占的。所以数量是320个。
nvme0q0 就是我们可爱的admin queue,从申请的角度看,我们可以看出来,一开始adminqueue申请,用的是裸命令,后面的ioqueues申请,利用的是admin queue的队列。
由于admin的queue是最先申请的,所以包括中断号也是单独申请的,nvme_configure_admin_queue 中,调用静态函数 queue_request_irq来初始化admin的队列的中断,而且它传入的参数是共享的,也就是不需要独占中断,IRQF_SHARED。admin的队列编号是0。
而ioquue,都是调用的nvme_pci_enable来完成中断的申请,
中断注册,也是在队列创建的时候完成,nvme_create_queue ,其中需要注意的是,admin的中断,会先注册,然后再取消注册,然后再注册一次。先注册的目的是为了借助这个中断来返回处理创建sq和cq等命令的结果。
nvme_create_io_queues---|nvme_alloc_queue----分配nvmeq结构体,并记录到dev->queues[]数组中,并分配submit queue 和complete queue命令所需要的空间。
---|nvme_create_queue---|adapter_alloc_cq----构建cmd,利用admin 的queue发送控制消息,分配sq相关信息
---|adapter_alloc_sq----这个是分配submitqueue队列的相关信息,与cq类似。
---|queue_request_irq---这个是申请中断
---|nvme_init_queue---初始化队列
下面,重点了解下queue_request_irq 的传入参数:
也就是nvme驱动默认没有使能中断线程化功能。request_irq 是中断的申请接口了,定义在interrupt.h中,调用request_threaded_irq,其中第三个传入传入的是NULL
request_threaded_irq定义在manager.c中,后面就是中断的通用流程了,我们主要针对传入的参数分析一下:
去掉包裹函数,真正干活的就是nvme_process_cq 了,又看到了熟悉的head,tail标志,这个机制的描述在网上已经烂大街了,借用一下:
Submission Queue使用Tail,Completion Queue使用Head,两者均由Host操作。处理完一个Command,Tail或Head加1,当大于Queue Depth时,则回到0。通过对比Head和Tail的值,就知道一个Queue中有多少未处理的Submission Command。下面的图摘自NVMe Spec,有兴趣的同学可以据此琢磨下Empty Queue和Full Queue的定义。
到此这篇主板nvme接口(主板nvme接口识别不了)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/33222.html