[PATCH v4 0/4] x86/irq: Fix lost interrupts on CPU hot-unplug

COLD15d

Revision v4 of 4 in this series.

12 messages, 4 authors, 15d ago · open the first message on its own page

[PATCH v4 0/4] x86/irq: Fix lost interrupts on CPU hot-unplug

From: Naman Jain <hidden>
Date: 2026-09-09 06:45:08

On CPU hot-unplug, fixup_irqs() re-injects interrupts that are still
pending in the outgoing CPU's IRR via the irqchip's irq_retrigger()
callback. The Hyper-V root partition PCI/MSI irqchip lost that callback
when it was converted to msi_create_parent_irq_domain(), so such a
pending interrupt is silently dropped, leading to lost interrupts, stalls
and "No irq handler for vector" messages.

Patch 1 is the minimal, backportable fix (Fixes:/Cc: stable) that restores
irq_chip_retrigger_hierarchy() on the Hyper-V root partition PCI/MSI chip.
The equivalent guest pci-hyperv.c fix from the previous version is already
merged, so it is dropped here.

Patch 2 then switches fixup_irqs() to have a fallback call to
irq_chip_retrigger_hierarchy() directly, if a chip does not define
irq_retrigger callback.

Patch 3 makes a similar change in msi_set_affinity()

Patch 4 then drops the now-redundant irq_retrigger() initializations.
This way, patch 2-4 do not need to be backported.

Changes since v3:
https://lore.kernel.org/all/20260907065129.269262-1-namjain@linux.microsoft.com/
* Move irq_retrigger setting to hv_init_dev_msi_info() in patch 1
  (Michael, Nam) 
* Add if-else fallback check in msi_set_affinity() in patch 3 (Michael)
* Break patch 3 into two separate patches, while *keeping review tags*.

Changes since v2:
https://lore.kernel.org/all/20260810090716.2325295-1-namjain@linux.microsoft.com/
* Add a backportable fix for Hyper-V root partition irqchip (Wei)
* Add a check for custom irq_retrigger implementations and add direct
  irq_chip_retrigger_hierarchy() calls as a fallback if it is not
  defined by a chip. (Sashiko, Michael)
* Removed local loop variable change, and continue using the irq_desc
  accessor function (Michael)
* Did not pick "Acked-by: Manivannan Sadhasivam" as it was on v1, and v3
  is a functionally different to some extent, specially patch 2.
  Requesting you to please review again.

Changes since v1:
https://lore.kernel.org/all/20260728135117.2888175-1-namjain@linux.microsoft.com/#t
* Added Review tags
* Adding minor clarification in commit msg of patch 2 (Shradha)

Original RFC: https://lore.kernel.org/all/87y0f3jhd6.ffs@fw13/

Naman Jain (4):
  x86/hyperv: Set irq_retrigger for root partition PCI/MSI irqchip
  x86/irq: Fall back to irq_chip_retrigger_hierarchy() in fixup_irqs()
  x86/irq: Fall back to irq_chip_retrigger_hierarchy() in
    msi_set_affinity()
  x86/irq, iommu/amd, x86/hyperv, PCI: Drop redundant irq_retrigger
    inits

 arch/x86/kernel/apic/io_apic.c      |  2 --
 arch/x86/kernel/apic/msi.c          | 12 ++++++++----
 arch/x86/kernel/hpet.c              |  1 -
 arch/x86/kernel/irq.c               | 19 +++++++++++--------
 drivers/iommu/amd/init.c            |  1 -
 drivers/pci/controller/pci-hyperv.c |  1 -
 6 files changed, 19 insertions(+), 17 deletions(-)


base-commit: 944a035ecca915ae947905dcfb03f2b9dc6d032c
-- 
2.43.0

[PATCH v4 1/4] x86/hyperv: Set irq_retrigger for root partition PCI/MSI irqchip

From: Naman Jain <hidden>
Date: 2026-09-09 06:45:11

The Hyper-V root partition vPCI MSI irqchip lost its irq_retrigger()
callback when it was converted to msi_create_parent_irq_domain(). The
callback was present on the original irqchip and was dropped during that
conversion.

On CPU hot-unplug fixup_irqs() migrates the interrupts which are affine to
the outgoing CPU to a new target. If an interrupt still has its pending bit
set in the outgoing CPU's IRR at that point, fixup_irqs() resends it on the
new target through the irqchip's irq_retrigger() callback. As the root
partition PCI/MSI chip no longer provides that callback, the pending
interrupt is silently dropped, which can result in lost interrupts, stalls
and "No irq handler for vector" messages during CPU hotplug.

Restore irq_chip_retrigger_hierarchy() as the irq_retrigger() callback for
the root partition PCI/MSI irqchip, so that a pending interrupt is resent
on its new target CPU via the parent x86 vector domain.

Fixes: 4691db0704ac ("x86/hyperv: Switch to msi_create_parent_irq_domain()")
Cc: stable@vger.kernel.org
Reviewed-by: Michael Kelley <redacted>
Signed-off-by: Naman Jain <redacted>
---
 arch/x86/hyperv/irqdomain.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index b3ad50a874dca..6d790636c8b95 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -316,6 +316,7 @@ static bool hv_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 		return false;
 
 	chip->flags |= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED;
+	chip->irq_retrigger = irq_chip_retrigger_hierarchy;
 
 	info->ops->msi_prepare = pci_msi_prepare;
 
-- 
2.43.0

[PATCH v4 2/4] x86/irq: Fall back to irq_chip_retrigger_hierarchy() in fixup_irqs()

From: Naman Jain <hidden>
Date: 2026-09-09 06:45:20

fixup_irqs() re-injects a pending interrupt on its new target CPU by
looking at the outermost domain chip and invoking its irq_retrigger()
callback directly. When the outermost chip does not implement
irq_retrigger(), the pending interrupt is silently dropped, which can
lead to lost interrupts on CPU hot-unplug.

Keep calling the outermost chip's irq_retrigger() when it is present,
but fall back to irq_chip_retrigger_hierarchy() otherwise, which walks
up the interrupt hierarchy until it finds a chip that implements
irq_retrigger().

While at it, use a scoped guard for desc->lock. VECTOR_RETRIGGERED is
now set only when the retrigger succeeds instead of unconditionally,
which is harmless today since apic_retrigger_irq() always returns 1.

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Shradha Gupta <redacted>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Michael Kelley <redacted>
Signed-off-by: Naman Jain <redacted>
---
 arch/x86/kernel/irq.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 30122f0b3af96..e0163f7ac7368 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -470,6 +470,7 @@ void fixup_irqs(void)
 	struct irq_desc *desc;
 	struct irq_data *data;
 	struct irq_chip *chip;
+	int ret;
 
 	irq_migrate_all_off_this_cpu();
 
@@ -490,21 +491,23 @@ void fixup_irqs(void)
 	 * nothing else will touch it.
 	 */
 	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		if (IS_ERR_OR_NULL(__this_cpu_read(vector_irq[vector])))
+		desc = __this_cpu_read(vector_irq[vector]);
+
+		if (IS_ERR_OR_NULL(desc))
 			continue;
 
 		if (is_vector_pending(vector)) {
-			desc = __this_cpu_read(vector_irq[vector]);
-
-			raw_spin_lock(&desc->lock);
+			guard(raw_spinlock)(&desc->lock);
 			data = irq_desc_get_irq_data(desc);
 			chip = irq_data_get_irq_chip(data);
-			if (chip->irq_retrigger) {
-				chip->irq_retrigger(data);
+			if (chip->irq_retrigger)
+				ret = chip->irq_retrigger(data);
+			else
+				ret = irq_chip_retrigger_hierarchy(data);
+			if (ret)
 				__this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED);
-			}
-			raw_spin_unlock(&desc->lock);
 		}
+
 		if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
 			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
 	}
-- 
2.43.0

[PATCH v4 3/4] x86/irq: Fall back to irq_chip_retrigger_hierarchy() in msi_set_affinity()

From: Naman Jain <hidden>
Date: 2026-09-09 06:45:29

msi_set_affinity() re-injects a pending interrupt on its new target by
looking at the outermost domain chip and invoking its irq_retrigger()
callback directly, without checking whether that callback is present.

Keep calling the outermost chip's irq_retrigger() when it is present,
but fall back to irq_chip_retrigger_hierarchy() otherwise, which walks
up the interrupt hierarchy until it finds a chip that implements
irq_retrigger().

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Shradha Gupta <redacted>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Naman Jain <redacted>
---
 arch/x86/kernel/apic/msi.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 66bc5d3e79db3..66647d51c0473 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -136,8 +136,14 @@ msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force)
 	 * underlying vector store. It's just checking the local APIC's
 	 * IRR.
 	 */
-	if (lapic_vector_set_in_irr(cfg->vector))
-		irq_data_get_irq_chip(irqd)->irq_retrigger(irqd);
+	if (lapic_vector_set_in_irr(cfg->vector)) {
+		struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+
+		if (chip->irq_retrigger)
+			chip->irq_retrigger(irqd);
+		else
+			irq_chip_retrigger_hierarchy(irqd);
+	}
 
 	return ret;
 }
-- 
2.43.0

[PATCH v4 4/4] x86/irq, iommu/amd, x86/hyperv, PCI: Drop redundant irq_retrigger inits

From: Naman Jain <hidden>
Date: 2026-09-09 06:45:39

With fixup_irqs(), msi_set_affinity() and the generic resend path
(try_retrigger()) now all falling back to irq_chip_retrigger_hierarchy(),
installing it as the irq_retrigger() callback on the outermost domain chips
is no longer required. The hierarchy walk reaches the x86 vector domain's
apic_retrigger_irq() for all of these stacked domain chips.

Remove the now redundant irq_retrigger() initializations from the outermost
domain interrupt chips, including the Hyper-V root partition PCI/MSI chip.

No functional change intended.

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Shradha Gupta <redacted>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Naman Jain <redacted>
---
 arch/x86/hyperv/irqdomain.c         | 1 -
 arch/x86/kernel/apic/io_apic.c      | 2 --
 arch/x86/kernel/apic/msi.c          | 2 --
 arch/x86/kernel/hpet.c              | 1 -
 drivers/iommu/amd/init.c            | 1 -
 drivers/pci/controller/pci-hyperv.c | 1 -
 6 files changed, 8 deletions(-)
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index 6d790636c8b95..b3ad50a874dca 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -316,7 +316,6 @@ static bool hv_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 		return false;
 
 	chip->flags |= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED;
-	chip->irq_retrigger = irq_chip_retrigger_hierarchy;
 
 	info->ops->msi_prepare = pci_msi_prepare;
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 7d7175d012288..18f49a251f23b 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1857,7 +1857,6 @@ static struct irq_chip ioapic_chip __read_mostly = {
 	.irq_ack		= irq_chip_ack_parent,
 	.irq_eoi		= ioapic_ack_level,
 	.irq_set_affinity	= ioapic_set_affinity,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_get_irqchip_state	= ioapic_irq_get_chip_state,
 	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED |
 				  IRQCHIP_AFFINITY_PRE_STARTUP,
@@ -1871,7 +1870,6 @@ static struct irq_chip ioapic_ir_chip __read_mostly = {
 	.irq_ack		= irq_chip_ack_parent,
 	.irq_eoi		= ioapic_ir_ack_level,
 	.irq_set_affinity	= ioapic_set_affinity,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_get_irqchip_state	= ioapic_irq_get_chip_state,
 	.flags			= IRQCHIP_SKIP_SET_WAKE |
 				  IRQCHIP_AFFINITY_PRE_STARTUP,
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 66647d51c0473..728d3bfefa85c 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -252,7 +252,6 @@ static bool x86_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
 	info->ops->msi_prepare		= x86_msi_prepare;
 
 	info->chip->irq_ack		= irq_chip_ack_parent;
-	info->chip->irq_retrigger	= irq_chip_retrigger_hierarchy;
 	info->chip->flags		|= IRQCHIP_SKIP_SET_WAKE |
 					   IRQCHIP_AFFINITY_PRE_STARTUP;
 
@@ -319,7 +318,6 @@ static struct irq_chip dmar_msi_controller = {
 	.irq_mask		= dmar_msi_mask,
 	.irq_ack		= irq_chip_ack_parent,
 	.irq_set_affinity	= msi_domain_set_affinity,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_compose_msi_msg	= dmar_msi_compose_msg,
 	.irq_write_msi_msg	= dmar_msi_write_msg,
 	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 8dc7b710e1250..2bb7a6f466af3 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -509,7 +509,6 @@ static struct irq_chip hpet_msi_controller __ro_after_init = {
 	.irq_mask = hpet_msi_mask,
 	.irq_ack = irq_chip_ack_parent,
 	.irq_set_affinity = msi_domain_set_affinity,
-	.irq_retrigger = irq_chip_retrigger_hierarchy,
 	.irq_write_msi_msg = hpet_msi_write_msg,
 	.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_AFFINITY_PRE_STARTUP,
 };
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 40726dfef2733..a19e1faf98750 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -2471,7 +2471,6 @@ static struct irq_chip intcapxt_controller = {
 	.irq_unmask		= intcapxt_unmask_irq,
 	.irq_mask		= intcapxt_mask_irq,
 	.irq_ack		= irq_chip_ack_parent,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_affinity       = intcapxt_set_affinity,
 	.irq_set_wake		= intcapxt_set_wake,
 	.flags			= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_MOVE_DEFERRED,
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 89816a2bd7cd3..cfc8fa403dad6 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -2119,7 +2119,6 @@ static bool hv_pcie_init_dev_msi_info(struct device *dev, struct irq_domain *dom
 	info->ops->msi_prepare = hv_msi_prepare;
 
 	chip->irq_set_affinity = irq_chip_set_affinity_parent;
-	chip->irq_retrigger = irq_chip_retrigger_hierarchy;
 
 	if (IS_ENABLED(CONFIG_X86))
 		chip->flags |= IRQCHIP_MOVE_DEFERRED;
-- 
2.43.0

Re: [PATCH v4 3/4] x86/irq: Fall back to irq_chip_retrigger_hierarchy() in msi_set_affinity()

From: sashiko-bot@kernel.org
Date: 2026-09-09 06:51:37

msi_set_affinity() re-injects a pending interrupt on its new target by
looking at the outermost domain chip and invoking its irq_retrigger()
callback directly, without checking whether that callback is present.

Keep calling the outermost chip's irq_retrigger() when it is present,
but fall back to irq_chip_retrigger_hierarchy() otherwise, which walks
up the interrupt hierarchy until it finds a chip that implements
irq_retrigger().

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Shradha Gupta <redacted>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Naman Jain <redacted>
Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909064448.1004-1-namjain@linux.microsoft.com?part=3

Re: [PATCH v4 4/4] x86/irq, iommu/amd, x86/hyperv, PCI: Drop redundant irq_retrigger inits

From: sashiko-bot@kernel.org
Date: 2026-09-09 06:52:29

With fixup_irqs(), msi_set_affinity() and the generic resend path
(try_retrigger()) now all falling back to irq_chip_retrigger_hierarchy(),
installing it as the irq_retrigger() callback on the outermost domain chips
is no longer required. The hierarchy walk reaches the x86 vector domain's
apic_retrigger_irq() for all of these stacked domain chips.

Remove the now redundant irq_retrigger() initializations from the outermost
domain interrupt chips, including the Hyper-V root partition PCI/MSI chip.

No functional change intended.

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Shradha Gupta <redacted>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Naman Jain <redacted>
Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909064448.1004-1-namjain@linux.microsoft.com?part=4

Re: [PATCH v4 1/4] x86/hyperv: Set irq_retrigger for root partition PCI/MSI irqchip

From: sashiko-bot@kernel.org
Date: 2026-09-09 06:53:10

The Hyper-V root partition vPCI MSI irqchip lost its irq_retrigger()
callback when it was converted to msi_create_parent_irq_domain(). The
callback was present on the original irqchip and was dropped during that
conversion.

On CPU hot-unplug fixup_irqs() migrates the interrupts which are affine to
the outgoing CPU to a new target. If an interrupt still has its pending bit
set in the outgoing CPU's IRR at that point, fixup_irqs() resends it on the
new target through the irqchip's irq_retrigger() callback. As the root
partition PCI/MSI chip no longer provides that callback, the pending
interrupt is silently dropped, which can result in lost interrupts, stalls
and "No irq handler for vector" messages during CPU hotplug.

Restore irq_chip_retrigger_hierarchy() as the irq_retrigger() callback for
the root partition PCI/MSI irqchip, so that a pending interrupt is resent
on its new target CPU via the parent x86 vector domain.

Fixes: 4691db0704ac ("x86/hyperv: Switch to msi_create_parent_irq_domain()")
Cc: stable@vger.kernel.org
Reviewed-by: Michael Kelley <redacted>
Signed-off-by: Naman Jain <redacted>
Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909064448.1004-1-namjain@linux.microsoft.com?part=1

Re: [PATCH v4 2/4] x86/irq: Fall back to irq_chip_retrigger_hierarchy() in fixup_irqs()

From: sashiko-bot@kernel.org
Date: 2026-09-09 06:54:25

fixup_irqs() re-injects a pending interrupt on its new target CPU by
looking at the outermost domain chip and invoking its irq_retrigger()
callback directly. When the outermost chip does not implement
irq_retrigger(), the pending interrupt is silently dropped, which can
lead to lost interrupts on CPU hot-unplug.

Keep calling the outermost chip's irq_retrigger() when it is present,
but fall back to irq_chip_retrigger_hierarchy() otherwise, which walks
up the interrupt hierarchy until it finds a chip that implements
irq_retrigger().

While at it, use a scoped guard for desc->lock. VECTOR_RETRIGGERED is
now set only when the retrigger succeeds instead of unconditionally,
which is harmless today since apic_retrigger_irq() always returns 1.

Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Shradha Gupta <redacted>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Michael Kelley <redacted>
Signed-off-by: Naman Jain <redacted>
Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909064448.1004-1-namjain@linux.microsoft.com?part=2

Re: [PATCH v4 1/4] x86/hyperv: Set irq_retrigger for root partition PCI/MSI irqchip

From: Nam Cao <hidden>
Date: 2026-09-10 07:11:35

Naman Jain [off-list ref] writes:
The Hyper-V root partition vPCI MSI irqchip lost its irq_retrigger()
callback when it was converted to msi_create_parent_irq_domain(). The
callback was present on the original irqchip and was dropped during that
conversion.

On CPU hot-unplug fixup_irqs() migrates the interrupts which are affine to
the outgoing CPU to a new target. If an interrupt still has its pending bit
set in the outgoing CPU's IRR at that point, fixup_irqs() resends it on the
new target through the irqchip's irq_retrigger() callback. As the root
partition PCI/MSI chip no longer provides that callback, the pending
interrupt is silently dropped, which can result in lost interrupts, stalls
and "No irq handler for vector" messages during CPU hotplug.

Restore irq_chip_retrigger_hierarchy() as the irq_retrigger() callback for
the root partition PCI/MSI irqchip, so that a pending interrupt is resent
on its new target CPU via the parent x86 vector domain.

Fixes: 4691db0704ac ("x86/hyperv: Switch to msi_create_parent_irq_domain()")
Cc: stable@vger.kernel.org
Reviewed-by: Michael Kelley <redacted>
Signed-off-by: Naman Jain <redacted>
Reviewed-by: Nam Cao <redacted>

Re: [PATCH v4 0/4] x86/irq: Fix lost interrupts on CPU hot-unplug

From: Wei Liu <wei.liu@kernel.org>
Date: 2026-09-13 22:48:44

On Wed, Sep 09, 2026 at 06:44:44AM +0000, Naman Jain wrote:
On CPU hot-unplug, fixup_irqs() re-injects interrupts that are still
pending in the outgoing CPU's IRR via the irqchip's irq_retrigger()
callback. The Hyper-V root partition PCI/MSI irqchip lost that callback
when it was converted to msi_create_parent_irq_domain(), so such a
pending interrupt is silently dropped, leading to lost interrupts, stalls
and "No irq handler for vector" messages.

Patch 1 is the minimal, backportable fix (Fixes:/Cc: stable) that restores
irq_chip_retrigger_hierarchy() on the Hyper-V root partition PCI/MSI chip.
The equivalent guest pci-hyperv.c fix from the previous version is already
merged, so it is dropped here.

Patch 2 then switches fixup_irqs() to have a fallback call to
irq_chip_retrigger_hierarchy() directly, if a chip does not define
irq_retrigger callback.

Patch 3 makes a similar change in msi_set_affinity()

Patch 4 then drops the now-redundant irq_retrigger() initializations.
This way, patch 2-4 do not need to be backported.

Changes since v3:
https://lore.kernel.org/all/20260907065129.269262-1-namjain@linux.microsoft.com/
* Move irq_retrigger setting to hv_init_dev_msi_info() in patch 1
  (Michael, Nam) 
* Add if-else fallback check in msi_set_affinity() in patch 3 (Michael)
* Break patch 3 into two separate patches, while *keeping review tags*.

Changes since v2:
https://lore.kernel.org/all/20260810090716.2325295-1-namjain@linux.microsoft.com/
* Add a backportable fix for Hyper-V root partition irqchip (Wei)
* Add a check for custom irq_retrigger implementations and add direct
  irq_chip_retrigger_hierarchy() calls as a fallback if it is not
  defined by a chip. (Sashiko, Michael)
* Removed local loop variable change, and continue using the irq_desc
  accessor function (Michael)
* Did not pick "Acked-by: Manivannan Sadhasivam" as it was on v1, and v3
  is a functionally different to some extent, specially patch 2.
  Requesting you to please review again.

Changes since v1:
https://lore.kernel.org/all/20260728135117.2888175-1-namjain@linux.microsoft.com/#t
* Added Review tags
* Adding minor clarification in commit msg of patch 2 (Shradha)

Original RFC: https://lore.kernel.org/all/87y0f3jhd6.ffs@fw13/

Naman Jain (4):
  x86/hyperv: Set irq_retrigger for root partition PCI/MSI irqchip
  x86/irq: Fall back to irq_chip_retrigger_hierarchy() in fixup_irqs()
  x86/irq: Fall back to irq_chip_retrigger_hierarchy() in
    msi_set_affinity()
  x86/irq, iommu/amd, x86/hyperv, PCI: Drop redundant irq_retrigger
    inits
I checked linux-next next-20260911. This series has not been applied.

This patch series needs to be applied in one go, since patch 4 depends
on patch 1.

I'm fine with carrying this through the hyperv-fixes tree, or let it go
through the x86 tree. Just let me know.

Thanks,
Wei

Re: [PATCH v4 0/4] x86/irq: Fix lost interrupts on CPU hot-unplug

From: Naman Jain <hidden>
Date: 2026-09-14 10:30:53


On 9/14/2026 4:18 AM, Wei Liu wrote:
On Wed, Sep 09, 2026 at 06:44:44AM +0000, Naman Jain wrote:
quoted
On CPU hot-unplug, fixup_irqs() re-injects interrupts that are still
pending in the outgoing CPU's IRR via the irqchip's irq_retrigger()
callback. The Hyper-V root partition PCI/MSI irqchip lost that callback
when it was converted to msi_create_parent_irq_domain(), so such a
pending interrupt is silently dropped, leading to lost interrupts, stalls
and "No irq handler for vector" messages.

Patch 1 is the minimal, backportable fix (Fixes:/Cc: stable) that restores
irq_chip_retrigger_hierarchy() on the Hyper-V root partition PCI/MSI chip.
The equivalent guest pci-hyperv.c fix from the previous version is already
merged, so it is dropped here.

Patch 2 then switches fixup_irqs() to have a fallback call to
irq_chip_retrigger_hierarchy() directly, if a chip does not define
irq_retrigger callback.

Patch 3 makes a similar change in msi_set_affinity()

Patch 4 then drops the now-redundant irq_retrigger() initializations.
This way, patch 2-4 do not need to be backported.

Changes since v3:
https://lore.kernel.org/all/20260907065129.269262-1-namjain@linux.microsoft.com/
* Move irq_retrigger setting to hv_init_dev_msi_info() in patch 1
   (Michael, Nam)
* Add if-else fallback check in msi_set_affinity() in patch 3 (Michael)
* Break patch 3 into two separate patches, while *keeping review tags*.

Changes since v2:
https://lore.kernel.org/all/20260810090716.2325295-1-namjain@linux.microsoft.com/
* Add a backportable fix for Hyper-V root partition irqchip (Wei)
* Add a check for custom irq_retrigger implementations and add direct
   irq_chip_retrigger_hierarchy() calls as a fallback if it is not
   defined by a chip. (Sashiko, Michael)
* Removed local loop variable change, and continue using the irq_desc
   accessor function (Michael)
* Did not pick "Acked-by: Manivannan Sadhasivam" as it was on v1, and v3
   is a functionally different to some extent, specially patch 2.
   Requesting you to please review again.

Changes since v1:
https://lore.kernel.org/all/20260728135117.2888175-1-namjain@linux.microsoft.com/#t
* Added Review tags
* Adding minor clarification in commit msg of patch 2 (Shradha)

Original RFC: https://lore.kernel.org/all/87y0f3jhd6.ffs@fw13/

Naman Jain (4):
   x86/hyperv: Set irq_retrigger for root partition PCI/MSI irqchip
   x86/irq: Fall back to irq_chip_retrigger_hierarchy() in fixup_irqs()
   x86/irq: Fall back to irq_chip_retrigger_hierarchy() in
     msi_set_affinity()
   x86/irq, iommu/amd, x86/hyperv, PCI: Drop redundant irq_retrigger
     inits
I checked linux-next next-20260911. This series has not been applied.

This patch series needs to be applied in one go, since patch 4 depends
on patch 1.

I'm fine with carrying this through the hyperv-fixes tree, or let it go
through the x86 tree. Just let me know.

Thanks,
Wei
Hi Wei,
There was some active discussion happening on v2 of this series which 
has been concluded now. It will bring minor changes. I'll send v5 now, 
and you or Thomas can pick those changes as per your convenience.

Regards,
Naman

Ref: https://lore.kernel.org/all/87y0d6xpan.ffs@fw13/
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help