Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp421228ybt; Wed, 17 Jun 2020 04:41:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzM5EZUxckMVLFIBFowNYXi0d/rUdHlslueyVD6BeFCXAGthYVrlKCQsV8ydtKZB64gj1tR X-Received: by 2002:a17:906:1d5b:: with SMTP id o27mr7017515ejh.344.1592394091444; Wed, 17 Jun 2020 04:41:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592394091; cv=none; d=google.com; s=arc-20160816; b=CmAaCrHhlFLVTV4zipioEubcYGGz4EkE824ffK+IZ7uPIuoQYTNmkhia0PfhRWLyB4 bu+SaCiGIMvQgE6BW1Ob9Uk7FtODBszd5V1Pi3Umo0WMnvYwTAMb9wGNu6M3IGOk+17h ampbfJJQhl+NOMGpscMZ6heCWoRhWanb3/D/KPtw2BZeIQl+4nEHqcd4BOLvgbpWbqmE Udi7wMmndhEQZlUjN5sf2maPeGBREW6aG7TBNQpOdsVJRKxF8P2fCZM/82TykttERTkr JDzP5grRki/yS00PmG6gsaelMEWx6dEyRpehU9a9gjnnV0TqJo+k24qfawtp9T1Jh2kQ SEMQ== 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=q9jPWKJmumKJVNjHz87/Y2cdosZf0UtHjtjS9jtfxCY=; b=o3DG7K263kbgxfOXDxviSCZFn+w5O5M6YyC8DD4FSTnnmgwMLo42lu2rq/CE9TjIty +KUXSHYI4Z1YCeLeEQNLrkVsBXlMGtAO7i00AF+/o7MClApoPUR+4T6r9fCPsQfQgW0g Fue9fDvdTv8UPXNnZVAmQlWr+hc0gT/pmspmJW3ZVKfKCE2MHlDlPsz51MO+V0CsjNLV qib+1B0ARZbVm6bD8XIKwr9TDmSdEQzv8KDnHsFBoxBtQ2I4EYwa2Scdb5BoBhDMJ2mZ hUMTBHlJxZjwpsGw1IdVEo34/kukYhgvyIFT8D2EZPdFa7vGGc1imDmVM13fSuL7/JmV Q8pw== 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 y14si12453760edu.550.2020.06.17.04.41.08; Wed, 17 Jun 2020 04:41:31 -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 S1727018AbgFQLip (ORCPT + 99 others); Wed, 17 Jun 2020 07:38:45 -0400 Received: from foss.arm.com ([217.140.110.172]:56326 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726988AbgFQLih (ORCPT ); Wed, 17 Jun 2020 07:38:37 -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 91C271045; Wed, 17 Jun 2020 04:38:36 -0700 (PDT) Received: from monolith.arm.com (unknown [10.37.8.7]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D64B03F71F; Wed, 17 Jun 2020 04:38:34 -0700 (PDT) From: Alexandru Elisei To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, mark.rutland@arm.com, Julien Thierry , Julien Thierry , Will Deacon Subject: [PATCH v5 7/7] arm_pmu: arm64: Use NMIs for PMU Date: Wed, 17 Jun 2020 12:38:51 +0100 Message-Id: <20200617113851.607706-8-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200617113851.607706-1-alexandru.elisei@arm.com> References: <20200617113851.607706-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.27.0