From patchwork Tue Nov 24 06:17:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 331623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D057C2D0E4 for ; Tue, 24 Nov 2020 06:27:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0300D2087C for ; Tue, 24 Nov 2020 06:27:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728171AbgKXG1h (ORCPT ); Tue, 24 Nov 2020 01:27:37 -0500 Received: from ozlabs.ru ([107.174.27.60]:51242 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727731AbgKXG1h (ORCPT ); Tue, 24 Nov 2020 01:27:37 -0500 X-Greylist: delayed 586 seconds by postgrey-1.27 at vger.kernel.org; Tue, 24 Nov 2020 01:27:37 EST Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 82CBCAE8022C; Tue, 24 Nov 2020 01:17:40 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 1/8] genirq/ipi: Simplify irq_reserve_ipi Date: Tue, 24 Nov 2020 17:17:13 +1100 Message-Id: <20201124061720.86766-2-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org __irq_domain_alloc_irqs() can already handle virq==-1 and free descriptors if it failed allocating hardware interrupts so let's skip this extra step. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Cédric Le Goater --- kernel/irq/ipi.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index 43e3d1be622c..1b2807318ea9 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -75,18 +75,12 @@ int irq_reserve_ipi(struct irq_domain *domain, } } - virq = irq_domain_alloc_descs(-1, nr_irqs, 0, NUMA_NO_NODE, NULL); - if (virq <= 0) { - pr_warn("Can't reserve IPI, failed to alloc descs\n"); - return -ENOMEM; - } - - virq = __irq_domain_alloc_irqs(domain, virq, nr_irqs, NUMA_NO_NODE, - (void *) dest, true, NULL); + virq = __irq_domain_alloc_irqs(domain, -1, nr_irqs, NUMA_NO_NODE, + (void *) dest, false, NULL); if (virq <= 0) { pr_warn("Can't reserve IPI, failed to alloc hw irqs\n"); - goto free_descs; + return -EBUSY; } for (i = 0; i < nr_irqs; i++) { @@ -96,10 +90,6 @@ int irq_reserve_ipi(struct irq_domain *domain, irq_set_status_flags(virq + i, IRQ_NO_BALANCING); } return virq; - -free_descs: - irq_free_descs(virq, nr_irqs); - return -EBUSY; } /** From patchwork Tue Nov 24 06:17:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 331622 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2861C63798 for ; Tue, 24 Nov 2020 06:27:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7013C208C3 for ; Tue, 24 Nov 2020 06:27:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728206AbgKXG1i (ORCPT ); Tue, 24 Nov 2020 01:27:38 -0500 Received: from ozlabs.ru ([107.174.27.60]:51272 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727731AbgKXG1i (ORCPT ); Tue, 24 Nov 2020 01:27:38 -0500 Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 55E0EAE80241; Tue, 24 Nov 2020 01:17:45 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 2/8] genirq/irqdomain: Clean legacy IRQ allocation Date: Tue, 24 Nov 2020 17:17:14 +1100 Message-Id: <20201124061720.86766-3-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org There are 10 users of __irq_domain_alloc_irqs() and only one - IOAPIC - passes realloc==true. There is no obvious reason for handling this specific case in the generic code. This splits out __irq_domain_alloc_irqs_data() to make it clear what IOAPIC does and makes __irq_domain_alloc_irqs() cleaner. This should cause no behavioral change. Signed-off-by: Alexey Kardashevskiy --- include/linux/irqdomain.h | 3 ++ arch/x86/kernel/apic/io_apic.c | 13 +++-- kernel/irq/irqdomain.c | 89 ++++++++++++++++++++-------------- 3 files changed, 65 insertions(+), 40 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 71535e87109f..6cc37bba9951 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -470,6 +470,9 @@ static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *par ops, host_data); } +extern int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, + unsigned int nr_irqs, int node, void *arg, + const struct irq_affinity_desc *affinity); extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, bool realloc, diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 7b3c7e0d4a09..df9c0ab3a119 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -970,9 +970,14 @@ static int alloc_irq_from_domain(struct irq_domain *domain, int ioapic, u32 gsi, return -1; } - return __irq_domain_alloc_irqs(domain, irq, 1, - ioapic_alloc_attr_node(info), - info, legacy, NULL); + if (irq == -1 || !legacy) + return __irq_domain_alloc_irqs(domain, irq, 1, + ioapic_alloc_attr_node(info), + info, false, NULL); + + return __irq_domain_alloc_irqs_data(domain, irq, 1, + ioapic_alloc_attr_node(info), + info, NULL); } /* @@ -1006,7 +1011,7 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain, return -ENOMEM; } else { info->flags |= X86_IRQ_ALLOC_LEGACY; - irq = __irq_domain_alloc_irqs(domain, irq, 1, node, info, true, + irq = __irq_domain_alloc_irqs_data(domain, irq, 1, node, info, NULL); if (irq >= 0) { irq_data = irq_domain_get_irq_data(domain, irq); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index cf8b374b892d..ca5c78366c85 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1386,6 +1386,51 @@ int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, return domain->ops->alloc(domain, irq_base, nr_irqs, arg); } +int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, + unsigned int nr_irqs, int node, void *arg, + const struct irq_affinity_desc *affinity) +{ + int i, ret; + + if (domain == NULL) { + domain = irq_default_domain; + if (WARN(!domain, "domain is NULL; cannot allocate IRQ\n")) + return -EINVAL; + } + + if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) { + pr_debug("cannot allocate memory for IRQ%d\n", virq); + ret = -ENOMEM; + goto out_free_irq_data; + } + + mutex_lock(&irq_domain_mutex); + ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg); + if (ret < 0) { + mutex_unlock(&irq_domain_mutex); + goto out_free_irq_data; + } + + for (i = 0; i < nr_irqs; i++) { + ret = irq_domain_trim_hierarchy(virq + i); + if (ret) { + mutex_unlock(&irq_domain_mutex); + goto out_free_irq_data; + } + } + + for (i = 0; i < nr_irqs; i++) { + irq_domain_insert_irq(virq + i); + } + mutex_unlock(&irq_domain_mutex); + + return virq; + +out_free_irq_data: + irq_domain_free_irq_data(virq, nr_irqs); + return ret; +} + /** * __irq_domain_alloc_irqs - Allocate IRQs from domain * @domain: domain to allocate from @@ -1412,7 +1457,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, bool realloc, const struct irq_affinity_desc *affinity) { - int i, ret, virq; + int ret, virq; if (domain == NULL) { domain = irq_default_domain; @@ -1420,47 +1465,19 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, return -EINVAL; } - if (realloc && irq_base >= 0) { - virq = irq_base; - } else { - virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node, - affinity); - if (virq < 0) { - pr_debug("cannot allocate IRQ(base %d, count %d)\n", - irq_base, nr_irqs); - return virq; - } + virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node, affinity); + if (virq < 0) { + pr_debug("cannot allocate IRQ(base %d, count %d)\n", + irq_base, nr_irqs); + return virq; } - if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) { - pr_debug("cannot allocate memory for IRQ%d\n", virq); - ret = -ENOMEM; + ret = __irq_domain_alloc_irqs_data(domain, virq, nr_irqs, node, arg, affinity); + if (ret <= 0) goto out_free_desc; - } - - mutex_lock(&irq_domain_mutex); - ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg); - if (ret < 0) { - mutex_unlock(&irq_domain_mutex); - goto out_free_irq_data; - } - - for (i = 0; i < nr_irqs; i++) { - ret = irq_domain_trim_hierarchy(virq + i); - if (ret) { - mutex_unlock(&irq_domain_mutex); - goto out_free_irq_data; - } - } - - for (i = 0; i < nr_irqs; i++) - irq_domain_insert_irq(virq + i); - mutex_unlock(&irq_domain_mutex); return virq; -out_free_irq_data: - irq_domain_free_irq_data(virq, nr_irqs); out_free_desc: irq_free_descs(virq, nr_irqs); return ret; From patchwork Tue Nov 24 06:17:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 331621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF692C6379D for ; Tue, 24 Nov 2020 06:27:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9A57F208CA for ; Tue, 24 Nov 2020 06:27:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727731AbgKXG1j (ORCPT ); Tue, 24 Nov 2020 01:27:39 -0500 Received: from ozlabs.ru ([107.174.27.60]:51294 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728682AbgKXG1i (ORCPT ); Tue, 24 Nov 2020 01:27:38 -0500 Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id E89CEAE8024C; Tue, 24 Nov 2020 01:17:51 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 3/8] genirq/irqdomain: Drop unused realloc parameter from __irq_domain_alloc_irqs Date: Tue, 24 Nov 2020 17:17:15 +1100 Message-Id: <20201124061720.86766-4-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The two previous patches made @realloc obsolete. This finishes removing it. Signed-off-by: Alexey Kardashevskiy --- include/linux/irqdomain.h | 4 +--- arch/x86/kernel/apic/io_apic.c | 2 +- drivers/gpio/gpiolib.c | 1 - drivers/irqchip/irq-armada-370-xp.c | 2 +- drivers/irqchip/irq-bcm2836.c | 3 +-- drivers/irqchip/irq-gic-v3.c | 3 +-- drivers/irqchip/irq-gic-v4.c | 6 ++---- drivers/irqchip/irq-gic.c | 3 +-- drivers/irqchip/irq-ixp4xx.c | 1 - kernel/irq/ipi.c | 2 +- kernel/irq/irqdomain.c | 4 +--- kernel/irq/msi.c | 2 +- 12 files changed, 11 insertions(+), 22 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 6cc37bba9951..a353b93ddf9e 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -475,7 +475,6 @@ extern int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, const struct irq_affinity_desc *affinity); extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, - bool realloc, const struct irq_affinity_desc *affinity); extern void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs); extern int irq_domain_activate_irq(struct irq_data *irq_data, bool early); @@ -484,8 +483,7 @@ extern void irq_domain_deactivate_irq(struct irq_data *irq_data); static inline int irq_domain_alloc_irqs(struct irq_domain *domain, unsigned int nr_irqs, int node, void *arg) { - return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false, - NULL); + return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, NULL); } extern int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index df9c0ab3a119..5b45f0874571 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -973,7 +973,7 @@ static int alloc_irq_from_domain(struct irq_domain *domain, int ioapic, u32 gsi, if (irq == -1 || !legacy) return __irq_domain_alloc_irqs(domain, irq, 1, ioapic_alloc_attr_node(info), - info, false, NULL); + info, NULL); return __irq_domain_alloc_irqs_data(domain, irq, 1, ioapic_alloc_attr_node(info), diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 089ddcaa9bc6..b7cfecb5c701 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1059,7 +1059,6 @@ static void gpiochip_set_hierarchical_irqchip(struct gpio_chip *gc, 1, NUMA_NO_NODE, &fwspec, - false, NULL); if (ret < 0) { chip_err(gc, diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index d7eb2e93db8f..bf17eb312669 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -431,7 +431,7 @@ static __init void armada_xp_ipi_init(struct device_node *node) irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, IPI_DOORBELL_END, - NUMA_NO_NODE, NULL, false, NULL); + NUMA_NO_NODE, NULL, NULL); if (WARN_ON(!base_ipi)) return; diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c index cbc7c740e4dc..fe9ff90940d3 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c @@ -269,8 +269,7 @@ static void __init bcm2836_arm_irqchip_smp_init(void) irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, BITS_PER_MBOX, - NUMA_NO_NODE, NULL, - false, NULL); + NUMA_NO_NODE, NULL, NULL); if (WARN_ON(!base_ipi)) return; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 16fecc0febe8..ff20fd54921f 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1163,8 +1163,7 @@ static void __init gic_smp_init(void) /* Register all 8 non-secure SGIs */ base_sgi = __irq_domain_alloc_irqs(gic_data.domain, -1, 8, - NUMA_NO_NODE, &sgi_fwspec, - false, NULL); + NUMA_NO_NODE, &sgi_fwspec, NULL); if (WARN_ON(base_sgi <= 0)) return; diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c index 0c18714ae13e..dd64dc50610c 100644 --- a/drivers/irqchip/irq-gic-v4.c +++ b/drivers/irqchip/irq-gic-v4.c @@ -117,8 +117,7 @@ static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx) goto err; sgi_base = __irq_domain_alloc_irqs(vpe->sgi_domain, -1, 16, - NUMA_NO_NODE, vpe, - false, NULL); + NUMA_NO_NODE, vpe, NULL); if (sgi_base <= 0) goto err; @@ -154,8 +153,7 @@ int its_alloc_vcpu_irqs(struct its_vm *vm) } vpe_base_irq = __irq_domain_alloc_irqs(vm->domain, -1, vm->nr_vpes, - NUMA_NO_NODE, vm, - false, NULL); + NUMA_NO_NODE, vm, NULL); if (vpe_base_irq <= 0) goto err; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 6053245a4754..28e5e5e4836a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -846,8 +846,7 @@ static __init void gic_smp_init(void) gic_starting_cpu, NULL); base_sgi = __irq_domain_alloc_irqs(gic_data[0].domain, -1, 8, - NUMA_NO_NODE, &sgi_fwspec, - false, NULL); + NUMA_NO_NODE, &sgi_fwspec, NULL); if (WARN_ON(base_sgi <= 0)) return; diff --git a/drivers/irqchip/irq-ixp4xx.c b/drivers/irqchip/irq-ixp4xx.c index 37e0749215c7..9dafcc22b592 100644 --- a/drivers/irqchip/irq-ixp4xx.c +++ b/drivers/irqchip/irq-ixp4xx.c @@ -353,7 +353,6 @@ void __init ixp4xx_irq_init(resource_size_t irqbase, chunk->nr_irqs, NUMA_NO_NODE, &fwspec, - false, NULL); if (ret < 0) { pr_crit("IXP4XX: can not allocate irqs in hierarchy %d\n", diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index 1b2807318ea9..fc20adf7ee0d 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -76,7 +76,7 @@ int irq_reserve_ipi(struct irq_domain *domain, } virq = __irq_domain_alloc_irqs(domain, -1, nr_irqs, NUMA_NO_NODE, - (void *) dest, false, NULL); + (void *) dest, NULL); if (virq <= 0) { pr_warn("Can't reserve IPI, failed to alloc hw irqs\n"); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index ca5c78366c85..805478f81d96 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1438,12 +1438,10 @@ int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, * @nr_irqs: number of IRQs to allocate * @node: NUMA node id for memory allocation * @arg: domain specific argument - * @realloc: IRQ descriptors have already been allocated if true * @affinity: Optional irq affinity mask for multiqueue devices * * Allocate IRQ numbers and initialized all data structures to support * hierarchy IRQ domains. - * Parameter @realloc is mainly to support legacy IRQs. * Returns error code or allocated IRQ number * * The whole process to setup an IRQ has been split into two steps. @@ -1455,7 +1453,7 @@ int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, */ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, - bool realloc, const struct irq_affinity_desc *affinity) + const struct irq_affinity_desc *affinity) { int ret, virq; diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 2c0c4d6d0f83..b1898514d9dc 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -414,7 +414,7 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, ops->set_desc(&arg, desc); virq = __irq_domain_alloc_irqs(domain, -1, desc->nvec_used, - dev_to_node(dev), &arg, false, + dev_to_node(dev), &arg, desc->affinity); if (virq < 0) { ret = -ENOSPC; From patchwork Tue Nov 24 06:17:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 331620 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 105C7C63798 for ; Tue, 24 Nov 2020 06:28:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BF9452068D for ; Tue, 24 Nov 2020 06:28:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729188AbgKXG2I (ORCPT ); Tue, 24 Nov 2020 01:28:08 -0500 Received: from ozlabs.ru ([107.174.27.60]:51420 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729552AbgKXG2H (ORCPT ); Tue, 24 Nov 2020 01:28:07 -0500 Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 894A2AE8024F; Tue, 24 Nov 2020 01:17:57 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 4/8] genirq: Free IRQ descriptor via embedded kobject Date: Tue, 24 Nov 2020 17:17:16 +1100 Message-Id: <20201124061720.86766-5-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org At the moment the IRQ descriptor is freed via the free_desc() helper. We want to add reference counting to IRQ descriptors and there is already kobj embedded into irq_desc which we want to reuse. This shuffles free_desc()/etc to make it simply call kobject_put() and moves all the cleanup into the kobject_release hook. As a bonus, we do not need irq_sysfs_del() as kobj removes itself from sysfs if it knows that it was added. This should cause no behavioral change. Signed-off-by: Alexey Kardashevskiy --- kernel/irq/irqdesc.c | 42 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 1a7723604399..75374b7944b5 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -295,18 +295,6 @@ static void irq_sysfs_add(int irq, struct irq_desc *desc) } } -static void irq_sysfs_del(struct irq_desc *desc) -{ - /* - * If irq_sysfs_init() has not yet been invoked (early boot), then - * irq_kobj_base is NULL and the descriptor was never added. - * kobject_del() complains about a object with no parent, so make - * it conditional. - */ - if (irq_kobj_base) - kobject_del(&desc->kobj); -} - static int __init irq_sysfs_init(void) { struct irq_desc *desc; @@ -337,7 +325,6 @@ static struct kobj_type irq_kobj_type = { }; static void irq_sysfs_add(int irq, struct irq_desc *desc) {} -static void irq_sysfs_del(struct irq_desc *desc) {} #endif /* CONFIG_SYSFS */ @@ -419,39 +406,34 @@ static struct irq_desc *alloc_desc(int irq, int node, unsigned int flags, return NULL; } -static void irq_kobj_release(struct kobject *kobj) -{ - struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj); - - free_masks(desc); - free_percpu(desc->kstat_irqs); - kfree(desc); -} - static void delayed_free_desc(struct rcu_head *rhp) { struct irq_desc *desc = container_of(rhp, struct irq_desc, rcu); + free_masks(desc); + free_percpu(desc->kstat_irqs); + kfree(desc); +} + +static void free_desc(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + kobject_put(&desc->kobj); } -static void free_desc(unsigned int irq) +static void irq_kobj_release(struct kobject *kobj) { - struct irq_desc *desc = irq_to_desc(irq); + struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj); + unsigned int irq = desc->irq_data.irq; irq_remove_debugfs_entry(desc); unregister_irq_proc(irq, desc); /* - * sparse_irq_lock protects also show_interrupts() and - * kstat_irq_usr(). Once we deleted the descriptor from the - * sparse tree we can free it. Access in proc will fail to - * lookup the descriptor. - * * The sysfs entry must be serialized against a concurrent * irq_sysfs_init() as well. */ - irq_sysfs_del(desc); delete_irq_desc(irq); /* From patchwork Tue Nov 24 06:17:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 331619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF89CC64E7A for ; Tue, 24 Nov 2020 06:28:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8AED92068D for ; Tue, 24 Nov 2020 06:28:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725616AbgKXG2J (ORCPT ); Tue, 24 Nov 2020 01:28:09 -0500 Received: from ozlabs.ru ([107.174.27.60]:51422 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729552AbgKXG2I (ORCPT ); Tue, 24 Nov 2020 01:28:08 -0500 Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 2A578AE80251; Tue, 24 Nov 2020 01:18:02 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 5/8] genirq: Add free_irq hook for IRQ descriptor and use for mapping disposal Date: Tue, 24 Nov 2020 17:17:17 +1100 Message-Id: <20201124061720.86766-6-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org We want to make the irq_desc.kobj's release hook free associated resources but we do not want to pollute the irqdesc code with domains. This adds a free_irq hook which is called when the last reference to the descriptor is dropped. The first user is mapped irqs. This potentially can break the existing users; however they seem to do the right thing and call dispose once per mapping. Signed-off-by: Alexey Kardashevskiy --- include/linux/irqdesc.h | 1 + include/linux/irqdomain.h | 2 -- include/linux/irqhandler.h | 1 + kernel/irq/irqdesc.c | 3 +++ kernel/irq/irqdomain.c | 14 ++++++++++++-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 5745491303e0..6d44cb6a20ad 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -57,6 +57,7 @@ struct irq_desc { struct irq_data irq_data; unsigned int __percpu *kstat_irqs; irq_flow_handler_t handle_irq; + irq_free_handler_t free_irq; struct irqaction *action; /* IRQ action list */ unsigned int status_use_accessors; unsigned int core_internal_state__do_not_mess_with_it; diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index a353b93ddf9e..ccca87cd3d15 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -381,8 +381,6 @@ extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq, extern void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base, irq_hw_number_t hwirq_base, int count); -extern void irq_domain_disassociate(struct irq_domain *domain, - unsigned int irq); extern unsigned int irq_create_mapping(struct irq_domain *host, irq_hw_number_t hwirq); diff --git a/include/linux/irqhandler.h b/include/linux/irqhandler.h index c30f454a9518..3dbc2bb764f3 100644 --- a/include/linux/irqhandler.h +++ b/include/linux/irqhandler.h @@ -10,5 +10,6 @@ struct irq_desc; struct irq_data; typedef void (*irq_flow_handler_t)(struct irq_desc *desc); +typedef void (*irq_free_handler_t)(struct irq_desc *desc); #endif diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 75374b7944b5..071363da8688 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -427,6 +427,9 @@ static void irq_kobj_release(struct kobject *kobj) struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj); unsigned int irq = desc->irq_data.irq; + if (desc->free_irq) + desc->free_irq(desc); + irq_remove_debugfs_entry(desc); unregister_irq_proc(irq, desc); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 805478f81d96..4779d912bb86 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -485,7 +485,7 @@ static void irq_domain_set_mapping(struct irq_domain *domain, } } -void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) +static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) { struct irq_data *irq_data = irq_get_irq_data(irq); irq_hw_number_t hwirq; @@ -582,6 +582,13 @@ void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base, } EXPORT_SYMBOL_GPL(irq_domain_associate_many); +static void irq_mapped_free_desc(struct irq_desc *desc) +{ + unsigned int virq = desc->irq_data.irq; + + irq_domain_disassociate(desc->irq_data.domain, virq); +} + /** * irq_create_direct_mapping() - Allocate an irq for direct mapping * @domain: domain to allocate the irq for or NULL for default domain @@ -638,6 +645,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain, { struct device_node *of_node; int virq; + struct irq_desc *desc; pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); @@ -674,6 +682,9 @@ unsigned int irq_create_mapping(struct irq_domain *domain, pr_debug("irq %lu on domain %s mapped to virtual irq %u\n", hwirq, of_node_full_name(of_node), virq); + desc = irq_to_desc(virq); + desc->free_irq = irq_mapped_free_desc; + return virq; } EXPORT_SYMBOL_GPL(irq_create_mapping); @@ -865,7 +876,6 @@ void irq_dispose_mapping(unsigned int virq) if (irq_domain_is_hierarchy(domain)) { irq_domain_free_irqs(virq, 1); } else { - irq_domain_disassociate(domain, virq); irq_free_desc(virq); } } From patchwork Tue Nov 24 06:17:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 332545 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DCDEDC56201 for ; Tue, 24 Nov 2020 06:28:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 934912080A for ; Tue, 24 Nov 2020 06:28:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728682AbgKXG2I (ORCPT ); Tue, 24 Nov 2020 01:28:08 -0500 Received: from ozlabs.ru ([107.174.27.60]:51418 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729188AbgKXG2H (ORCPT ); Tue, 24 Nov 2020 01:28:07 -0500 Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id D511EAE80253; Tue, 24 Nov 2020 01:18:08 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 6/8] genirq/irqdomain: Move hierarchical IRQ cleanup to kobject_release Date: Tue, 24 Nov 2020 17:17:18 +1100 Message-Id: <20201124061720.86766-7-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org This moves hierarchical domain's irqs cleanup into the kobject release hook to make irq_domain_free_irqs() as simple as kobject_put. Signed-off-by: Alexey Kardashevskiy --- kernel/irq/irqdomain.c | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 4779d912bb86..a0a81cc6c524 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -863,21 +863,9 @@ EXPORT_SYMBOL_GPL(irq_create_of_mapping); */ void irq_dispose_mapping(unsigned int virq) { - struct irq_data *irq_data = irq_get_irq_data(virq); - struct irq_domain *domain; + struct irq_desc *desc = irq_to_desc(virq); - if (!virq || !irq_data) - return; - - domain = irq_data->domain; - if (WARN_ON(domain == NULL)) - return; - - if (irq_domain_is_hierarchy(domain)) { - irq_domain_free_irqs(virq, 1); - } else { - irq_free_desc(virq); - } + kobject_put(&desc->kobj); } EXPORT_SYMBOL_GPL(irq_dispose_mapping); @@ -1396,6 +1384,19 @@ int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, return domain->ops->alloc(domain, irq_base, nr_irqs, arg); } +static void irq_domain_hierarchy_free_desc(struct irq_desc *desc) +{ + unsigned int virq = desc->irq_data.irq; + struct irq_data *data = irq_get_irq_data(virq); + + mutex_lock(&irq_domain_mutex); + irq_domain_remove_irq(virq); + irq_domain_free_irqs_hierarchy(data->domain, virq, 1); + mutex_unlock(&irq_domain_mutex); + + irq_domain_free_irq_data(virq, 1); +} + int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, unsigned int nr_irqs, int node, void *arg, const struct irq_affinity_desc *affinity) @@ -1430,7 +1431,10 @@ int __irq_domain_alloc_irqs_data(struct irq_domain *domain, int virq, } for (i = 0; i < nr_irqs; i++) { + struct irq_desc *desc = irq_to_desc(virq + i); + irq_domain_insert_irq(virq + i); + desc->free_irq = irq_domain_hierarchy_free_desc; } mutex_unlock(&irq_domain_mutex); @@ -1675,14 +1679,11 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs) "NULL pointer, cannot free irq\n")) return; - mutex_lock(&irq_domain_mutex); - for (i = 0; i < nr_irqs; i++) - irq_domain_remove_irq(virq + i); - irq_domain_free_irqs_hierarchy(data->domain, virq, nr_irqs); - mutex_unlock(&irq_domain_mutex); + for (i = 0; i < nr_irqs; i++) { + struct irq_desc *desc = irq_to_desc(virq + i); - irq_domain_free_irq_data(virq, nr_irqs); - irq_free_descs(virq, nr_irqs); + kobject_put(&desc->kobj); + } } /** From patchwork Tue Nov 24 06:17:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 332546 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B291AC63777 for ; Tue, 24 Nov 2020 06:28:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 67C352068D for ; Tue, 24 Nov 2020 06:28:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729675AbgKXG2H (ORCPT ); Tue, 24 Nov 2020 01:28:07 -0500 Received: from ozlabs.ru ([107.174.27.60]:51416 "EHLO ozlabs.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728682AbgKXG2H (ORCPT ); Tue, 24 Nov 2020 01:28:07 -0500 Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 75863AE80257; Tue, 24 Nov 2020 01:18:20 -0500 (EST) From: Alexey Kardashevskiy To: linux-kernel@vger.kernel.org Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Frederic Barrat , =?utf-8?q?Michal_Such?= =?utf-8?b?w6FuZWs=?= , "Oliver O'Halloran" , Marc Zyngier , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, x86@kernel.org, linuxppc-dev@lists.ozlabs.org, Alexey Kardashevskiy Subject: [PATCH kernel v4 8/8] powerpc/pci: Remove LSI mappings on device teardown Date: Tue, 24 Nov 2020 17:17:20 +1100 Message-Id: <20201124061720.86766-9-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201124061720.86766-1-aik@ozlabs.ru> References: <20201124061720.86766-1-aik@ozlabs.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Oliver O'Halloran When a passthrough IO adapter is removed from a pseries machine using hash MMU and the XIVE interrupt mode, the POWER hypervisor expects the guest OS to clear all page table entries related to the adapter. If some are still present, the RTAS call which isolates the PCI slot returns error 9001 "valid outstanding translations" and the removal of the IO adapter fails. This is because when the PHBs are scanned, Linux maps automatically the INTx interrupts in the Linux interrupt number space but these are never removed. This problem can be fixed by adding the corresponding unmap operation when the device is removed. There's no pcibios_* hook for the remove case, but the same effect can be achieved using a bus notifier. Signed-off-by: Oliver O'Halloran Reviewed-by: Cédric Le Goater Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/kernel/pci-common.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index be108616a721..95f4e173368a 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -404,6 +404,27 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) return 0; } +static int ppc_pci_unmap_irq_line(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct pci_dev *pdev = to_pci_dev(data); + + if (action == BUS_NOTIFY_DEL_DEVICE) + irq_dispose_mapping(pdev->irq); + + return NOTIFY_DONE; +} + +static struct notifier_block ppc_pci_unmap_irq_notifier = { + .notifier_call = ppc_pci_unmap_irq_line, +}; + +static int ppc_pci_register_irq_notifier(void) +{ + return bus_register_notifier(&pci_bus_type, &ppc_pci_unmap_irq_notifier); +} +arch_initcall(ppc_pci_register_irq_notifier); + /* * Platform support for /proc/bus/pci/X/Y mmap()s. * -- paulus.