Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp467964pxa; Wed, 19 Aug 2020 06:35:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzt6dNCRfpcxsRXdOEFwGn530iNrUyqcxSD4GdJPYJyXg8uBqMAxXUbVIWiQsz1Z/uYL+3h X-Received: by 2002:a17:906:2506:: with SMTP id i6mr24484631ejb.72.1597844115481; Wed, 19 Aug 2020 06:35:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597844115; cv=none; d=google.com; s=arc-20160816; b=jFuPRQ1ugUJ9c0Va5KH9dhxII0/NG42T96ugewl5WGBlG2SApe7XAIeINnbTAgsX9N SRR+N20ccuvzpNS/6yf65fsXMlWNvZuHIvnqxsXQZOYoVsrz6nTBhTF7XPgJ4zIuCbDg Wyy50X0+q1OgoUEYd69BU3T6hXBjBAQuTt6VazAWm/7vn56W69H7WJ0bEj6CGg4GX6Sl uvH7pQFVWiiKuZHdaFbGCqnhp10YZmxqZZ7E6luM4xtKaLAYfOjLLyfvkrlKJGselyQp FAoStAmJbfyeiI8xba0LVGq8uxdjXgkhMd2PscTFgUNNPQbW260Kj1RG0jlp/XOYxDyP 1ACg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=aPJZyRH0u66v1AFqzAX7ZkUo6W71SY/y8+sa0bp+Hbs=; b=vOjbCUhXNEGvOKXHeoRyXtper3c1iG4WFVoRf9YJDAQpk17ktHw5+zbE+RASr2Y6sW DVEI0/VlzwqX981K2s2AWplRkIIEHjwbyX0oKUlYd7/f7iYxAjuiQhXgNK25ApDFeAp0 hEZ4Zh2Dd8kknHMSixbygohiJF92Fl/tfyZDSELcQF8vsjL3Oh7tG0WxhZukcIt/ovaT bNAqFIroRR9X5Gac+Ep4kkMvAYvxg36h6TjrStKrhScqrrDgS9ff6OdHv0sam507klor sat8hnpMogrVCLNYdKsHFnajlKGy9TMX/SYM9ceHPPw4N4fCk/2zGDuSp1TaY9EPk6Ok Fbow== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id od24si16084804ejb.630.2020.08.19.06.34.50; Wed, 19 Aug 2020 06:35:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728590AbgHSNd4 (ORCPT + 99 others); Wed, 19 Aug 2020 09:33:56 -0400 Received: from foss.arm.com ([217.140.110.172]:36996 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728558AbgHSNds (ORCPT ); Wed, 19 Aug 2020 09:33:48 -0400 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 649E71435; Wed, 19 Aug 2020 06:33:43 -0700 (PDT) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E42F63F71F; Wed, 19 Aug 2020 06:33:41 -0700 (PDT) From: Alexandru Elisei To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: mark.rutland@arm.com, maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, swboyd@chromium.org, sumit.garg@linaro.org, Julien Thierry , Julien Thierry , Will Deacon Subject: [PATCH v6 7/7] arm_pmu: arm64: Use NMIs for PMU Date: Wed, 19 Aug 2020 14:34:19 +0100 Message-Id: <20200819133419.526889-8-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200819133419.526889-1-alexandru.elisei@arm.com> References: <20200819133419.526889-1-alexandru.elisei@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Julien Thierry Add required PMU interrupt operations for NMIs. Request interrupt lines as NMIs when possible, otherwise fall back to normal interrupts. NMIs are only supported on the arm64 architecture with a GICv3 irqchip. Cc: Julien Thierry Cc: Will Deacon Cc: Mark Rutland Signed-off-by: Julien Thierry [Added that NMIs only work on arm64 + GICv3] Signed-off-by: Alexandru Elisei --- drivers/perf/arm_pmu.c | 62 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 17e5952d21e4..dd9d7f61ee29 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -45,6 +45,17 @@ static const struct pmu_irq_ops pmuirq_ops = { .free_pmuirq = armpmu_free_pmuirq }; +static void armpmu_free_pmunmi(unsigned int irq, int cpu, void __percpu *devid) +{ + free_nmi(irq, per_cpu_ptr(devid, cpu)); +} + +static const struct pmu_irq_ops pmunmi_ops = { + .enable_pmuirq = enable_nmi, + .disable_pmuirq = disable_nmi_nosync, + .free_pmuirq = armpmu_free_pmunmi +}; + static void armpmu_enable_percpu_pmuirq(unsigned int irq) { enable_percpu_irq(irq, IRQ_TYPE_NONE); @@ -63,6 +74,31 @@ static const struct pmu_irq_ops percpu_pmuirq_ops = { .free_pmuirq = armpmu_free_percpu_pmuirq }; +static void armpmu_enable_percpu_pmunmi(unsigned int irq) +{ + if (!prepare_percpu_nmi(irq)) + enable_percpu_nmi(irq, IRQ_TYPE_NONE); +} + +static void armpmu_disable_percpu_pmunmi(unsigned int irq) +{ + disable_percpu_nmi(irq); + teardown_percpu_nmi(irq); +} + +static void armpmu_free_percpu_pmunmi(unsigned int irq, int cpu, + void __percpu *devid) +{ + if (armpmu_count_irq_users(irq) == 1) + free_percpu_nmi(irq, devid); +} + +static const struct pmu_irq_ops percpu_pmunmi_ops = { + .enable_pmuirq = armpmu_enable_percpu_pmunmi, + .disable_pmuirq = armpmu_disable_percpu_pmunmi, + .free_pmuirq = armpmu_free_percpu_pmunmi +}; + static DEFINE_PER_CPU(struct arm_pmu *, cpu_armpmu); static DEFINE_PER_CPU(int, cpu_irq); static DEFINE_PER_CPU(const struct pmu_irq_ops *, cpu_irq_ops); @@ -633,15 +669,29 @@ int armpmu_request_irq(int irq, int cpu) IRQF_NO_THREAD; irq_set_status_flags(irq, IRQ_NOAUTOEN); - err = request_irq(irq, handler, irq_flags, "arm-pmu", + + err = request_nmi(irq, handler, irq_flags, "arm-pmu", per_cpu_ptr(&cpu_armpmu, cpu)); - irq_ops = &pmuirq_ops; + /* If cannot get an NMI, get a normal interrupt */ + if (err) { + err = request_irq(irq, handler, irq_flags, "arm-pmu", + per_cpu_ptr(&cpu_armpmu, cpu)); + irq_ops = &pmuirq_ops; + } else { + irq_ops = &pmunmi_ops; + } } else if (armpmu_count_irq_users(irq) == 0) { - err = request_percpu_irq(irq, handler, "arm-pmu", - &cpu_armpmu); - - irq_ops = &percpu_pmuirq_ops; + err = request_percpu_nmi(irq, handler, "arm-pmu", &cpu_armpmu); + + /* If cannot get an NMI, get a normal interrupt */ + if (err) { + err = request_percpu_irq(irq, handler, "arm-pmu", + &cpu_armpmu); + irq_ops = &percpu_pmuirq_ops; + } else { + irq_ops = &percpu_pmunmi_ops; + } } else { /* Per cpudevid irq was already requested by another CPU */ irq_ops = armpmu_find_irq_ops(irq); -- 2.28.0