Skip to content

Commit da5dd9e

Browse files
committed
genirq/msi: Handle reactivation only on success
When analyzing the fallout of the x86 vector allocation rework it turned out that the error handling in msi_domain_alloc_irqs() is broken. If MSI_FLAG_MUST_REACTIVATE is set for a MSI domain then it clears the activation flag for a successfully initialized msi descriptor. If a subsequent initialization fails then the error handling code path does not deactivate the interrupt because the activation flag got cleared. Move the clearing of the activation flag outside of the initialization loop so that an eventual failure can be cleaned up correctly. Fixes: 22d0b12 ("genirq/irqdomain: Add force reactivation flag to irq domains") Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Alexandru Chirvasitu <achirvasub@gmail.com> Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Dou Liyang <douly.fnst@cn.fujitsu.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Maciej W. Rozycki <macro@linux-mips.org> Cc: Mikael Pettersson <mikpelinux@gmail.com> Cc: Josh Poulson <jopoulso@microsoft.com> Cc: Mihai Costache <v-micos@microsoft.com> Cc: Stephen Hemminger <sthemmin@microsoft.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: linux-pci@vger.kernel.org Cc: Haiyang Zhang <haiyangz@microsoft.com> Cc: Dexuan Cui <decui@microsoft.com> Cc: Simon Xiao <sixiao@microsoft.com> Cc: Saeed Mahameed <saeedm@mellanox.com> Cc: Jork Loeser <Jork.Loeser@microsoft.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: devel@linuxdriverproject.org Cc: KY Srinivasan <kys@microsoft.com> Cc: Alan Cox <alan@linux.intel.com> Cc: Sakari Ailus <sakari.ailus@intel.com>, Cc: linux-media@vger.kernel.org
1 parent 8880c13 commit da5dd9e

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

kernel/irq/msi.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,13 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
339339
return ret;
340340
}
341341

342+
static bool msi_check_reservation_mode(struct msi_domain_info *info)
343+
{
344+
if (!(info->flags & MSI_FLAG_MUST_REACTIVATE))
345+
return false;
346+
return true;
347+
}
348+
342349
/**
343350
* msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain
344351
* @domain: The domain to allocate from
@@ -353,9 +360,11 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
353360
{
354361
struct msi_domain_info *info = domain->host_data;
355362
struct msi_domain_ops *ops = info->ops;
356-
msi_alloc_info_t arg;
363+
struct irq_data *irq_data;
357364
struct msi_desc *desc;
365+
msi_alloc_info_t arg;
358366
int i, ret, virq;
367+
bool can_reserve;
359368

360369
ret = msi_domain_prepare_irqs(domain, dev, nvec, &arg);
361370
if (ret)
@@ -385,6 +394,8 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
385394
if (ops->msi_finish)
386395
ops->msi_finish(&arg, 0);
387396

397+
can_reserve = msi_check_reservation_mode(info);
398+
388399
for_each_msi_entry(desc, dev) {
389400
virq = desc->irq;
390401
if (desc->nvec_used == 1)
@@ -397,15 +408,23 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
397408
* the MSI entries before the PCI layer enables MSI in the
398409
* card. Otherwise the card latches a random msi message.
399410
*/
400-
if (info->flags & MSI_FLAG_ACTIVATE_EARLY) {
401-
struct irq_data *irq_data;
411+
if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY))
412+
continue;
402413

414+
irq_data = irq_domain_get_irq_data(domain, desc->irq);
415+
ret = irq_domain_activate_irq(irq_data, true);
416+
if (ret)
417+
goto cleanup;
418+
}
419+
420+
/*
421+
* If these interrupts use reservation mode, clear the activated bit
422+
* so request_irq() will assign the final vector.
423+
*/
424+
if (can_reserve) {
425+
for_each_msi_entry(desc, dev) {
403426
irq_data = irq_domain_get_irq_data(domain, desc->irq);
404-
ret = irq_domain_activate_irq(irq_data, true);
405-
if (ret)
406-
goto cleanup;
407-
if (info->flags & MSI_FLAG_MUST_REACTIVATE)
408-
irqd_clr_activated(irq_data);
427+
irqd_clr_activated(irq_data);
409428
}
410429
}
411430
return 0;

0 commit comments

Comments
 (0)