x86 multi-msi w/o iommu
From: Jeffrey Hugo
Date: Fri Apr 08 2022 - 13:34:34 EST
Hi Thomas,
I'd like to get multi-MSI without IOMMU working on x86. I'm hoping you
could help me understand the current state of things, and if there is a
path toward enabling this.
This is an overly simplistic assessment, but this reportedly works in
other OSes, so it looks like Linux is broken in comparison.
In my investigation so far, the failure stems from
x86_vector_alloc_irqs() in arch/x86/kernel/apic/vector.c [1]. If we
need a contiguous allocation of more than one irq, the allocation
immediately fails:
/* Currently vector allocator can't guarantee contiguous allocations */
if ((info->flags & X86_IRQ_ALLOC_CONTIGUOUS_VECTORS) && nr_irqs > 1)
return -ENOSYS;
As I'm sure you are aware, this only impacts MSI without IOMMU as both
MSI-X and MSI with IOMMU can handle a discontinuous allocation (the flag
is not set for either of those cases).
That check was added back in 2015 with [2]. In 2017, it looks like you
refactored the allocator to the irq_matrix component [3]. However, the
limitation remains to today.
Digging a bit further, it looks like the internal function
matrix_alloc_area() [4] is capable of doing a contiguous allocation, but
all the callers of that via the public api hardcode num to 1. I
wouldn't say it would be trivial to refactor the irq_matrix public api
to do a contigious range allocation, and refactor
x86_vector_alloc_irqs() to do that based on
X86_IRQ_ALLOC_CONTIGUOUS_VECTORS, but since it seems like that hasn't
been tackled in 5-7 years (depending on how you look at the history), I
suspect I'm missing something.
Since I'm poking my nose in an area of the kernel that I haven't gone
poking into before, I'm guessing there is a lot I don't know. Would you
kindly educate me on what the concerns might be?
I look forward to your expertise and opinions.
Thanks
-Jeff
[1]:
https://elixir.bootlin.com/linux/v5.18-rc1/source/arch/x86/kernel/apic/vector.c#L542
[2]:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/x86/kernel/apic/vector.c?h=v5.18-rc1&id=b5dc8e6c21e7ffba0246bf39cea97805c142bf85
[3]:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/x86/kernel/apic/vector.c?h=v5.18-rc1&id=69cde0004a4b5cfc7d1cec4ef9ce4cf4e26142f0
[4]:
https://elixir.bootlin.com/linux/v5.18-rc1/source/kernel/irq/matrix.c#L110