Commit 7135b35f authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch irq/irqdomain-locking into irq/irqchip-next



* irq/irqdomain-locking:
  : .
  : irqdomain locking overhaul courtesy of Johan Hovold.
  :
  : From the cover letter:
  :
  : "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 series fixes this mapping race and reworks the irqdomain locking so
  : that in the end the global irq_domain_mutex is only used for managing
  : the likewise global irq_domain_list, while domain operations (e.g. IRQ
  : allocations) use per-domain (hierarchy) locking."
  : .
  irqdomain: Switch to per-domain locking
  irqchip/mvebu-odmi: Use irq_domain_create_hierarchy()
  irqchip/loongson-pch-msi: Use irq_domain_create_hierarchy()
  irqchip/gic-v3-mbi: Use irq_domain_create_hierarchy()
  irqchip/gic-v3-its: Use irq_domain_create_hierarchy()
  irqchip/gic-v2m: Use irq_domain_create_hierarchy()
  irqchip/alpine-msi: Use irq_domain_add_hierarchy()
  x86/uv: Use irq_domain_create_hierarchy()
  x86/ioapic: Use irq_domain_create_hierarchy()
  irqdomain: Clean up irq_domain_push/pop_irq()
  irqdomain: Drop leftover brackets
  irqdomain: Drop dead domain-name assignment
  irqdomain: Drop revmap mutex
  irqdomain: Fix domain registration race
  irqdomain: Fix mapping-creation race
  irqdomain: Refactor __irq_domain_alloc_irqs()
  irqdomain: Look for existing mapping only once
  irqdomain: Drop bogus fwspec-mapping error handling
  irqdomain: Fix disassociation race
  irqdomain: Fix association race

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents df2d85d0 9dbb8e34
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -2364,9 +2364,8 @@ static int mp_irqdomain_create(int ioapic)
		return -ENODEV;
	}

	ip->irqdomain = irq_domain_create_linear(fn, hwirqs, cfg->ops,
	ip->irqdomain = irq_domain_create_hierarchy(parent, 0, hwirqs, fn, cfg->ops,
						    (void *)(long)ioapic);

	if (!ip->irqdomain) {
		/* Release fw handle if it was allocated above */
		if (!cfg->dev)
@@ -2374,8 +2373,6 @@ static int mp_irqdomain_create(int ioapic)
		return -ENOMEM;
	}

	ip->irqdomain->parent = parent;

	if (cfg->type == IOAPIC_DOMAIN_LEGACY ||
	    cfg->type == IOAPIC_DOMAIN_STRICT)
		ioapic_dynirq_base = max(ioapic_dynirq_base,
+3 −4
Original line number Diff line number Diff line
@@ -166,10 +166,9 @@ static struct irq_domain *uv_get_irq_domain(void)
	if (!fn)
		goto out;

	uv_domain = irq_domain_create_tree(fn, &uv_domain_ops, NULL);
	if (uv_domain)
		uv_domain->parent = x86_vector_domain;
	else
	uv_domain = irq_domain_create_hierarchy(x86_vector_domain, 0, 0, fn,
						&uv_domain_ops, NULL);
	if (!uv_domain)
		irq_domain_free_fwnode(fn);
out:
	mutex_unlock(&uv_lock);
+3 −5
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv,
		return -ENXIO;
	}

	middle_domain = irq_domain_add_tree(NULL,
	middle_domain = irq_domain_add_hierarchy(gic_domain, 0, 0, NULL,
						 &alpine_msix_middle_domain_ops,
						 priv);
	if (!middle_domain) {
@@ -213,8 +213,6 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv,
		return -ENOMEM;
	}

	middle_domain->parent = gic_domain;

	msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node),
					       &alpine_msix_domain_info,
					       middle_domain);
+2 −3
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ static __init int gicv2m_allocate_domains(struct irq_domain *parent)
	if (!v2m)
		return 0;

	inner_domain = irq_domain_create_tree(v2m->fwnode,
	inner_domain = irq_domain_create_hierarchy(parent, 0, 0, v2m->fwnode,
						   &gicv2m_domain_ops, v2m);
	if (!inner_domain) {
		pr_err("Failed to create GICv2m domain\n");
@@ -295,7 +295,6 @@ static __init int gicv2m_allocate_domains(struct irq_domain *parent)
	}

	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
	inner_domain->parent = parent;
	pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
					       &gicv2m_msi_domain_info,
					       inner_domain);
+7 −6
Original line number Diff line number Diff line
@@ -4909,18 +4909,19 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
	if (!info)
		return -ENOMEM;

	inner_domain = irq_domain_create_tree(handle, &its_domain_ops, its);
	info->ops = &its_msi_domain_ops;
	info->data = its;

	inner_domain = irq_domain_create_hierarchy(its_parent,
						   its->msi_domain_flags, 0,
						   handle, &its_domain_ops,
						   info);
	if (!inner_domain) {
		kfree(info);
		return -ENOMEM;
	}

	inner_domain->parent = its_parent;
	irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
	inner_domain->flags |= its->msi_domain_flags;
	info->ops = &its_msi_domain_ops;
	info->data = its;
	inner_domain->host_data = info;

	return 0;
}
Loading