Message ID | 20230105031039.207972-4-anshuman.khandual@arm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp94355wrt; Wed, 4 Jan 2023 19:13:55 -0800 (PST) X-Google-Smtp-Source: AMrXdXuiVtwDRR5Xs41PXaZcW8xjOIuP26JPmIDNOyHLi5v3I24TdQfnWGw4EV5Stjj/C/xOp5Xg X-Received: by 2002:a05:6a21:339b:b0:ad:c97f:1c1b with SMTP id yy27-20020a056a21339b00b000adc97f1c1bmr76804463pzb.0.1672888435044; Wed, 04 Jan 2023 19:13:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672888435; cv=none; d=google.com; s=arc-20160816; b=mvYVFlC9gYLK7tVsClFQLKViLUULXvcmRfAV62XGG2u12gXYofOpDLe21AnJ/n6QWE B8966aoEQjKFtsdj1N4rbExqtFhGhIZsNZUFYnHv8oIrMKXwzFSaFfhZtkqq7T7QaETL iqsNUt6aUeZH8RI7fG2z2pYrZp/vegV/nJCv1BTgovSA0noUUKxO0AH+D1rKj4ZXCrbU t/56g6qF7WtwipLCScORYICWdiminXjjvASk5FHMr5f2vu/iXcfHL+RhySSZgiyrS4iC rLOcc37jvw4rhW7nkisvLsuLRmCvBv9r8TalSkG6nkiSDEkTCr5GEl4dE9NTwdTCSfFx JqAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Z45+2LpVGI3TFrkRHBTpAMIKrSVhsm4SydnZPAG/k/M=; b=OtD0HMgcLB6XvXl4EDceBtMEcwmPv7yRFvuqwZ4fsKYwJvJIkOCgfRpMHRCujm9V/g cnEtEYwB7QNdRPhFLeA7rQgPloCGFj3ch8LdXVQdPvkZcur+FFqG5EuAkzuCWIuVb4h6 MllGeONnbuaXJVyiuWVk3bnDUYySoiPxqtt2aimgoILYtk0R1CXEOxpk+gMM1VwOcsDN KIPIibpmh7mpPE+FscFacGyeTYqyu515aS1230uvteh0tb/BytN8IZr1eSCpFteeZmWV F4YCh/I4R1S5ZPWGs2GCJRv5LJTSLfP03tSuVzsKpbSnnsmER5Wyvvz4/k8qndOLKaDU 3knA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e14-20020a63d94e000000b00496731929d6si32117735pgj.780.2023.01.04.19.13.38; Wed, 04 Jan 2023 19:13:55 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230110AbjAEDLO (ORCPT <rfc822;tmhikaru@gmail.com> + 99 others); Wed, 4 Jan 2023 22:11:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229588AbjAEDLF (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 4 Jan 2023 22:11:05 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8FDBD11178 for <linux-kernel@vger.kernel.org>; Wed, 4 Jan 2023 19:11:02 -0800 (PST) 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 1CF2016A3; Wed, 4 Jan 2023 19:11:44 -0800 (PST) Received: from a077893.blr.arm.com (unknown [10.162.43.6]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 02C443F663; Wed, 4 Jan 2023 19:10:59 -0800 (PST) From: Anshuman Khandual <anshuman.khandual@arm.com> To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, mark.rutland@arm.com Cc: Anshuman Khandual <anshuman.khandual@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org> Subject: [PATCH V7 3/6] arm64/perf: Add branch stack support in struct arm_pmu Date: Thu, 5 Jan 2023 08:40:36 +0530 Message-Id: <20230105031039.207972-4-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230105031039.207972-1-anshuman.khandual@arm.com> References: <20230105031039.207972-1-anshuman.khandual@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1754150663353788299?= X-GMAIL-MSGID: =?utf-8?q?1754150663353788299?= |
Series |
arm64/perf: Enable branch stack sampling
|
|
Commit Message
Anshuman Khandual
Jan. 5, 2023, 3:10 a.m. UTC
This updates 'struct arm_pmu' for branch stack sampling support later. This
adds a new 'features' element in the structure to track supported features,
and another 'private' element to encapsulate implementation attributes on a
given 'struct arm_pmu'. These updates here will help in tracking any branch
stack sampling support, which is being added later. This also adds a helper
arm_pmu_branch_stack_supported().
This also enables perf branch stack sampling event on all 'struct arm pmu',
supporting the feature but after removing the current gate that blocks such
events unconditionally in armpmu_event_init(). Instead a quick probe can be
initiated via arm_pmu_branch_stack_supported() to ascertain the support.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
drivers/perf/arm_pmu.c | 3 +--
include/linux/perf/arm_pmu.h | 9 +++++++++
2 files changed, 10 insertions(+), 2 deletions(-)
Comments
On Thu, Jan 05, 2023 at 08:40:36AM +0530, Anshuman Khandual wrote: > This updates 'struct arm_pmu' for branch stack sampling support later. This > adds a new 'features' element in the structure to track supported features, > and another 'private' element to encapsulate implementation attributes on a > given 'struct arm_pmu'. These updates here will help in tracking any branch > stack sampling support, which is being added later. This also adds a helper > arm_pmu_branch_stack_supported(). > > This also enables perf branch stack sampling event on all 'struct arm pmu', > supporting the feature but after removing the current gate that blocks such > events unconditionally in armpmu_event_init(). Instead a quick probe can be > initiated via arm_pmu_branch_stack_supported() to ascertain the support. > > Cc: Catalin Marinas <catalin.marinas@arm.com> > Cc: Will Deacon <will@kernel.org> > Cc: Mark Rutland <mark.rutland@arm.com> > Cc: linux-arm-kernel@lists.infradead.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> > --- > drivers/perf/arm_pmu.c | 3 +-- > include/linux/perf/arm_pmu.h | 9 +++++++++ > 2 files changed, 10 insertions(+), 2 deletions(-) > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c > index 14a3ed3bdb0b..a85b2d67022e 100644 > --- a/drivers/perf/arm_pmu.c > +++ b/drivers/perf/arm_pmu.c > @@ -510,8 +510,7 @@ static int armpmu_event_init(struct perf_event *event) > !cpumask_test_cpu(event->cpu, &armpmu->supported_cpus)) > return -ENOENT; > > - /* does not support taken branch sampling */ > - if (has_branch_stack(event)) > + if (has_branch_stack(event) && !arm_pmu_branch_stack_supported(armpmu)) > return -EOPNOTSUPP; > > return __hw_perf_event_init(event); > diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h > index 2a9d07cee927..64e1b2594025 100644 > --- a/include/linux/perf/arm_pmu.h > +++ b/include/linux/perf/arm_pmu.h > @@ -80,11 +80,14 @@ enum armpmu_attr_groups { > ARMPMU_NR_ATTR_GROUPS > }; > > +#define ARM_PMU_BRANCH_STACK BIT(0) > + > struct arm_pmu { > struct pmu pmu; > cpumask_t supported_cpus; > char *name; > int pmuver; > + int features; > irqreturn_t (*handle_irq)(struct arm_pmu *pmu); > void (*enable)(struct perf_event *event); > void (*disable)(struct perf_event *event); Hmm, we already have the secure_access field separately. How about we fold that in and go with: unsigned int secure_access : 1, has_branch_stack : 1; ... that way we have one way to manage flags, we don't need to allocate the bits, and the bulk of the existing code for secure_access can stay as-is. > @@ -119,8 +122,14 @@ struct arm_pmu { > > /* Only to be used by ACPI probing code */ > unsigned long acpi_cpuid; > + void *private; Does this need to be on the end of struct arm_pmu, or can it be placed earlier? The line spacing makes it look like the ACPI comment applies to 'private', which isn't the case. > }; > > +static inline bool arm_pmu_branch_stack_supported(struct arm_pmu *armpmu) > +{ > + return armpmu->features & ARM_PMU_BRANCH_STACK; > +} With the above, this would become: static inline bool arm_pmu_branch_stack_supported(struct arm_pmu *armpmu) { return armpmu->has_branch_stack; } Thanks, Mark. > + > #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) > > u64 armpmu_event_update(struct perf_event *event); > -- > 2.25.1 >
On 1/12/23 19:24, Mark Rutland wrote: > On Thu, Jan 05, 2023 at 08:40:36AM +0530, Anshuman Khandual wrote: >> This updates 'struct arm_pmu' for branch stack sampling support later. This >> adds a new 'features' element in the structure to track supported features, >> and another 'private' element to encapsulate implementation attributes on a >> given 'struct arm_pmu'. These updates here will help in tracking any branch >> stack sampling support, which is being added later. This also adds a helper >> arm_pmu_branch_stack_supported(). >> >> This also enables perf branch stack sampling event on all 'struct arm pmu', >> supporting the feature but after removing the current gate that blocks such >> events unconditionally in armpmu_event_init(). Instead a quick probe can be >> initiated via arm_pmu_branch_stack_supported() to ascertain the support. >> >> Cc: Catalin Marinas <catalin.marinas@arm.com> >> Cc: Will Deacon <will@kernel.org> >> Cc: Mark Rutland <mark.rutland@arm.com> >> Cc: linux-arm-kernel@lists.infradead.org >> Cc: linux-kernel@vger.kernel.org >> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> >> --- >> drivers/perf/arm_pmu.c | 3 +-- >> include/linux/perf/arm_pmu.h | 9 +++++++++ >> 2 files changed, 10 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c >> index 14a3ed3bdb0b..a85b2d67022e 100644 >> --- a/drivers/perf/arm_pmu.c >> +++ b/drivers/perf/arm_pmu.c >> @@ -510,8 +510,7 @@ static int armpmu_event_init(struct perf_event *event) >> !cpumask_test_cpu(event->cpu, &armpmu->supported_cpus)) >> return -ENOENT; >> >> - /* does not support taken branch sampling */ >> - if (has_branch_stack(event)) >> + if (has_branch_stack(event) && !arm_pmu_branch_stack_supported(armpmu)) >> return -EOPNOTSUPP; >> >> return __hw_perf_event_init(event); >> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h >> index 2a9d07cee927..64e1b2594025 100644 >> --- a/include/linux/perf/arm_pmu.h >> +++ b/include/linux/perf/arm_pmu.h >> @@ -80,11 +80,14 @@ enum armpmu_attr_groups { >> ARMPMU_NR_ATTR_GROUPS >> }; >> >> +#define ARM_PMU_BRANCH_STACK BIT(0) >> + >> struct arm_pmu { >> struct pmu pmu; >> cpumask_t supported_cpus; >> char *name; >> int pmuver; >> + int features; >> irqreturn_t (*handle_irq)(struct arm_pmu *pmu); >> void (*enable)(struct perf_event *event); >> void (*disable)(struct perf_event *event); > > Hmm, we already have the secure_access field separately. How about we fold that > in and go with: > > unsigned int secure_access : 1, > has_branch_stack : 1; Something like this would work, but should we use __u32 instead of unsigned int to ensure 32 bit width ? - bool secure_access; /* 32-bit ARM only */ + unsigned int secure_access : 1, /* 32-bit ARM only */ + has_branch_stack: 1, + reserved : 31; > > ... that way we have one way to manage flags, we don't need to allocate the > bits, and the bulk of the existing code for secure_access can stay as-is. Right, the changed code also builds on arm32 without any code change. > >> @@ -119,8 +122,14 @@ struct arm_pmu { >> >> /* Only to be used by ACPI probing code */ >> unsigned long acpi_cpuid; >> + void *private; > > Does this need to be on the end of struct arm_pmu, or can it be placed earlier? This additional 'private' attribute structure sticking out from struct arm_pmu should be at the end. But is there any benefit moving this earlier ? > > The line spacing makes it look like the ACPI comment applies to 'private', > which isn't the case. Sure, will add the following comment, and a space in between. diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index f60f7e01acae..c0a090ff7991 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -130,6 +130,8 @@ struct arm_pmu { /* Only to be used by ACPI probing code */ unsigned long acpi_cpuid; + + /* Implementation specific attributes */ void *private; }; > >> }; >> >> +static inline bool arm_pmu_branch_stack_supported(struct arm_pmu *armpmu) >> +{ >> + return armpmu->features & ARM_PMU_BRANCH_STACK; >> +} > > With the above, this would become: > > static inline bool arm_pmu_branch_stack_supported(struct arm_pmu *armpmu) > { > return armpmu->has_branch_stack; > } Right, will change this helper as required.
On Fri, Jan 13, 2023 at 09:45:22AM +0530, Anshuman Khandual wrote: > > On 1/12/23 19:24, Mark Rutland wrote: > > On Thu, Jan 05, 2023 at 08:40:36AM +0530, Anshuman Khandual wrote: > >> struct arm_pmu { > >> struct pmu pmu; > >> cpumask_t supported_cpus; > >> char *name; > >> int pmuver; > >> + int features; > >> irqreturn_t (*handle_irq)(struct arm_pmu *pmu); > >> void (*enable)(struct perf_event *event); > >> void (*disable)(struct perf_event *event); > > > > Hmm, we already have the secure_access field separately. How about we fold that > > in and go with: > > > > unsigned int secure_access : 1, > > has_branch_stack : 1; > > Something like this would work, but should we use __u32 instead of unsigned int > to ensure 32 bit width ? I don't think that's necessary; the exact size doesn't really matter, and unsigned int is 32-bits on all targets suppropted by Linux, not just arm and arm64. I do agree that if this were a userspace ABI detail, it might be preferable to use __u32. However, I think using it here gives the misleading impression that there is an ABI concern when there is not, and as above it's not necessary, so I'd prefer unsigned int here. Thanks, Mark.
On 2/9/23 00:56, Mark Rutland wrote: > On Fri, Jan 13, 2023 at 09:45:22AM +0530, Anshuman Khandual wrote: >> >> On 1/12/23 19:24, Mark Rutland wrote: >>> On Thu, Jan 05, 2023 at 08:40:36AM +0530, Anshuman Khandual wrote: >>>> struct arm_pmu { >>>> struct pmu pmu; >>>> cpumask_t supported_cpus; >>>> char *name; >>>> int pmuver; >>>> + int features; >>>> irqreturn_t (*handle_irq)(struct arm_pmu *pmu); >>>> void (*enable)(struct perf_event *event); >>>> void (*disable)(struct perf_event *event); >>> >>> Hmm, we already have the secure_access field separately. How about we fold that >>> in and go with: >>> >>> unsigned int secure_access : 1, >>> has_branch_stack : 1; >> >> Something like this would work, but should we use __u32 instead of unsigned int >> to ensure 32 bit width ? > > I don't think that's necessary; the exact size doesn't really matter, and > unsigned int is 32-bits on all targets suppropted by Linux, not just arm and > arm64. > > I do agree that if this were a userspace ABI detail, it might be preferable to > use __u32. However, I think using it here gives the misleading impression that > there is an ABI concern when there is not, and as above it's not necessary, so > I'd prefer unsigned int here. Makes sense, will this as unsigned int.
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 14a3ed3bdb0b..a85b2d67022e 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -510,8 +510,7 @@ static int armpmu_event_init(struct perf_event *event) !cpumask_test_cpu(event->cpu, &armpmu->supported_cpus)) return -ENOENT; - /* does not support taken branch sampling */ - if (has_branch_stack(event)) + if (has_branch_stack(event) && !arm_pmu_branch_stack_supported(armpmu)) return -EOPNOTSUPP; return __hw_perf_event_init(event); diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 2a9d07cee927..64e1b2594025 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -80,11 +80,14 @@ enum armpmu_attr_groups { ARMPMU_NR_ATTR_GROUPS }; +#define ARM_PMU_BRANCH_STACK BIT(0) + struct arm_pmu { struct pmu pmu; cpumask_t supported_cpus; char *name; int pmuver; + int features; irqreturn_t (*handle_irq)(struct arm_pmu *pmu); void (*enable)(struct perf_event *event); void (*disable)(struct perf_event *event); @@ -119,8 +122,14 @@ struct arm_pmu { /* Only to be used by ACPI probing code */ unsigned long acpi_cpuid; + void *private; }; +static inline bool arm_pmu_branch_stack_supported(struct arm_pmu *armpmu) +{ + return armpmu->features & ARM_PMU_BRANCH_STACK; +} + #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) u64 armpmu_event_update(struct perf_event *event);