Skip to content

Commit b08ecce

Browse files
committed
Merge tag 'irq-core-2023-10-29-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "Core: - Exclude managed interrupts in the calculation of interrupts which are targeted to a CPU which is about to be offlined to ensure that there are enough free vectors on the still online CPUs to migrate them over. Managed interrupts do not need to be accounted because they are either shut down on offline or migrated to an already reserved and guaranteed slot on a still online CPU in the interrupts affinity mask. Including managed interrupts is overaccounting and can result in needlessly aborting hibernation on large server machines. - The usual set of small improvements Drivers: - Make the generic interrupt chip implementation handle interrupt domains correctly and initialize the name pointers correctly - Add interrupt affinity setting support to the Renesas RZG2L chip driver. - Prevent registering syscore operations multiple times in the SiFive PLIC chip driver. - Update device tree handling in the NXP Layerscape MSI chip driver" * tag 'irq-core-2023-10-29-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/sifive-plic: Fix syscore registration for multi-socket systems irqchip/ls-scfg-msi: Use device_get_match_data() genirq/generic_chip: Make irq_remove_generic_chip() irqdomain aware genirq/matrix: Exclude managed interrupts in irq_matrix_allocated() PCI/MSI: Provide stubs for IMS functions irqchip/renesas-rzg2l: Enhance driver to support interrupt affinity setting genirq/generic-chip: Fix the irq_chip name for /proc/interrupts irqdomain: Annotate struct irq_domain with __counted_by
2 parents 9cc6fea + f99b926 commit b08ecce

File tree

7 files changed

+64
-29
lines changed

7 files changed

+64
-29
lines changed

drivers/irqchip/irq-ls-scfg-msi.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#include <linux/irqdomain.h>
1818
#include <linux/of_irq.h>
1919
#include <linux/of_pci.h>
20-
#include <linux/of_platform.h>
20+
#include <linux/platform_device.h>
21+
#include <linux/property.h>
2122
#include <linux/spinlock.h>
2223

2324
#define MSI_IRQS_PER_MSIR 32
@@ -334,20 +335,17 @@ MODULE_DEVICE_TABLE(of, ls_scfg_msi_id);
334335

335336
static int ls_scfg_msi_probe(struct platform_device *pdev)
336337
{
337-
const struct of_device_id *match;
338338
struct ls_scfg_msi *msi_data;
339339
struct resource *res;
340340
int i, ret;
341341

342-
match = of_match_device(ls_scfg_msi_id, &pdev->dev);
343-
if (!match)
344-
return -ENODEV;
345-
346342
msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data), GFP_KERNEL);
347343
if (!msi_data)
348344
return -ENOMEM;
349345

350-
msi_data->cfg = (struct ls_scfg_msi_cfg *) match->data;
346+
msi_data->cfg = (struct ls_scfg_msi_cfg *)device_get_match_data(&pdev->dev);
347+
if (!msi_data->cfg)
348+
return -ENODEV;
351349

352350
msi_data->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
353351
if (IS_ERR(msi_data->regs)) {

drivers/irqchip/irq-renesas-rzg2l.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ static const struct irq_chip irqc_chip = {
247247
.irq_set_irqchip_state = irq_chip_set_parent_state,
248248
.irq_retrigger = irq_chip_retrigger_hierarchy,
249249
.irq_set_type = rzg2l_irqc_set_type,
250+
.irq_set_affinity = irq_chip_set_affinity_parent,
250251
.flags = IRQCHIP_MASK_ON_SUSPEND |
251252
IRQCHIP_SET_TYPE_MASKED |
252253
IRQCHIP_SKIP_SET_WAKE,

drivers/irqchip/irq-sifive-plic.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,17 +532,18 @@ static int __init __plic_init(struct device_node *node,
532532
}
533533

534534
/*
535-
* We can have multiple PLIC instances so setup cpuhp state only
536-
* when context handler for current/boot CPU is present.
535+
* We can have multiple PLIC instances so setup cpuhp state
536+
* and register syscore operations only when context handler
537+
* for current/boot CPU is present.
537538
*/
538539
handler = this_cpu_ptr(&plic_handlers);
539540
if (handler->present && !plic_cpuhp_setup_done) {
540541
cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
541542
"irqchip/sifive/plic:starting",
542543
plic_starting_cpu, plic_dying_cpu);
544+
register_syscore_ops(&plic_irq_syscore_ops);
543545
plic_cpuhp_setup_done = true;
544546
}
545-
register_syscore_ops(&plic_irq_syscore_ops);
546547

547548
pr_info("%pOFP: mapped %d interrupts with %d handlers for"
548549
" %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);

include/linux/irqdomain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ struct irq_domain {
174174
irq_hw_number_t hwirq_max;
175175
unsigned int revmap_size;
176176
struct radix_tree_root revmap_tree;
177-
struct irq_data __rcu *revmap[];
177+
struct irq_data __rcu *revmap[] __counted_by(revmap_size);
178178
};
179179

180180
/* Irq domain flags */

include/linux/pci.h

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,8 @@ struct msix_entry {
16241624
u16 entry; /* Driver uses to specify entry, OS writes */
16251625
};
16261626

1627+
struct msi_domain_template;
1628+
16271629
#ifdef CONFIG_PCI_MSI
16281630
int pci_msi_vec_count(struct pci_dev *dev);
16291631
void pci_disable_msi(struct pci_dev *dev);
@@ -1656,6 +1658,11 @@ void pci_msix_free_irq(struct pci_dev *pdev, struct msi_map map);
16561658
void pci_free_irq_vectors(struct pci_dev *dev);
16571659
int pci_irq_vector(struct pci_dev *dev, unsigned int nr);
16581660
const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec);
1661+
bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template,
1662+
unsigned int hwsize, void *data);
1663+
struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie,
1664+
const struct irq_affinity_desc *affdesc);
1665+
void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map);
16591666

16601667
#else
16611668
static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; }
@@ -1719,6 +1726,25 @@ static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev,
17191726
{
17201727
return cpu_possible_mask;
17211728
}
1729+
1730+
static inline bool pci_create_ims_domain(struct pci_dev *pdev,
1731+
const struct msi_domain_template *template,
1732+
unsigned int hwsize, void *data)
1733+
{ return false; }
1734+
1735+
static inline struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev,
1736+
union msi_instance_cookie *icookie,
1737+
const struct irq_affinity_desc *affdesc)
1738+
{
1739+
struct msi_map map = { .index = -ENOSYS, };
1740+
1741+
return map;
1742+
}
1743+
1744+
static inline void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map)
1745+
{
1746+
}
1747+
17221748
#endif
17231749

17241750
/**
@@ -2616,14 +2642,6 @@ static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
26162642
void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type);
26172643
#endif
26182644

2619-
struct msi_domain_template;
2620-
2621-
bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template,
2622-
unsigned int hwsize, void *data);
2623-
struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie,
2624-
const struct irq_affinity_desc *affdesc);
2625-
void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map);
2626-
26272645
#include <linux/dma-mapping.h>
26282646

26292647
#define pci_printk(level, pdev, fmt, arg...) \

kernel/irq/generic-chip.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,15 @@ void irq_init_generic_chip(struct irq_chip_generic *gc, const char *name,
219219
int num_ct, unsigned int irq_base,
220220
void __iomem *reg_base, irq_flow_handler_t handler)
221221
{
222+
struct irq_chip_type *ct = gc->chip_types;
223+
int i;
224+
222225
raw_spin_lock_init(&gc->lock);
223226
gc->num_ct = num_ct;
224227
gc->irq_base = irq_base;
225228
gc->reg_base = reg_base;
226-
gc->chip_types->chip.name = name;
229+
for (i = 0; i < num_ct; i++)
230+
ct[i].chip.name = name;
227231
gc->chip_types->handler = handler;
228232
}
229233

@@ -544,21 +548,34 @@ EXPORT_SYMBOL_GPL(irq_setup_alt_chip);
544548
void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
545549
unsigned int clr, unsigned int set)
546550
{
547-
unsigned int i = gc->irq_base;
551+
unsigned int i, virq;
548552

549553
raw_spin_lock(&gc_lock);
550554
list_del(&gc->list);
551555
raw_spin_unlock(&gc_lock);
552556

553-
for (; msk; msk >>= 1, i++) {
557+
for (i = 0; msk; msk >>= 1, i++) {
554558
if (!(msk & 0x01))
555559
continue;
556560

561+
/*
562+
* Interrupt domain based chips store the base hardware
563+
* interrupt number in gc::irq_base. Otherwise gc::irq_base
564+
* contains the base Linux interrupt number.
565+
*/
566+
if (gc->domain) {
567+
virq = irq_find_mapping(gc->domain, gc->irq_base + i);
568+
if (!virq)
569+
continue;
570+
} else {
571+
virq = gc->irq_base + i;
572+
}
573+
557574
/* Remove handler first. That will mask the irq line */
558-
irq_set_handler(i, NULL);
559-
irq_set_chip(i, &no_irq_chip);
560-
irq_set_chip_data(i, NULL);
561-
irq_modify_status(i, clr, set);
575+
irq_set_handler(virq, NULL);
576+
irq_set_chip(virq, &no_irq_chip);
577+
irq_set_chip_data(virq, NULL);
578+
irq_modify_status(virq, clr, set);
562579
}
563580
}
564581
EXPORT_SYMBOL_GPL(irq_remove_generic_chip);

kernel/irq/matrix.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,16 +466,16 @@ unsigned int irq_matrix_reserved(struct irq_matrix *m)
466466
}
467467

468468
/**
469-
* irq_matrix_allocated - Get the number of allocated irqs on the local cpu
469+
* irq_matrix_allocated - Get the number of allocated non-managed irqs on the local CPU
470470
* @m: Pointer to the matrix to search
471471
*
472-
* This returns number of allocated irqs
472+
* This returns number of allocated non-managed interrupts.
473473
*/
474474
unsigned int irq_matrix_allocated(struct irq_matrix *m)
475475
{
476476
struct cpumap *cm = this_cpu_ptr(m->maps);
477477

478-
return cm->allocated;
478+
return cm->allocated - cm->managed_allocated;
479479
}
480480

481481
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS

0 commit comments

Comments
 (0)