From patchwork Mon Jan 30 15:31:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 9545621 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A7CE260415 for ; Mon, 30 Jan 2017 15:34:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 968E627BA5 for ; Mon, 30 Jan 2017 15:34:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B43928138; Mon, 30 Jan 2017 15:34:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00 autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 42AA22808C for ; Mon, 30 Jan 2017 15:34:38 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cYDyO-0002yY-6Z; Mon, 30 Jan 2017 15:34:28 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cYDwp-000192-I4 for linux-arm-kernel@lists.infradead.org; Mon, 30 Jan 2017 15:33:12 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7665F14F6; Mon, 30 Jan 2017 07:32:31 -0800 (PST) Received: from leverpostej.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DA0B93F477; Mon, 30 Jan 2017 07:32:30 -0800 (PST) From: Mark Rutland To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 1/3] drivers/perf: arm_pmu: rework per-cpu allocation Date: Mon, 30 Jan 2017 15:31:17 +0000 Message-Id: <1485790279-3139-2-git-send-email-mark.rutland@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1485790279-3139-1-git-send-email-mark.rutland@arm.com> References: <1485790279-3139-1-git-send-email-mark.rutland@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170130_073252_377760_0D3B8C33 X-CRM114-Status: GOOD ( 12.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, will.deacon@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP For historical reasons, we allocate per-cpu data associated with a PMU rather late, in cpu_pmu_init, after we've parsed whatever hardware information we were provided with. In order to allow use to store some per-cpu data early in the probe path, we need to allocate (and initialise) the per-cpu data earlier. This patch reworks the way we allocate the pmu and associated per-cpu data in order to make that possible. Signed-off-by: Mark Rutland Cc: Will Deacon --- drivers/perf/arm_pmu.c | 64 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 6d93358..dc4c8aa 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -827,29 +827,16 @@ static inline void cpu_pm_pmu_unregister(struct arm_pmu *cpu_pmu) { } static int cpu_pmu_init(struct arm_pmu *cpu_pmu) { int err; - int cpu; - struct pmu_hw_events __percpu *cpu_hw_events; - - cpu_hw_events = alloc_percpu(struct pmu_hw_events); - if (!cpu_hw_events) - return -ENOMEM; err = cpuhp_state_add_instance_nocalls(CPUHP_AP_PERF_ARM_STARTING, &cpu_pmu->node); if (err) - goto out_free; + goto out; err = cpu_pm_pmu_register(cpu_pmu); if (err) goto out_unregister; - for_each_possible_cpu(cpu) { - struct pmu_hw_events *events = per_cpu_ptr(cpu_hw_events, cpu); - raw_spin_lock_init(&events->pmu_lock); - events->percpu_pmu = cpu_pmu; - } - - cpu_pmu->hw_events = cpu_hw_events; cpu_pmu->request_irq = cpu_pmu_request_irq; cpu_pmu->free_irq = cpu_pmu_free_irq; @@ -875,8 +862,7 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu) out_unregister: cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_STARTING, &cpu_pmu->node); -out_free: - free_percpu(cpu_hw_events); +out: return err; } @@ -1007,6 +993,45 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu) return 0; } +struct arm_pmu *armpmu_alloc(void) +{ + struct arm_pmu *pmu; + int cpu; + + pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + if (!pmu) { + pr_info("failed to allocate PMU device!\n"); + goto out; + } + + pmu->hw_events = alloc_percpu(struct pmu_hw_events); + if (!pmu->hw_events) { + pr_info("failed to allocate per-cpu PMU data.\n"); + goto out_free_pmu; + } + + for_each_possible_cpu(cpu) { + struct pmu_hw_events *events; + + events = per_cpu_ptr(pmu->hw_events, cpu); + raw_spin_lock_init(&events->pmu_lock); + events->percpu_pmu = pmu; + } + + return pmu; + +out_free_pmu: + kfree(pmu); +out: + return NULL; +} + +void armpmu_free(struct arm_pmu *pmu) +{ + free_percpu(pmu->hw_events); + kfree(pmu); +} + int arm_pmu_device_probe(struct platform_device *pdev, const struct of_device_id *of_table, const struct pmu_probe_info *probe_table) @@ -1017,11 +1042,9 @@ int arm_pmu_device_probe(struct platform_device *pdev, struct arm_pmu *pmu; int ret = -ENODEV; - pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL); - if (!pmu) { - pr_info("failed to allocate PMU device!\n"); + pmu = armpmu_alloc(); + if (!pmu) return -ENOMEM; - } armpmu_init(pmu); @@ -1075,7 +1098,6 @@ int arm_pmu_device_probe(struct platform_device *pdev, pr_info("%s: failed to register PMU devices!\n", of_node_full_name(node)); kfree(pmu->irq_affinity); - kfree(pmu); return ret; }