[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <87sfg8kfh4.ffs@tglx>
Date: Tue, 17 Jan 2023 22:39:51 +0100
From: Thomas Gleixner <tglx@...utronix.de>
To: Johan Hovold <johan+linaro@...nel.org>,
Marc Zyngier <maz@...nel.org>
Cc: x86@...nel.org, platform-driver-x86@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org, linux-mips@...r.kernel.org,
linux-kernel@...r.kernel.org,
Johan Hovold <johan+linaro@...nel.org>,
Dmitry Torokhov <dtor@...omium.org>,
Jon Hunter <jonathanh@...dia.com>,
Hsin-Yi Wang <hsinyi@...omium.org>,
Mark-PK Tsai <mark-pk.tsai@...iatek.com>
Subject: Re: [PATCH v4 09/19] irqdomain: Fix mapping-creation race
On Mon, Jan 16 2023 at 14:50, Johan Hovold wrote:
> Parallel probing (e.g. due to asynchronous probing) of devices that share
> interrupts can currently result in two mappings for the same hardware
> interrupt to be created.
This lacks an explanation why this can happen.
> @@ -802,6 +811,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
> if (WARN_ON(type & ~IRQ_TYPE_SENSE_MASK))
> type &= IRQ_TYPE_SENSE_MASK;
>
> + mutex_lock(&irq_domain_mutex);
> +
> /*
> * If we've already configured this interrupt,
> * don't do it again, or hell will break loose.
> @@ -814,7 +825,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
> * interrupt number.
> */
> if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq))
> - return virq;
> + goto out;
>
> /*
> * If the trigger type has not been set yet, then set
> @@ -823,36 +834,43 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
> if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) {
> irq_data = irq_get_irq_data(virq);
> if (!irq_data)
> - return 0;
> + goto err;
>
> irqd_set_trigger_type(irq_data, type);
> - return virq;
> + goto out;
> }
>
> pr_warn("type mismatch, failed to map hwirq-%lu for %s!\n",
> hwirq, of_node_full_name(to_of_node(fwspec->fwnode)));
> - return 0;
> + goto err;
> }
>
> if (irq_domain_is_hierarchy(domain)) {
> - virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, fwspec);
> + virq = ___irq_domain_alloc_irqs(domain, -1, 1, NUMA_NO_NODE,
> + fwspec, false, NULL);
> if (virq <= 0)
> - return 0;
> + goto err;
> } else {
> /* Create mapping */
> virq = __irq_create_mapping_affinity(domain, hwirq, NULL);
> if (!virq)
> - return virq;
> + goto err;
> }
>
> irq_data = irq_get_irq_data(virq);
> if (WARN_ON(!irq_data))
> - return 0;
> + goto err;
>
> /* Store trigger type */
> irqd_set_trigger_type(irq_data, type);
> +out:
> + mutex_unlock(&irq_domain_mutex);
>
> return virq;
> +err:
> + mutex_unlock(&irq_domain_mutex);
> +
> + return 0;
> }
> EXPORT_SYMBOL_GPL(irq_create_fwspec_mapping);
You can spare that goto churn by renaming the existing function to
irq_create_fwspec_mapping_locked() and invoked that guarded by the
mutex, no?
Thanks,
tglx
Powered by blists - more mailing lists