Multi Message MSI 是否在 Linux / x86 上实现?

Is Multi Message MSI implemented on Linux / x86?

我正在为支持 PCIe 总线上的多消息 MSI 中断(不是 msix)的 FPGA 端点开发网络驱动程序。主机处理器是 CentOS 上的 x86 Intel i7 620LM 运行,内核为 4.2。

FPGA 端点在其 MSI 功能寄存器中正确地公布了多个 msi 向量(0x101 = 总共 32 个可能的向量)。

据我所知,内核 4.2 中添加了多消息功能。不幸的是,当我调用 pci_enable_msi_range(pdev, 1, 32); 时,它只调用 returns 1。当我调用 pci_msi_vec_count(pdev); 时,它是 returns 32。我能够在一个向量上请求一个 irq 处理程序,它按预期工作。

有谁知道在 x86 架构上 Linux 是否真正支持多消息 MSI 向量?

更新: 我能够使用带有 i7-4700EQ 处理器的不同 SBC 启用所有 32 个 MSI 矢量。这是一个 4.4-rc1 内核。

更新: 也适用于 4.2。

更新: 在这种情况下,问题出在 coreboot 中。一旦电路板供应商提供了更新,我就能够让多个向量工作。

当然是。 我不确定你为什么会收到错误。但我写过几个使用超过 1 个矢量的驱动程序。

我刚刚在家里检查了我的电脑,我有各种驱动程序更多地使用了 1 MSI IRQ:

$ cat /proc/interrupts | grep -i msi
 33:    5683962          0          0          0          0          0          0          0   PCI-MSI 524288-edge      radeon
 34:          0          0          0          0          0          0          0          0   PCI-MSI 1572864-edge      xhci_hcd
 35:          0          0          0          0          0          0          0          0   PCI-MSI 1572865-edge      xhci_hcd
 36:          0          0          0          0          0          0          0          0   PCI-MSI 1572866-edge      xhci_hcd
 37:          0          0          0          0          0          0          0          0   PCI-MSI 1572867-edge      xhci_hcd
 38:          0          0          0          0          0          0          0          0   PCI-MSI 1572868-edge      xhci_hcd
 39:          0          0          0          0          0          0          0          0   PCI-MSI 1572869-edge      xhci_hcd
 40:          0          0          0          0          0          0          0          0   PCI-MSI 1572870-edge      xhci_hcd
 41:          0          0          0          0          0          0          0          0   PCI-MSI 1572871-edge      xhci_hcd
 42:    3807594          0          0          0          0          0          0          0   PCI-MSI 512000-edge      0000:00:1f.2
 43:          0          0          0          0          0          0          0          0   PCI-MSI 2097152-edge      xhci_hcd
 44:          0          0          0          0          0          0          0          0   PCI-MSI 2097153-edge      xhci_hcd
 45:          0          0          0          0          0          0          0          0   PCI-MSI 2097154-edge      xhci_hcd
 46:          0          0          0          0          0          0          0          0   PCI-MSI 2097155-edge      xhci_hcd
 47:          0          0          0          0          0          0          0          0   PCI-MSI 2097156-edge      xhci_hcd
 48:          0          0          0          0          0          0          0          0   PCI-MSI 2097157-edge      xhci_hcd
 49:          0          0          0          0          0          0          0          0   PCI-MSI 2097158-edge      xhci_hcd
 50:          0          0          0          0          0          0          0          0   PCI-MSI 2097159-edge      xhci_hcd
 51:     310762          0          0          0          0          0          0          0   PCI-MSI 5242880-edge      0000:0a:00.0
 52:         11          0          0          0          0          0          0          0   PCI-MSI 360448-edge      mei_me
 54:   38991293          0          0          0          0          0          0          0   PCI-MSI 7340032-edge      enp14s0
 55:          1          0          0          0          0          0          0          0   PCI-MSI 32768-edge      i915
 56:       1169          0          0          0          0          0          0          0   PCI-MSI 442368-edge      snd_hda_intel
 57:        152          0          0          0          0          0          0          0   PCI-MSI 526336-edge      snd_hda_intel

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 42
Model name:            Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz
Stepping:              7
CPU MHz:               1634.257
CPU max MHz:           3800.0000
CPU min MHz:           1600.0000
BogoMIPS:              6825.67
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid xsaveopt

我在独立于 Linux 内核版本的 Intel 机器上使用多个 MSI 时也遇到了问题。经过大量调整后,我意识到在 bios 中启用 VT-d 可以解决问题(在 Linux 4.6 内核上测试)。我认为这是因为为了在 x86 上支持多个 MSI,Linux 内核需要支持中断重新映射,这是 VT-d 提供的功能之一。

添加 Adrien 提到的内容,打开 CONFIG_IRQ_REMAP 解决了我能够为同一设备请求多个 MSI 的问题。 pci_enable_msi_range 我请求的 msi 中断成功(在本例中为 8)。