- MSI中斷
介紹MSI-X中斷之前,我們先來看看MSI中斷的機制。
MSI中斷本質上是一個memory write,memory write的地址就是設備配置空間的MSI address寄存器的值,memory write的數據就是設備配置空間的MSI data寄存器的值。Message address寄存器和message data寄存器是調用pci_enable_msi時,系統軟件填入的。
也就是說,一個設備想產生一個MSI中斷話,只需要使用配置空間的message address寄存器和message data寄存器發起一個memory write請求,即往message address寄存器寫入memory data。在X86系統下,message address對應的LAPIC的地址。
2.爲何要引入MSI-X
前面講了MSI中斷的機制,其實MSI-X Capability中斷機制與MSI Capability的中斷機制類似。既然機制類似,爲啥還要需要引入MSI-X呢?
回答這個問題前,我們先看看MSI有哪些限制?
(1)MSI相關的寄存器都是在配置空間中,從Message Control寄存器multiple message Capble字段可以看出MSI最多支持32箇中斷向量,且必須是,也就是說如果一個function需要3箇中斷向量,必須申請4個纔可以滿足。
(2)MSI要求中斷控制器分配給該function的中斷向量號必須連續。
MSI-X的出現就是爲了解決上面兩個問題,主要是第二個問題。
3.MSI-X CAP結構
MSI-X和MSI最大的不同是message data、message address字段和status字段沒有存放在設備的配置空間中,而是使用MSI-X Table structure和MSI-X PBA structure來存放這些字段。
MSI-X Table structure和PBA structure存放在設備的BAR空間裏,這兩個structure可以map到相同BAR,也可以map到不同BAR,但是這個BAR必須是memory BAR而不能是IO BAR,也就是說兩個structure要map到memory空間。
注意:一個function只能支持一個MSI-X CAP。
3.1 配置空間的Message control 寄存器
配置空間Message Control寄存器中的table size字段可以獲取MSI-X的table的大小。軟件讀取該字段獲取table size,table size+1就是MSI-X table entry的個數,也就是Figure 7-36中的entry(N-1)中的N,每個entry對應一箇中斷向量。從table size可以看出1個function最多可以支持=2048個MSI-X中斷。
pci_msix_vec_count讀取Message Control寄存器的table size字段獲取MSI-X table entry的個數。
調用關係如下:
pci_enable_msix_range->__pci_enable_msix_range->__pci_enable_msix->pci_msix_vec_count
3.2 配置空間的Table offset/Table BIR寄存器
配置空間中Table offset/Table BIR寄存器的Table BIR字段指示使用哪個BAR來映射的MSI-X Table structure。該字段的0-5也對應function的BAR0-5。
Table offset字段代表MSI-X Table structure entry 0存放在BAR空間的偏移。
kernel代碼先讀取配置空間的Table offset/Table BIR寄存器,通過Table BIR字段獲取使用哪個BAR來映射MSI-X Table structure。然後計算出MSI-X table entry 0相對BAR空間偏移的物理地址(phys_addr),最後ioremap得到虛擬地址。
調用關係如下:
pci_enable_msix_range->__pci_enable_msix_range->__pci_enable_msix->msix_capability_init
2.3配置空間的PBA offset/PBA BIR寄存器
配置空間中PBA offset/PBA BIR寄存器的PBA BIR字段指示使用哪個BAR來映射的PBA structure。該字段的0-5也對應function的BAR0-5。
PBA offset字段代表PBA structure存放在BAR空間的偏移。
4.Memory空間的MSI-X table structure
Message address和Message Upper address字段存放的是MSI-X memory write請求需要使用的地址。
Message Data字段存放的是MSI-X memory write請求需要使用的data。該地址和CPU的架構相關,是使能MSI-X時,系統軟件寫入的。
Kernel函數__pci_write_msi_msg把message address、message data寫入對應的entry。
如果是X86的CPU,存放message address和message data的結構struct msi_msg *msg是在irq_msi_compose_msg中初始化的,這個值和CPU架構相關。
desc->mask_base是MSI-X table entry 0對應的虛擬地址,desc->msi_attrib.entry_nr是MSI-X table entry編號。desc->mask_base和desc->msi_attrib.entry_nr都是在msix_setup_entries賦值的(pci_enable_msix_range->__pci_enable_msix_range->
__pci_enable_msix->msix_capability_init->msix_setup_entries)。
X86下調用關係:
pci_enable_msix_range->__pci_enable_msix_range->__pci_enable_msix-> msix_capability_init-> pci_msi_setup_msi_irqs-> arch_setup_msi_irqs->native_setup_msi_irqs
msi_domain_alloc_irqs->irq_domain_activate_irq->__irq_domain_activate_irq-> msi_domain_activate->irq_chip_write_msi_msg->pci_msi_domain_write_msg-> __pci_write_msi_msg
Vector Control字段存放的是控制字段,當Mask Bit爲1時,PCIe設備不能使用該MSI-X table entry來發送中斷消息。
如果其他的MSI-X table entry也是使用的相同的vector,只要對應entry的vector control寄存器的mask bit字段不爲1,仍然可以使用該vector發送MSI-X中斷消息。這個意思是說Mask Bit的作用範圍是該entry的,如果兩個entry使用相同的vector(對X86來說就是Message Data字段低8 bit相同),Mask Bit不爲1的entry是可以使用該vector發出message中斷。
此時MSI-X中斷還沒有完全初始化完畢,Kernel代碼是把MSI-X vector control 寄存器的Mask bit置1來mask所有vector的中斷。
調用關係:
pci_enable_msix_range->__pci_enable_msix_range->__pci_enable_msix-> msix_capability_init-> msix_program_entries
5、什麼時候umask的vector中斷呢?
以網卡爲例,在request_irq的時候才把MSI-X的使用的vector給unmask的。
__igb_open->request_threaded_irq->__setup_irq->irq_startup->__irq_startup-> unmask_irq->pci_msi_unmask_irq-> msi_set_mask_bit->msix_mask_irq->__pci_msix_desc_mask_irq
6、MSI和MSI-X對比
對比項 |
MSI |
MSI-X |
Message Address |
存放在MSI相關配置空間 |
存放在BAR空間MSI-X table structure |
Message Data |
存放在MSI相關配置空間 |
存放在BAR空間MSI-X table structure |
Sataus相關 |
存放在MSI相關配置空間 |
存放在BAR空間PBA structure |
每個設備支持的Vector數量 |
32 |
2048 |
中斷號連續? |
是 |
否 |
7、舉個例子
說了這麼多拿網卡舉個例子吧。從配置空間可以看出MSI-X使用的BAR3,MSI-X table structure存放在BAR3起始地址+0的位置,PBA structure存在BAR3起始地址+0x2000的位置。
我們來讀一下該地址,發現使用的entry的message地址爲LAPIC的地址。