Skip to content

Commit

Permalink
Merge tag 'irq-core-2023-02-20' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "Updates for the interrupt subsystem:

  Core:

   - Move the interrupt affinity spreading mechanism into lib/group_cpus
     so it can be used for similar spreading requirements, e.g. in the
     block multi-queue code

     This also contains a first usecase in the block multi-queue code
     which Jens asked to take along with the librarization

   - Improve irqdomain locking to close a number race conditions which
     can be observed with massive parallel device driver probing

   - Enforce and document the semantics of disable_irq() which cannot be
     invoked safely from non-sleepable context

   - Move the IPI multiplexing code from the Apple AIC driver into the
     core, so it can be reused by RISCV

  Drivers:

   - Plug OF node refcounting leaks in various drivers

   - Correctly mark level triggered interrupts in the Broadcom L2
     drivers

   - The usual small fixes and improvements

   - No new drivers for the record!"

* tag 'irq-core-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (42 commits)
  irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts
  irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts
  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
  ...
  • Loading branch information
torvalds committed Feb 21, 2023
2 parents 560b803 + 6f3ee0e commit 9e58df9
Show file tree
Hide file tree
Showing 37 changed files with 1,020 additions and 830 deletions.
4 changes: 2 additions & 2 deletions Documentation/kernel-hacking/locking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1277,11 +1277,11 @@ Manfred Spraul points out that you can still do this, even if the data
is very occasionally accessed in user context or softirqs/tasklets. The
irq handler doesn't use a lock, and all other accesses are done as so::

spin_lock(&lock);
mutex_lock(&lock);
disable_irq(irq);
...
enable_irq(irq);
spin_unlock(&lock);
mutex_unlock(&lock);

The disable_irq() prevents the irq handler from running
(and waits for it to finish if it's currently running on other CPUs).
Expand Down
4 changes: 2 additions & 2 deletions Documentation/translations/it_IT/kernel-hacking/locking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1307,11 +1307,11 @@ se i dati vengono occasionalmente utilizzati da un contesto utente o
da un'interruzione software. Il gestore d'interruzione non utilizza alcun
*lock*, e tutti gli altri accessi verranno fatti così::

spin_lock(&lock);
mutex_lock(&lock);
disable_irq(irq);
...
enable_irq(irq);
spin_unlock(&lock);
mutex_unlock(&lock);

La funzione disable_irq() impedisce al gestore d'interruzioni
d'essere eseguito (e aspetta che finisca nel caso fosse in esecuzione su
Expand Down
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -10777,6 +10777,8 @@ L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
F: kernel/irq/
F: include/linux/group_cpus.h
F: lib/group_cpus.c

IRQCHIP DRIVERS
M: Thomas Gleixner <tglx@linutronix.de>
Expand Down
7 changes: 2 additions & 5 deletions arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2364,18 +2364,15 @@ static int mp_irqdomain_create(int ioapic)
return -ENODEV;
}

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

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)
irq_domain_free_fwnode(fn);
return -ENOMEM;
}

ip->irqdomain->parent = parent;

if (cfg->type == IOAPIC_DOMAIN_LEGACY ||
cfg->type == IOAPIC_DOMAIN_STRICT)
ioapic_dynirq_base = max(ioapic_dynirq_base,
Expand Down
7 changes: 3 additions & 4 deletions arch/x86/platform/uv/uv_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
63 changes: 13 additions & 50 deletions block/blk-mq-cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,66 +10,29 @@
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/cpu.h>
#include <linux/group_cpus.h>

#include <linux/blk-mq.h>
#include "blk.h"
#include "blk-mq.h"

static int queue_index(struct blk_mq_queue_map *qmap,
unsigned int nr_queues, const int q)
{
return qmap->queue_offset + (q % nr_queues);
}

static int get_first_sibling(unsigned int cpu)
{
unsigned int ret;

ret = cpumask_first(topology_sibling_cpumask(cpu));
if (ret < nr_cpu_ids)
return ret;

return cpu;
}

void blk_mq_map_queues(struct blk_mq_queue_map *qmap)
{
unsigned int *map = qmap->mq_map;
unsigned int nr_queues = qmap->nr_queues;
unsigned int cpu, first_sibling, q = 0;

for_each_possible_cpu(cpu)
map[cpu] = -1;

/*
* Spread queues among present CPUs first for minimizing
* count of dead queues which are mapped by all un-present CPUs
*/
for_each_present_cpu(cpu) {
if (q >= nr_queues)
break;
map[cpu] = queue_index(qmap, nr_queues, q++);
const struct cpumask *masks;
unsigned int queue, cpu;

masks = group_cpus_evenly(qmap->nr_queues);
if (!masks) {
for_each_possible_cpu(cpu)
qmap->mq_map[cpu] = qmap->queue_offset;
return;
}

for_each_possible_cpu(cpu) {
if (map[cpu] != -1)
continue;
/*
* First do sequential mapping between CPUs and queues.
* In case we still have CPUs to map, and we have some number of
* threads per cores then map sibling threads to the same queue
* for performance optimizations.
*/
if (q < nr_queues) {
map[cpu] = queue_index(qmap, nr_queues, q++);
} else {
first_sibling = get_first_sibling(cpu);
if (first_sibling == cpu)
map[cpu] = queue_index(qmap, nr_queues, q++);
else
map[cpu] = map[first_sibling];
}
for (queue = 0; queue < qmap->nr_queues; queue++) {
for_each_cpu(cpu, &masks[queue])
qmap->mq_map[cpu] = qmap->queue_offset + queue;
}
kfree(masks);
}
EXPORT_SYMBOL_GPL(blk_mq_map_queues);

Expand Down
3 changes: 2 additions & 1 deletion drivers/irqchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ config LS_EXTIRQ

config LS_SCFG_MSI
def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE
depends on PCI && PCI_MSI
depends on PCI_MSI

config PARTITION_PERCPU
bool
Expand Down Expand Up @@ -653,6 +653,7 @@ config APPLE_AIC
bool "Apple Interrupt Controller (AIC)"
depends on ARM64
depends on ARCH_APPLE || COMPILE_TEST
select GENERIC_IRQ_IPI_MUX
help
Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
such as the M1.
Expand Down
9 changes: 4 additions & 5 deletions drivers/irqchip/irq-alpine-msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,20 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv,
}

gic_domain = irq_find_host(gic_node);
of_node_put(gic_node);
if (!gic_domain) {
pr_err("Failed to find the GIC domain\n");
return -ENXIO;
}

middle_domain = irq_domain_add_tree(NULL,
&alpine_msix_middle_domain_ops,
priv);
middle_domain = irq_domain_add_hierarchy(gic_domain, 0, 0, NULL,
&alpine_msix_middle_domain_ops,
priv);
if (!middle_domain) {
pr_err("Failed to create the MSIX middle domain\n");
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);
Expand Down
Loading

0 comments on commit 9e58df9

Please sign in to comment.