7.5 interrupts
中断架构应当去考虑有效的报告中断,这样才能使Host通过最小的开支为中断提供服务。
nvme Specification中允许Controller配置四种中断模式中的一种。这四种模式是:Pin-based中断,Signle message MSI中断,multiple message MSI中断和MSI-X中断。为了提高性能,降低延时和HOST处理中断服务的CPU利用率,建议选择MSI-X中断模式。
中断聚合,也叫作中断合并,旨在通过减少Controller的中断请求频率来减小HOST的中断服务开销。这种减少HOST开支的方式通常以增加延时为代价。本规范中没有规定一种中断聚合算法,而是采用将中断聚合参数传递给Controller,Controller采用各厂商自己定义的聚合算法的方式来进行实现这种中断聚合架构。与Admin Completion相关联的中断不应当被延时触发。
Interrupt Coalescing Feature中的Aggregation Threshold(聚合阈值)代表Host希望的在每个中断向量基础上的最小中断聚合阈值。这个值定义了当在每个中断向量上进行中断聚合降低HOST处理开销到低于阈值水平时的Completion Queue Entries的数量。这个是是HOST推荐给Controller的,Controller可以在到达这个阈值之前或者之后生成一个中断给HOST。Controller实现的使用此值的中断聚合算法是Controller自己定义的。
Interrupt Coalescing Feature中的Aggregation Time(聚合时间)代表了HOST希望的在Controller生成一个中断信号给HOST之前的最大延时。这个值是HOST给Controller的一个建议值,中断可以在此时间到达之前或者之后触发。Controller可以在某个中断或者所有中断上使用此值。Controller实现的使用此值的中断聚合算法是Controller自己定义的。
虽然Controller需要支持Set/Get feature 中的Interrupt Coalescing相关特性,但是聚合阈值和聚合时间的使用是Controller自己决定的。例如,可以忽略掉这两个Feature并且不去实现中断聚合。
7.5.1 Pin Based, Signle MSI, and Multiple MSI Bahavior
如果满足下列任何一个条件,则使用的中断模式为本三种模式:
.Pin Based中断被使用 – MSI(MSICAP.MC.MSIE=’0’)并且MSI-X非使能。
.Signle MSI中断被使用 – MSI被使能(MSICAP.MC.MSIE=’1’),MSICAP.MC.MME=0h,并且MSI-Xf非使能。
.Multiple MSI中断被使用 – Multiple message MSI被使能(MSICAP.MC.MSIE=’1’),MSICAP.MC.MME被设置为001b到101b之间的值,而且MSI-X非使能。
在Controller中有一个对于HOST不可见的中断状态寄存器(IS)。在这种模式下,IS寄存器决定了是PCI中断线被激活使用还是MSI message被发送。在IS寄存器中的每个Bit都对应了一个中断向量(interrupt vector)。当以下情况时,IS寄存器对应Bit被设置为1.
.有一个或多个未被处理的Completion Queue Entries正在与当前中断向量相对应的Completion Queue中。
.Completion Queue中未被处理的Completion Queue Entries来自于一个将中断使能了的Create IO Completion Queue命 令。
.此中断向量相对应的INTM寄存器中的Bit被HOST清0,代表中断没有被MASK。
对于signle或Multiple MSI来说,INTM寄存器在MSI逻辑之前屏蔽掉中断传输。因此,一个中断向量被INTM寄存器MASK掉并不会导致对应的MSI CAP中的Pending位被设置。
如果MSIs没有被使能,IS寄存器的Bit0是一个PCI中断线被激活的原因(电平’0’).如果MSIs被使能了,任何一个IS寄存器的改变都会导致一个UNMASK的状态位从0到1的改变或者清除一个mask中的bit位对应的状态位应该导致一个MSI被发送。因此,在连线模式下,一条线将会保持活动状态,在MSI模式下,会有数个Message可能被发送,因为每一个端口上的边沿触发时间都会导致一个新的message
为了清除一个特定中断向量的中断,HOST软件处理完所有与本中断向量向关的Completion Queue中的Completion Queue Entries。
Status of IS Register | Pin-based Action | MSI Action |
All bits ‘0’ Note:可能是因为INTM寄存器相应的bit被设置为‘1’,MASK掉了相应的中断 | Wire inactive | No action |
One or more bits set to ‘1’ Note: 可能是因为INTM寄存器相应的bit被设置为‘1’,UNMASK掉了相应的中断 | Wire active | New message sent |
One or more bits set to ‘1’, new bit gets set to ‘1’ | Wire active | New message sent |
One or more bits set to ‘1’, some (but not all) bits in the IS register are cleared (i.e., host software acknowledges some of the associated completion queue entries) | Wire active | New message sent |
One or more bits set to ‘1’, all bits in the IS register are cleared (i.e., host software acknowledges all associated completion queue entries) | Wire inactive | No action |
7.5.1.1 Host Software Interrupt Handling
当配置为Pin Based或者MSI message中断模式时,建议Host软件利用Interrupt Mask Set和Interrupt Mask Clear(INTMS/INTMC)寄存器去有效的处理中断。尤其是在中断服务程序中,Host软件应当通过INTMS寄存器设置相应的Mask 寄存器位为1去Mask中断。在这之后的程序调用中,Host软件应当处理掉所有的Completion Queue Entries,并且通过写相应的CqyHDBL DB寄存器来告知Controller Entries已经处理完。所有Completion Queue Entries被处理完之后,Host软件应当通过INTMC寄存器清除相应的Mask寄存器位为0去Unmask掉中断。
建议在处理CQ中的Entries时屏蔽掉正在处理的与本CQ相关联的MSI中断向量,以便误触发或者丢失掉中断。对于Single message或者Multiple message MSI中断,INTMS和INTMC寄存器应当被用来在CQ Entries被处理时恰当的MASK中断。
7.5.1.1.1 Interrupt Example(Informative)
在本节中描述了一个Host软件处理中断的流程。这个例子中假定使用了Multiple Message MSI而且中断向量3和IO CQ3相关联。
1.Controller发送一个CQ Entries到IO CQ3中。Controller设置在内部的IS寄存器中的IS[3]为1。Controller 触发一个中断给host.
2.中断服务程序(ISR)被触发.
3.Host扫描MSI 向量对应的所有IO CQ确定哪些是新的CQ Entries。在这种情况下,有一个新的Entry被发送到IO CQ3.
4.Host软件向INTMS写08h去MASK掉中断向量3的中断。
5.Controller基于Host写入的INTMS寄存器来MASK掉中断向量3.
6.Host软件进行延时调用程序(DPC)去处理Completed command。
7.延时调用程序(DPC)被触发
8.Host软件处理新的CQ3的Entries,完成操作系统相关的命令。Host软件更新CQyHDBL去告知CQ Entries被处理完成并且清除与CQ相应的中断。如果Host软件告知已经完成了所有的CQ Entries,那么Controller de-asserts中断向量3。
9.Host软件通过写08h到INTMC寄存器去UNMASK中断向量3.
7.5.1.2 Differences Between Pin Based and MIS Interrupt
Signle MSI和Pin Based中断行为模式是相似的。主要的区别是报告中断的方式。MSI中断是用MSI message发送一个中断到Host,而不是使用INTx 虚拟线。MSI中断是边沿触发,而不是INTx虚拟线的电平触发。
Pin Based和signle MSI仅支持1个中断向量。Multiple MSI可以使用最多至32个中断向量。
对于Multiple MSI,Controller在MC寄存器的MMC字段告知了Multiple MSI中断向量数。MSICAP.MC.MMC字段使用2的幂次方来表明中断向量个数。例如,三个中断向量被请求的话,那么MSICAP.MC.MMC字段应当被置为’010’.
Multiple-message MSI允许在每个中断向量的基础上进行Completion的聚合。如果中断向量足够多的的话,每个CQ可能发送一个特定的message代表本CQ的中断,反之一个message也可能会代表多个CQ。
7.5.2 MSI-X Based Behabior
MSI和Multiple-message MSI相似的是,允许基于每个中断向量的中断聚合。然而,MSI-X的最大中断向量是2K.MSI-X也允许为每个中断发送一个独一无二的消息。
MSI-X允许中断聚合,每个CQ可能有自己的Message,也可能所有CQ都用一个Message。
当发送一个MSI-X消息时,应当在生成Message之前进行以下检查:
.MSI-X Message Control Register的mask bit没有被设置为1.
.对应的MSI-X table中的vector mask bit没有被设置为1.
如果这两个mask bit都被设置为了1,那么MSI-X PBA中对应的Pending bit也应当被设置为1,代表这个向量的中断正在发生。当这两个mask bit都被清零时,才会生成新的message。