Skip to content

Commit

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

Pull interrupt subsystem updates from Thomas Gleixner:

 - Consolidate the machine_kexec_mask_interrupts() by providing a
   generic implementation and replacing the copy & pasta orgy in the
   relevant architectures.

 - Prevent unconditional operations on interrupt chips during kexec
   shutdown, which can trigger warnings in certain cases when the
   underlying interrupt has been shut down before.

 - Make the enforcement of interrupt handling in interrupt context
   unconditionally available, so that it actually works for non x86
   related interrupt chips. The earlier enablement for ARM GIC chips set
   the required chip flag, but did not notice that the check was hidden
   behind a config switch which is not selected by ARM[64].

 - Decrapify the handling of deferred interrupt affinity setting.

   Some interrupt chips require that affinity changes are made from the
   context of handling an interrupt to avoid certain race conditions.
   For x86 this was the default, but with interrupt remapping this
   requirement was lifted and a flag was introduced which tells the core
   code that affinity changes can be done in any context. Unrestricted
   affinity changes are the default for the majority of interrupt chips.

   RISCV has the requirement to add the deferred mode to one of it's
   interrupt controllers, but with the original implementation this
   would require to add the any context flag to all other RISC-V
   interrupt chips. That's backwards, so reverse the logic and require
   that chips, which need the deferred mode have to be marked
   accordingly. That avoids chasing the 'sane' chips and marking them.

 - Add multi-node support to the Loongarch AVEC interrupt controller
   driver.

 - The usual tiny cleanups, fixes and improvements all over the place.

* tag 'irq-core-2025-01-21' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  genirq/generic_chip: Export irq_gc_mask_disable_and_ack_set()
  genirq/timings: Add kernel-doc for a function parameter
  genirq: Remove IRQ_MOVE_PCNTXT and related code
  x86/apic: Convert to IRQCHIP_MOVE_DEFERRED
  genirq: Provide IRQCHIP_MOVE_DEFERRED
  hexagon: Remove GENERIC_PENDING_IRQ leftover
  ARC: Remove GENERIC_PENDING_IRQ
  genirq: Remove handle_enforce_irqctx() wrapper
  genirq: Make handle_enforce_irqctx() unconditionally available
  irqchip/loongarch-avec: Add multi-nodes topology support
  irqchip/ts4800: Replace seq_printf() by seq_puts()
  irqchip/ti-sci-inta : Add module build support
  irqchip/ti-sci-intr: Add module build support
  irqchip/irq-brcmstb-l2: Replace brcmstb_l2_mask_and_ack() by generic function
  irqchip: keystone: Use syscon_regmap_lookup_by_phandle_args
  genirq/kexec: Prevent redundant IRQ masking by checking state before shutdown
  kexec: Consolidate machine_kexec_mask_interrupts() implementation
  genirq: Reuse irq_thread_fn() for forced thread case
  genirq: Move irq_thread_fn() further up in the code
  • Loading branch information
Linus Torvalds committed Jan 21, 2025
2 parents f200c31 + a4b3990 commit 4c55116
Show file tree
Hide file tree
Showing 41 changed files with 107 additions and 229 deletions.
1 change: 0 additions & 1 deletion arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ config ARC
# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
select GENERIC_PENDING_IRQ if SMP
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select GENERIC_IOREMAP
Expand Down
2 changes: 0 additions & 2 deletions arch/arc/kernel/mcip.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,6 @@ static void idu_cascade_isr(struct irq_desc *desc)
static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq)
{
irq_set_chip_and_handler(virq, &idu_irq_chip, handle_level_irq);
irq_set_status_flags(virq, IRQ_MOVE_PCNTXT);

return 0;
}

Expand Down
23 changes: 0 additions & 23 deletions arch/arm/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
cpus_stopped = 1;
}

static void machine_kexec_mask_interrupts(void)
{
unsigned int i;
struct irq_desc *desc;

for_each_irq_desc(i, desc) {
struct irq_chip *chip;

chip = irq_desc_get_chip(desc);
if (!chip)
continue;

if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);

if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);

if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
chip->irq_disable(&desc->irq_data);
}
}

void machine_crash_shutdown(struct pt_regs *regs)
{
local_irq_disable();
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ config ARM64
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IOREMAP
select GENERIC_IRQ_IPI
select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
Expand Down
2 changes: 0 additions & 2 deletions arch/arm64/Kconfig.platforms
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ config ARCH_K3
select SOC_TI
select TI_MESSAGE_MANAGER
select TI_SCI_PROTOCOL
select TI_SCI_INTR_IRQCHIP
select TI_SCI_INTA_IRQCHIP
select TI_K3_SOCINFO
help
This enables support for Texas Instruments' K3 multicore SoC
Expand Down
31 changes: 0 additions & 31 deletions arch/arm64/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
BUG(); /* Should never get here. */
}

static void machine_kexec_mask_interrupts(void)
{
unsigned int i;
struct irq_desc *desc;

for_each_irq_desc(i, desc) {
struct irq_chip *chip;
int ret;

chip = irq_desc_get_chip(desc);
if (!chip)
continue;

/*
* First try to remove the active state. If this
* fails, try to EOI the interrupt.
*/
ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);

if (ret && irqd_irq_inprogress(&desc->irq_data) &&
chip->irq_eoi)
chip->irq_eoi(&desc->irq_data);

if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);

if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
chip->irq_disable(&desc->irq_data);
}
}

/**
* machine_crash_shutdown - shutdown non-crashing cpus and save registers
*/
Expand Down
1 change: 0 additions & 1 deletion arch/hexagon/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ config HEXAGON
# select ARCH_HAS_CPU_IDLE_WAIT
# select GPIOLIB
# select HAVE_CLK
# select GENERIC_PENDING_IRQ if SMP
select GENERIC_ATOMIC64
select HAVE_PERF_EVENTS
# GENERIC_ALLOCATOR is used by dma_alloc_coherent()
Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/include/asm/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ struct pt_regs;
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
master to copy new code to 0 */
extern void default_machine_kexec(struct kimage *image);
extern void machine_kexec_mask_interrupts(void);

void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
unsigned long start_address) __noreturn;
Expand Down
22 changes: 0 additions & 22 deletions arch/powerpc/kexec/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,6 @@
#include <asm/setup.h>
#include <asm/firmware.h>

void machine_kexec_mask_interrupts(void) {
unsigned int i;
struct irq_desc *desc;

for_each_irq_desc(i, desc) {
struct irq_chip *chip;

chip = irq_desc_get_chip(desc);
if (!chip)
continue;

if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);

if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);

if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
chip->irq_disable(&desc->irq_data);
}
}

#ifdef CONFIG_CRASH_DUMP
void machine_crash_shutdown(struct pt_regs *regs)
{
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/kexec/core_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Copyright (C) 2005 IBM Corporation.
*/

#include <linux/irq.h>
#include <linux/kexec.h>
#include <linux/mm.h>
#include <linux/string.h>
Expand Down
23 changes: 0 additions & 23 deletions arch/riscv/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,29 +114,6 @@ void machine_shutdown(void)
#endif
}

static void machine_kexec_mask_interrupts(void)
{
unsigned int i;
struct irq_desc *desc;

for_each_irq_desc(i, desc) {
struct irq_chip *chip;

chip = irq_desc_get_chip(desc);
if (!chip)
continue;

if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);

if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);

if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
chip->irq_disable(&desc->irq_data);
}
}

/*
* machine_crash_shutdown - Prepare to kexec after a kernel crash
*
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/hyperv/irqdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ static struct irq_chip hv_pci_msi_controller = {
.irq_retrigger = irq_chip_retrigger_hierarchy,
.irq_compose_msi_msg = hv_irq_compose_msi_msg,
.irq_set_affinity = msi_domain_set_affinity,
.flags = IRQCHIP_SKIP_SET_WAKE,
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED,
};

static struct msi_domain_ops pci_msi_domain_ops = {
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
.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 |
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED |
IRQCHIP_AFFINITY_PRE_STARTUP,
};

Expand Down
3 changes: 2 additions & 1 deletion arch/x86/kernel/apic/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ static bool x86_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
if (WARN_ON_ONCE(domain != real_parent))
return false;
info->chip->irq_set_affinity = msi_set_affinity;
info->chip->flags |= IRQCHIP_MOVE_DEFERRED;
break;
case DOMAIN_BUS_DMAR:
case DOMAIN_BUS_AMDVI:
Expand Down Expand Up @@ -315,7 +316,7 @@ static struct irq_chip dmar_msi_controller = {
.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 |
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED |
IRQCHIP_AFFINITY_PRE_STARTUP,
};

Expand Down
8 changes: 0 additions & 8 deletions arch/x86/kernel/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,22 +517,14 @@ static int hpet_msi_init(struct irq_domain *domain,
struct msi_domain_info *info, unsigned int virq,
irq_hw_number_t hwirq, msi_alloc_info_t *arg)
{
irq_set_status_flags(virq, IRQ_MOVE_PCNTXT);
irq_domain_set_info(domain, virq, arg->hwirq, info->chip, NULL,
handle_edge_irq, arg->data, "edge");

return 0;
}

static void hpet_msi_free(struct irq_domain *domain,
struct msi_domain_info *info, unsigned int virq)
{
irq_clear_status_flags(virq, IRQ_MOVE_PCNTXT);
}

static struct msi_domain_ops hpet_msi_domain_ops = {
.msi_init = hpet_msi_init,
.msi_free = hpet_msi_free,
};

static struct msi_domain_info hpet_msi_domain_info = {
Expand Down
3 changes: 0 additions & 3 deletions arch/x86/platform/uv/uv_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ static int uv_domain_alloc(struct irq_domain *domain, unsigned int virq,
if (ret >= 0) {
if (info->uv.limit == UV_AFFINITY_CPU)
irq_set_status_flags(virq, IRQ_NO_BALANCING);
else
irq_set_status_flags(virq, IRQ_MOVE_PCNTXT);

chip_data->pnode = uv_blade_to_pnode(info->uv.blade);
chip_data->offset = info->uv.offset;
Expand All @@ -113,7 +111,6 @@ static void uv_domain_free(struct irq_domain *domain, unsigned int virq,

BUG_ON(nr_irqs != 1);
kfree(irq_data->chip_data);
irq_clear_status_flags(virq, IRQ_MOVE_PCNTXT);
irq_clear_status_flags(virq, IRQ_NO_BALANCING);
irq_domain_free_irqs_top(domain, virq, nr_irqs);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/amd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -2332,7 +2332,7 @@ static struct irq_chip intcapxt_controller = {
.irq_retrigger = irq_chip_retrigger_hierarchy,
.irq_set_affinity = intcapxt_set_affinity,
.irq_set_wake = intcapxt_set_wake,
.flags = IRQCHIP_MASK_ON_SUSPEND,
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_MOVE_DEFERRED,
};

static const struct irq_domain_ops intcapxt_domain_ops = {
Expand Down
1 change: 0 additions & 1 deletion drivers/iommu/amd/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3540,7 +3540,6 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
irq_data->chip_data = data;
irq_data->chip = &amd_ir_chip;
irq_remapping_prepare_irte(data, cfg, info, devid, index, i);
irq_set_status_flags(virq + i, IRQ_MOVE_PCNTXT);
}

return 0;
Expand Down
1 change: 0 additions & 1 deletion drivers/iommu/intel/irq_remapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -1463,7 +1463,6 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain,
else
irq_data->chip = &intel_ir_chip;
intel_irq_remapping_prepare_irte(ird, irq_cfg, info, index, i);
irq_set_status_flags(virq + i, IRQ_MOVE_PCNTXT);
}
return 0;

Expand Down
6 changes: 4 additions & 2 deletions drivers/irqchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,9 @@ config LS1X_IRQ
Support for the Loongson-1 platform Interrupt Controller.

config TI_SCI_INTR_IRQCHIP
bool
tristate "TI SCI INTR Interrupt Controller"
depends on TI_SCI_PROTOCOL
depends on ARCH_K3 || COMPILE_TEST
select IRQ_DOMAIN_HIERARCHY
help
This enables the irqchip driver support for K3 Interrupt router
Expand All @@ -544,8 +545,9 @@ config TI_SCI_INTR_IRQCHIP
TI System Controller, say Y here. Otherwise, say N.

config TI_SCI_INTA_IRQCHIP
bool
tristate "TI SCI INTA Interrupt Controller"
depends on TI_SCI_PROTOCOL
depends on ARCH_K3 || (COMPILE_TEST && ARM64)
select IRQ_DOMAIN_HIERARCHY
select TI_SCI_INTA_MSI_DOMAIN
help
Expand Down
28 changes: 1 addition & 27 deletions drivers/irqchip/irq-brcmstb-l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,6 @@ struct brcmstb_l2_intc_data {
u32 saved_mask; /* for suspend/resume */
};

/**
* brcmstb_l2_mask_and_ack - Mask and ack pending interrupt
* @d: irq_data
*
* Chip has separate enable/disable registers instead of a single mask
* register and pending interrupt is acknowledged by setting a bit.
*
* Note: This function is generic and could easily be added to the
* generic irqchip implementation if there ever becomes a will to do so.
* Perhaps with a name like irq_gc_mask_disable_and_ack_set().
*
* e.g.: https://patchwork.kernel.org/patch/9831047/
*/
static void brcmstb_l2_mask_and_ack(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
u32 mask = d->mask;

irq_gc_lock(gc);
irq_reg_writel(gc, mask, ct->regs.disable);
*ct->mask_cache &= ~mask;
irq_reg_writel(gc, mask, ct->regs.ack);
irq_gc_unlock(gc);
}

static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc)
{
struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc);
Expand Down Expand Up @@ -248,7 +222,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
if (init_params->cpu_clear >= 0) {
ct->regs.ack = init_params->cpu_clear;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask_ack = brcmstb_l2_mask_and_ack;
ct->chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set;
} else {
/* No Ack - but still slightly more efficient to define this */
ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
Expand Down
11 changes: 2 additions & 9 deletions drivers/irqchip/irq-keystone.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,11 @@ static int keystone_irq_probe(struct platform_device *pdev)
if (!kirq)
return -ENOMEM;

kirq->devctrl_regs =
syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev");
kirq->devctrl_regs = syscon_regmap_lookup_by_phandle_args(np, "ti,syscon-dev",
1, &kirq->devctrl_offset);
if (IS_ERR(kirq->devctrl_regs))
return PTR_ERR(kirq->devctrl_regs);

ret = of_property_read_u32_index(np, "ti,syscon-dev", 1,
&kirq->devctrl_offset);
if (ret) {
dev_err(dev, "couldn't read the devctrl_offset offset!\n");
return ret;
}

kirq->irq = platform_get_irq(pdev, 0);
if (kirq->irq < 0)
return kirq->irq;
Expand Down
Loading

0 comments on commit 4c55116

Please sign in to comment.