From 57aaf27a1222e0148aa17df454b3e34b75186ce6 Mon Sep 17 00:00:00 2001 From: Juxin Gao Date: Fri, 15 Nov 2024 19:20:57 +0800 Subject: [PATCH 1/2] drivers/irqchip: Disable pci_irq_limit when using avec interrupt controller Upstream: no In the new interrupt model, the avec interrupt controller no longer has a limit on the number of interrupts like the extended interrupt controller, so when using the avec interrupt model, pci_irq_limit is disabled by default. Signed-off-by Juxin Gao Signed-off-by: Ming Wang --- arch/loongarch/include/asm/setup.h | 1 + drivers/irqchip/irq-loongarch-avec.c | 2 ++ drivers/pci/msi/msi.c | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h index ee52fb1e9963..eefb30c33ba3 100644 --- a/arch/loongarch/include/asm/setup.h +++ b/arch/loongarch/include/asm/setup.h @@ -12,6 +12,7 @@ #define VECSIZE 0x200 +extern bool disable_pci_irq_limit; extern unsigned long eentry; extern unsigned long tlbrentry; extern char init_command_line[COMMAND_LINE_SIZE]; diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c index 5c9dcc488e21..638516164d2f 100644 --- a/drivers/irqchip/irq-loongarch-avec.c +++ b/drivers/irqchip/irq-loongarch-avec.c @@ -30,6 +30,7 @@ struct pending_list { struct list_head head; }; +bool disable_pci_irq_limit; static struct cpumask intersect_mask; static DEFINE_PER_CPU(struct pending_list, pending_list); #endif @@ -365,6 +366,7 @@ static int __init avecintc_init(struct irq_domain *parent) int ret, parent_irq; unsigned long value; + disable_pci_irq_limit = true; raw_spin_lock_init(&loongarch_avec.lock); loongarch_avec.fwnode = irq_domain_alloc_named_fwnode("AVECINTC"); diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index e6ac06d94fb5..3bd6b9d20b09 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -409,6 +409,8 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, } #ifdef CONFIG_LOONGARCH +#include + static unsigned int pci_irq_numbers = 32; static int __init pci_irq_limit(char *str) @@ -430,9 +432,11 @@ int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, int rc; #ifdef CONFIG_LOONGARCH - if (maxvec > 32) { - maxvec = pci_irq_numbers; - minvec = min_t(int, pci_irq_numbers, minvec); + if (!disable_pci_irq_limit) { + if (maxvec > 32) { + maxvec = pci_irq_numbers; + minvec = min_t(int, pci_irq_numbers, minvec); + } } #endif @@ -807,9 +811,11 @@ int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int int hwsize, rc, nvec = maxvec; #ifdef CONFIG_LOONGARCH - if (maxvec > 32) { - nvec = pci_irq_numbers; - minvec = min_t(int, pci_irq_numbers, minvec); + if (!disable_pci_irq_limit) { + if (maxvec > 32) { + nvec = pci_irq_numbers; + minvec = min_t(int, pci_irq_numbers, minvec); + } } #endif -- Gitee From bd4d123da8f56c21f41fad6b9684c4cece6d06d5 Mon Sep 17 00:00:00 2001 From: Tianyang Zhang Date: Wed, 27 Nov 2024 14:28:18 +0800 Subject: [PATCH 2/2] irq-loongarch-avec.c: Enables the Advanced Extended Interrupt Controllers (AVEC) functionality in multi-node 3C6000 systems. Upstream: no The AVEC topology is aligned with the NUMA node architecture. During CPU online, the enable status of the corresponding NUMA node is verified. This introduces a minor overhead but ensures AVEC functionality remains available even when some CPUs fail to start. Additionally, this patch addresses a bug in the IPI-based expired affinity cleanup mechanism for multi-node systems. Signed-off-by: zhangtianyang Signed-off-by: Ming Wang --- drivers/irqchip/irq-loongarch-avec.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c index 638516164d2f..b9202fdb6d92 100644 --- a/drivers/irqchip/irq-loongarch-avec.c +++ b/drivers/irqchip/irq-loongarch-avec.c @@ -84,7 +84,7 @@ static void avecintc_sync(struct avecintc_data *adata) plist = per_cpu_ptr(&pending_list, adata->prev_cpu); list_add_tail(&adata->entry, &plist->head); adata->moving = 1; - smp_ops.send_ipi_single(adata->prev_cpu, SMP_CLEAR_VECTOR); + smp_ops.send_ipi_single(adata->prev_cpu, ACTION_CLEAR_VECTOR); } } @@ -133,6 +133,7 @@ static int avecintc_set_affinity(struct irq_data *data, const struct cpumask *de static int avecintc_cpu_online(unsigned int cpu) { + long value; if (!loongarch_avec.vector_matrix) return 0; @@ -142,6 +143,10 @@ static int avecintc_cpu_online(unsigned int cpu) pending_list_init(cpu); + value = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC); + value |= IOCSR_MISC_FUNC_AVEC_EN; + iocsr_write64(value, LOONGARCH_IOCSR_MISC_FUNC); + raw_spin_unlock(&loongarch_avec.lock); return 0; @@ -194,7 +199,7 @@ void complete_irq_moving(void) } if (isr & (1UL << (vector % VECTORS_PER_REG))) { - smp_ops.send_ipi_single(cpu, SMP_CLEAR_VECTOR); + smp_ops.send_ipi_single(cpu, ACTION_CLEAR_VECTOR); continue; } list_del(&adata->entry); -- Gitee