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]/

Reply via email to