From patchwork Fri Oct 22 10:33:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Schneider X-Patchwork-Id: 12577525 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E735EC433EF for ; Fri, 22 Oct 2021 10:35:04 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A5CAD6112F for ; Fri, 22 Oct 2021 10:35:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A5CAD6112F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1bMTt7S1lNawGJLuoH4/Roa6ORmjqw4A4Adpbk4IaTs=; b=VGSE252K6/TD0m d+esdr53XklEJN1VNHw7KMn8KFefxJFEDTVBOe3mKTvFoG6s6p3EZD+iKGndxHmtT7Yk1muS9kPMm M4AsQRfA3xJUQ9cOPWbP4QgRLWmbVd65pkBaDobRunmMhuRqrG1qsmdZkiqUmYygMaUOTbU4A9vey xTYD2v+KTk2F0UTtkvzJ3qGIysBo28Y4A19SbFv6C5tFBePjrx7155pEbBK1KDWA7a+op3QFQj6+A YH0BRC1CjUOScamRjRMK7FizWOGTAVnyC78e763iNGYQ6t80NgjXsjiv1j+gd58p940MOlB9ld9EJ PiUnRk/LL7PKLaf/bXyQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdrrx-00AXHJ-Ti; Fri, 22 Oct 2021 10:33:50 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdrrg-00AX9C-SF for linux-arm-kernel@lists.infradead.org; Fri, 22 Oct 2021 10:33:36 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A11BC1396; Fri, 22 Oct 2021 03:33:27 -0700 (PDT) Received: from e113632-lin.cambridge.arm.com (e113632-lin.cambridge.arm.com [10.1.196.57]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 517CD3F70D; Fri, 22 Oct 2021 03:33:26 -0700 (PDT) From: Valentin Schneider To: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Will Deacon , Mark Rutland , Marc Zyngier , Thomas Gleixner , Sebastian Andrzej Siewior , Ard Biesheuvel Subject: [PATCH 1/3] irqchip/gic-v3-its: Give the percpu rdist struct its own flags field Date: Fri, 22 Oct 2021 11:33:05 +0100 Message-Id: <20211022103307.1711619-2-valentin.schneider@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211022103307.1711619-1-valentin.schneider@arm.com> References: <20211022103307.1711619-1-valentin.schneider@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211022_033333_057196_A1580C5E X-CRM114-Status: GOOD ( 14.26 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Later patches will require tracking some per-rdist status. Reuse the bytes "lost" to padding within the __percpu rdist struct as a flags field, and re-encode ->lpi_enabled within said flags. No change in functionality intended. Signed-off-by: Valentin Schneider --- drivers/irqchip/irq-gic-v3-its.c | 26 ++++++++++++++------------ include/linux/irqchip/arm-gic-v3.h | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index eb0882d15366..a688ed5c21e8 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -43,8 +43,10 @@ #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) -#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) -#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) +#define RDISTS_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) +#define RDISTS_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) + +#define RDIST_FLAGS_LPI_ENABLED BIT(0) static u32 lpi_id_bits; @@ -1415,7 +1417,7 @@ static void lpi_write_config(struct irq_data *d, u8 clr, u8 set) * And yes, we're flushing exactly: One. Single. Byte. * Humpf... */ - if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING) + if (gic_rdists->flags & RDISTS_FLAGS_PROPBASE_NEEDS_FLUSHING) gic_flush_dcache_to_poc(cfg, sizeof(*cfg)); else dsb(ishst); @@ -2224,7 +2226,7 @@ static int gic_reserve_range(phys_addr_t addr, unsigned long size) static int __init its_setup_lpi_prop_table(void) { - if (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) { + if (gic_rdists->flags & RDISTS_FLAGS_RD_TABLES_PREALLOCATED) { u64 val; val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER); @@ -2978,8 +2980,8 @@ static int __init allocate_lpi_tables(void) */ val = readl_relaxed(gic_data_rdist_rd_base() + GICR_CTLR); if ((val & GICR_CTLR_ENABLE_LPIS) && enabled_lpis_allowed()) { - gic_rdists->flags |= (RDIST_FLAGS_RD_TABLES_PREALLOCATED | - RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING); + gic_rdists->flags |= (RDISTS_FLAGS_RD_TABLES_PREALLOCATED | + RDISTS_FLAGS_PROPBASE_NEEDS_FLUSHING); pr_info("GICv3: Using preallocated redistributor tables\n"); } @@ -3044,11 +3046,11 @@ static void its_cpu_init_lpis(void) phys_addr_t paddr; u64 val, tmp; - if (gic_data_rdist()->lpi_enabled) + if (gic_data_rdist()->flags & RDIST_FLAGS_LPI_ENABLED) return; val = readl_relaxed(rbase + GICR_CTLR); - if ((gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) && + if ((gic_rdists->flags & RDISTS_FLAGS_RD_TABLES_PREALLOCATED) && (val & GICR_CTLR_ENABLE_LPIS)) { /* * Check that we get the same property table on all @@ -3095,7 +3097,7 @@ static void its_cpu_init_lpis(void) gicr_write_propbaser(val, rbase + GICR_PROPBASER); } pr_info_once("GIC: using cache flushing for LPI property table\n"); - gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; + gic_rdists->flags |= RDISTS_FLAGS_PROPBASE_NEEDS_FLUSHING; } /* set PENDBASE */ @@ -3158,7 +3160,7 @@ static void its_cpu_init_lpis(void) /* Make sure the GIC has seen the above */ dsb(sy); out: - gic_data_rdist()->lpi_enabled = true; + gic_data_rdist()->flags |= RDIST_FLAGS_LPI_ENABLED; pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", smp_processor_id(), gic_data_rdist()->pend_page ? "allocated" : "reserved", @@ -5138,8 +5140,8 @@ static int redist_disable_lpis(void) * * If running with preallocated tables, there is nothing to do. */ - if (gic_data_rdist()->lpi_enabled || - (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED)) + if ((gic_data_rdist()->flags & RDIST_FLAGS_LPI_ENABLED) || + (gic_rdists->flags & RDISTS_FLAGS_RD_TABLES_PREALLOCATED)) return 0; /* diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 81cbf85f73de..0dc34d7d735a 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -615,7 +615,7 @@ struct rdists { void __iomem *rd_base; struct page *pend_page; phys_addr_t phys_base; - bool lpi_enabled; + u64 flags; cpumask_t *vpe_table_mask; void *vpe_l1_base; } __percpu *rdist; From patchwork Fri Oct 22 10:33:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Schneider X-Patchwork-Id: 12577527 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F219C433F5 for ; Fri, 22 Oct 2021 10:35:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2A11861059 for ; Fri, 22 Oct 2021 10:35:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2A11861059 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jTA5pyrkoXtbLH3UxgtNp1M6DBb6ZPzu1XBEURiHao0=; b=pH8mLahLR71L6L RVz0bPEEadaemvqVEmaBKmGh8F7PUHlByDTYIesqVSBJAe2PaBC4CQcH/GHtNjYLfxKsqRrmDG7Da kivIGZLj/MLvb2Rmjal2mw7Y/PCbKBCSbzw9W1282J6ZJYqBHgCKBsoYeieD82tVlTyVufKc4H6RI 2jW8/sYEYnNoUDS9BnbLuqIxCASjowTMwJk3bN60PhO0shJImn1Pm8nldlOZ0O2kAzHszgTlGDSlx hF1qCnOx4eVHOLusZVz6BneDPIHsKhrBc9qvQz7Yz2DDTji/MPpZ7Pbtefr+Zcvw6hthXPyMoUwr7 oZTNeg5Cmj1SXDYYOG7w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdrs9-00AXJh-37; Fri, 22 Oct 2021 10:34:01 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdrri-00AX9p-GI for linux-arm-kernel@lists.infradead.org; Fri, 22 Oct 2021 10:33:36 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 349AD1474; Fri, 22 Oct 2021 03:33:29 -0700 (PDT) Received: from e113632-lin.cambridge.arm.com (e113632-lin.cambridge.arm.com [10.1.196.57]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D68793F70D; Fri, 22 Oct 2021 03:33:27 -0700 (PDT) From: Valentin Schneider To: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Will Deacon , Mark Rutland , Marc Zyngier , Thomas Gleixner , Sebastian Andrzej Siewior , Ard Biesheuvel Subject: [PATCH 2/3] irqchip/gic-v3-its: Postpone LPI pending table freeing and memreserve Date: Fri, 22 Oct 2021 11:33:06 +0100 Message-Id: <20211022103307.1711619-3-valentin.schneider@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211022103307.1711619-1-valentin.schneider@arm.com> References: <20211022103307.1711619-1-valentin.schneider@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211022_033334_704480_C64CCEBA X-CRM114-Status: GOOD ( 21.87 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Memory used by the LPI tables have to be made persistent for kexec to have a chance to work, as explained in [1]. If they have been made persistent and we are booting into a kexec'd kernel, we also need to free the pages that were preemptively allocated by the new kernel for those tables. Both of those operations currently happen during its_cpu_init(), which happens in a _STARTING (IOW atomic) cpuhp callback for secondary CPUs. efi_mem_reserve_iomem() issues a GFP_ATOMIC allocation, which unfortunately doesn't work under PREEMPT_RT (this ends up grabbing a non-raw spinlock, which can sleep under PREEMPT_RT). Similarly, freeing the pages ends up grabbing a sleepable spinlock. Since the memreserve is only required by kexec, it doesn't have to be done so early in the secondary boot process. Issue the reservation in a new CPUHP_AP_ONLINE_DYN cpuhp callback, and piggy-back the page freeing on top of it. As kexec issues a machine_shutdown() prior to machine_kexec(), it will be serialized vs a CPU being plugged to life by the hotplug machinery - either the CPU will have been brought up and have had its redistributor's pending table memreserved, or it never went online and will have its table allocated by the new kernel. [1]: https://lore.kernel.org/lkml/20180921195954.21574-1-marc.zyngier@arm.com/ Signed-off-by: Valentin Schneider --- drivers/irqchip/irq-gic-v3-its.c | 65 ++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index a688ed5c21e8..a6a4af59205e 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -47,6 +47,8 @@ #define RDISTS_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) #define RDIST_FLAGS_LPI_ENABLED BIT(0) +#define RDIST_FLAGS_PENDTABLE_RESERVED BIT(1) +#define RDIST_FLAGS_PENDTABLE_PREALLOCATED BIT(2) static u32 lpi_id_bits; @@ -3065,15 +3067,15 @@ static void its_cpu_init_lpis(void) paddr &= GENMASK_ULL(51, 16); WARN_ON(!gic_check_reserved_range(paddr, LPI_PENDBASE_SZ)); - its_free_pending_table(gic_data_rdist()->pend_page); - gic_data_rdist()->pend_page = NULL; + gic_data_rdist()->flags |= + RDIST_FLAGS_PENDTABLE_RESERVED | + RDIST_FLAGS_PENDTABLE_PREALLOCATED; goto out; } pend_page = gic_data_rdist()->pend_page; paddr = page_to_phys(pend_page); - WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ)); /* set PROPBASE */ val = (gic_rdists->prop_table_pa | @@ -3163,7 +3165,8 @@ static void its_cpu_init_lpis(void) gic_data_rdist()->flags |= RDIST_FLAGS_LPI_ENABLED; pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", smp_processor_id(), - gic_data_rdist()->pend_page ? "allocated" : "reserved", + gic_data_rdist()->flags & RDIST_FLAGS_PENDTABLE_PREALLOCATED ? + "reserved" : "allocated", &paddr); } @@ -5202,6 +5205,39 @@ int its_cpu_init(void) return 0; } +#ifdef CONFIG_EFI +static int its_cpu_memreserve_lpi(unsigned int cpu) +{ + struct page *pend_page = gic_data_rdist()->pend_page; + phys_addr_t paddr; + + /* + * If the pending table was pre-programmed, free the memory we + * preemptively allocated. + */ + if (pend_page && + (gic_data_rdist()->flags & RDIST_FLAGS_PENDTABLE_PREALLOCATED)) { + its_free_pending_table(gic_data_rdist()->pend_page); + gic_data_rdist()->pend_page = NULL; + } + + /* + * Did we already issue a memreserve? This could be via a previous + * invocation of this callback, or in a previous life before kexec. + */ + if (gic_data_rdist()->flags & RDIST_FLAGS_PENDTABLE_RESERVED) + return 0; + + gic_data_rdist()->flags |= RDIST_FLAGS_PENDTABLE_RESERVED; + + pend_page = gic_data_rdist()->pend_page; + paddr = page_to_phys(pend_page); + WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ)); + + return 0; +} +#endif + static const struct of_device_id its_device_id[] = { { .compatible = "arm,gic-v3-its", }, {}, @@ -5385,6 +5421,23 @@ static void __init its_acpi_probe(void) static void __init its_acpi_probe(void) { } #endif +static int __init its_lpi_memreserve_init(void) +{ + int state; + + if (!efi_enabled(EFI_CONFIG_TABLES)) + return 0; + + state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "irqchip/arm/gicv3/memreserve:online", + its_cpu_memreserve_lpi, + NULL); + if (state < 0) + return state; + + return 0; +} + int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, struct irq_domain *parent_domain) { @@ -5412,6 +5465,10 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, if (err) return err; + err = its_lpi_memreserve_init(); + if (err) + return err; + list_for_each_entry(its, &its_nodes, entry) { has_v4 |= is_v4(its); has_v4_1 |= is_v4_1(its); From patchwork Fri Oct 22 10:33:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Schneider X-Patchwork-Id: 12577529 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67AC9C433F5 for ; Fri, 22 Oct 2021 10:35:29 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2D46461059 for ; Fri, 22 Oct 2021 10:35:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2D46461059 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ssHcCqyo0lvGXNLdwsLE3myF0cwOFQSAy4I5LG2ptbo=; b=4rYteJhgAG5W4H Ons/cW0Cn1MXL4YwVqpFuQQaeDrC2nQaWPhd9dQL0ZjkkAOF8YS1I17zNLN8WxmxE8TIeO8KQB98b UhEJCc3NydRojFo0PiIqMTPHvUxJXGyeO4znjnfeE3Of/DuMkDTSeFbCql5l4K/UY6DtKaRzSdH0B L0hB3kwKmXFCniro4YSh0ZzjZeWTvrkDS79t6pdtFT8Gl9jT9wkr2dJNAAlc52KirE7hi/eIBqXnS DyxWPhF2c0YiHkt6naXjoDgpKCHxFDA210mFGBpHIPhgZxpUZpjUgPDOiluFslF95RyMvNxs6Z0si ab7mFmOS12nqId6GPlbA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdrsJ-00AXNH-Kk; Fri, 22 Oct 2021 10:34:11 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mdrri-00AX9w-Kz for linux-arm-kernel@lists.infradead.org; Fri, 22 Oct 2021 10:33:37 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B96BC13A1; Fri, 22 Oct 2021 03:33:30 -0700 (PDT) Received: from e113632-lin.cambridge.arm.com (e113632-lin.cambridge.arm.com [10.1.196.57]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 673CC3F70D; Fri, 22 Oct 2021 03:33:29 -0700 (PDT) From: Valentin Schneider To: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Will Deacon , Mark Rutland , Marc Zyngier , Thomas Gleixner , Sebastian Andrzej Siewior , Ard Biesheuvel Subject: [PATCH 3/3] irqchip/gic-v3-its: Limit memreserve cpuhp state lifetime Date: Fri, 22 Oct 2021 11:33:07 +0100 Message-Id: <20211022103307.1711619-4-valentin.schneider@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211022103307.1711619-1-valentin.schneider@arm.com> References: <20211022103307.1711619-1-valentin.schneider@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211022_033334_876207_08782CCA X-CRM114-Status: GOOD ( 17.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The new memreserve cpuhp callback only needs to survive up until a point where every CPU in the system has booted once. Beyond that, it becomes a no-op and can be put in the bin. Signed-off-by: Valentin Schneider --- drivers/irqchip/irq-gic-v3-its.c | 23 ++++++++++++++++++++--- include/linux/irqchip/arm-gic-v3.h | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index a6a4af59205e..4ae9ae6b90fe 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -5206,6 +5206,15 @@ int its_cpu_init(void) } #ifdef CONFIG_EFI +static void rdist_memreserve_cpuhp_cleanup_workfn(struct work_struct *work) +{ + cpuhp_remove_state_nocalls(gic_rdists->cpuhp_memreserve_state); + gic_rdists->cpuhp_memreserve_state = CPUHP_INVALID; +} + +static DECLARE_WORK(rdist_memreserve_cpuhp_cleanup_work, + rdist_memreserve_cpuhp_cleanup_workfn); + static int its_cpu_memreserve_lpi(unsigned int cpu) { struct page *pend_page = gic_data_rdist()->pend_page; @@ -5226,7 +5235,7 @@ static int its_cpu_memreserve_lpi(unsigned int cpu) * invocation of this callback, or in a previous life before kexec. */ if (gic_data_rdist()->flags & RDIST_FLAGS_PENDTABLE_RESERVED) - return 0; + goto out; gic_data_rdist()->flags |= RDIST_FLAGS_PENDTABLE_RESERVED; @@ -5234,6 +5243,11 @@ static int its_cpu_memreserve_lpi(unsigned int cpu) paddr = page_to_phys(pend_page); WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ)); +out: + /* This only needs to run once per CPU */ + if (cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask)) + schedule_work(&rdist_memreserve_cpuhp_cleanup_work); + return 0; } #endif @@ -5421,13 +5435,14 @@ static void __init its_acpi_probe(void) static void __init its_acpi_probe(void) { } #endif -static int __init its_lpi_memreserve_init(void) +static int __init its_lpi_memreserve_init(struct rdists *rdists) { int state; if (!efi_enabled(EFI_CONFIG_TABLES)) return 0; + rdists->cpuhp_memreserve_state = CPUHP_INVALID; state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/arm/gicv3/memreserve:online", its_cpu_memreserve_lpi, @@ -5435,6 +5450,8 @@ static int __init its_lpi_memreserve_init(void) if (state < 0) return state; + rdists->cpuhp_memreserve_state = state; + return 0; } @@ -5465,7 +5482,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, if (err) return err; - err = its_lpi_memreserve_init(); + err = its_lpi_memreserve_init(rdists); if (err) return err; diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 0dc34d7d735a..95479b315918 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -624,6 +624,7 @@ struct rdists { u64 flags; u32 gicd_typer; u32 gicd_typer2; + int cpuhp_memreserve_state; bool has_vlpis; bool has_rvpeid; bool has_direct_lpi;