From: Thomas Gleixner <[email protected]> Sent: Wednesday, September 9, 2026 3:24 AM > > On Mon, Aug 10 2026 at 09:07, Naman Jain wrote: > > --- a/arch/x86/kernel/apic/msi.c > > +++ b/arch/x86/kernel/apic/msi.c > > @@ -137,7 +137,7 @@ msi_set_affinity(struct irq_data *irqd, const struct > > cpumask *mask, bool force) > > * IRR. > > */ > > if (lapic_vector_set_in_irr(cfg->vector)) > > - irq_data_get_irq_chip(irqd)->irq_retrigger(irqd); > > + irq_chip_retrigger_hierarchy(irqd); > > That's broken because irqd points at the vector domain already, so there > is no parent and nothing gets retriggered. > > Let's look at the hierarchy when interrupt remapping is enabled: > > | --- [DMAR] > [VECTOR] --- | | -- [IOAPIC] > | --- [REMAP] ---| -- [HPET] > | -- [DEVICE MSI] > > All outer domains have .irq_set_affinity = msi_domain_set_affinity, > which does: > > msi_domain_set_affinity(irqdata, ....) > > irqdata->parent->irq_set_affinity(irqdata->parent, ....); > > In that case msi_set_affinity() is only reachable for the DMAR domain > and all others (IOAPIC, HPET, DEVICE MSI) end up in the REMAP domain > which handles irq_set_affinity and never ends up in the above code. > > In the non-remapping case: > > | -- [IOAPIC] > [VECTOR] --- | -- [HPET] > | -- [DEVICE MSI] > > In this case the vector domain is the MSI parent domain for all of them > and all outer domains will end up in msi_set_affinity() via > msi_domain_set_affinity(). > > In any case 'irqd' in msi_set_affinity() will always point to the vector > domain and therefore the exiting code is correct and can't be changed to > retrigger hierarchy as that would see irqd->parent == NULL and do > nothing. Neither will adding a conditional there do anything useful > because the vector domain always has the retrigger callback set. >
Hmmm. I've been staring at the code to try to understand it all, and I'm not seeing that 'irqd' in msi_set_affinity() always points to the VECTOR domain. Starting with the non-remapping case for simplicity, the only place .irq_set_affinity is set to msi_set_affinity() is in x86_init_dev_msi_info(), and the chip in this case is for the about-to-be-created device MSI IRQ domain. So when msi_set_affinity is called, won't the irqd be for the device MSI domain? And in fact, msi_set_affinity() calls the parent .set_affinity function (and the parent is the VECTOR domain). Finally, in existing code (before this patch) msi_set_affinity() calls the .irq_retrigger function for the device MSI domain, which was set to irq_chip_retrigger_hierarchy() in x86_init_dev_msi_info(). irq_chip_retrigger_hierarchy() then finds the VECTOR domain .irq_retrigger function and the right thing happens. In the remapping case, the same thing happens -- the device MSI domain has its .irq_set_affinity as msi_set_affinity(), as set by x86_init_dev_msi_info(). And before this patch, the VECTOR domain .irq_retrigger gets invoked the same way by going up the hierarchy to VECTOR. v4 of this patch set is here [1]. In Patch 3, it uses the most robust way to invoke .irq_retrigger, which is to check the current irqchip first, and if it doesn't implement .irq_retrigger, invoke irq_chip_retrigger_hierarchy(). With this version, setting .irq_retrigger in x86_init_dev_msi_info() could be dropped, similar to the other places that setting .irq_retrigger is being dropped in Patch 4 of the set. This is what I see from looking at the code. But I don't have a bare metal x86 system running Linux where I can confirm, so maybe I've gone astray. In the Hyper-V guests I can access, device MSI domains don't parent directly to VECTOR there, so they aren't useful to confirm. Thanks for your time looking at this. And thanks to Nam as well. I've learned quite a bit about IRQ domains! Michael [1] https://lore.kernel.org/linux-hyperv/[email protected]/

