From patchwork Tue Sep 19 09:51:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Clark X-Patchwork-Id: 13391081 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id CDC32CD54A9 for ; Tue, 19 Sep 2023 09:52:37 +0000 (UTC) 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=lxY5DKoX56UpRtyDJuU6NZiF9efMcereuRqbiHeseJ0=; b=KrkcUAjKPd+uTd c6GCj+jeFBNzyRlni8225zt0MiszpeU0JgMWJXyHMgtR7K15yyD+0RwyKq6Pf0ChIHL1hOP6JvwE/ MyoufTOB1g94gjL90JK0s2Jbty8P41Ie/VqCAryG7S3Fu/LpTFldA9wszy/PfDIO3UPuqZXwthu7V aW8g2jH959Msf2L7jcrgocmW0VW8Dp2Ea/WTUcqwXhUyQe/LyfOMNkJhUOLjVcmL36nkwwhqBaBv4 C5qiFmGhBSBGVLTNqXnE8kuPScyH5P+0XajzgIy+Kipb+x8K00MRyBUxz+o59XMc0uZ29WZ6BdCRE Dnc6LlNq+NPWwdGCuoBQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qiXOu-00HYG4-31; Tue, 19 Sep 2023 09:52:12 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qiXOr-00HYEu-1O for linux-arm-kernel@lists.infradead.org; Tue, 19 Sep 2023 09:52:11 +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 CE5FC1FB; Tue, 19 Sep 2023 02:52:43 -0700 (PDT) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E9A833F67D; Tue, 19 Sep 2023 02:52:04 -0700 (PDT) From: James Clark To: linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: James Clark , Catalin Marinas , Will Deacon , Jonathan Corbet , Mark Rutland , Marc Zyngier , Zaid Al-Bassam , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 1/2] arm64: perf: Add support for event counting threshold Date: Tue, 19 Sep 2023 10:51:28 +0100 Message-Id: <20230919095137.360963-2-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230919095137.360963-1-james.clark@arm.com> References: <20230919095137.360963-1-james.clark@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230919_025209_561154_AEF81D3E X-CRM114-Status: GOOD ( 22.04 ) 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 FEAT_PMUv3_TH (Armv8.8) permits a PMU counter to increment only on events whose count meets a specified threshold condition. For example if PMEVTYPERn.TC (Threshold Control) is set to 0b101 (Greater than or equal, count), and the threshold is set to 2, then the PMU counter will now only increment by 1 when an event would have previously incremented the PMU counter by 2 or more on a single processor cycle. Two new Perf event config fields, 'threshold' and 'threshold_control' have been added for controlling the feature: $ perf stat -e stall_slot/threshold=2,threshold_control=5/ A new capability for reading out the maximum supported threshold value has also been added: $ cat /sys/bus/event_source/devices/armv8_pmuv3/caps/threshold_max 0x000000ff If a threshold higher than threshold_max is provided, then no error is generated but the threshold is clamped to the max value. If FEAT_PMUv3_TH isn't implemented, then threshold_max reads zero, and neither the 'threshold' nor 'threshold_control' parameters will be used. The threshold is per PMU counter, and there are potentially different threshold_max values per PMU type on heterogeneous systems. Bits higher than 32 now need to be written into PMEVTYPER, so armv8pmu_write_evtype() has to be updated to take a u64 value rather than u32. Signed-off-by: James Clark --- drivers/perf/arm_pmuv3.c | 59 +++++++++++++++++++++++++++++++++- include/linux/perf/arm_pmuv3.h | 7 +++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c index e5a2ac4155f6..ad6574b2bdab 100644 --- a/drivers/perf/arm_pmuv3.c +++ b/drivers/perf/arm_pmuv3.c @@ -294,9 +294,16 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = { .is_visible = armv8pmu_event_attr_is_visible, }; +#define TH_LO 2 +#define TH_HI 13 +#define TH_CNTL_LO 14 +#define TH_CNTL_HI 16 + PMU_FORMAT_ATTR(event, "config:0-15"); PMU_FORMAT_ATTR(long, "config1:0"); PMU_FORMAT_ATTR(rdpmc, "config1:1"); +PMU_FORMAT_ATTR(threshold, "config1:" __stringify(TH_LO) "-" __stringify(TH_HI)); +PMU_FORMAT_ATTR(threshold_control, "config1:" __stringify(TH_CNTL_LO) "-" __stringify(TH_CNTL_HI)); static int sysctl_perf_user_access __read_mostly; @@ -310,10 +317,22 @@ static inline bool armv8pmu_event_want_user_access(struct perf_event *event) return event->attr.config1 & 0x2; } +static inline u32 armv8pmu_event_threshold(struct perf_event_attr *attr) +{ + return FIELD_GET(GENMASK(TH_HI, TH_LO), attr->config1); +} + +static inline u8 armv8pmu_event_threshold_control(struct perf_event_attr *attr) +{ + return FIELD_GET(GENMASK(TH_CNTL_HI, TH_CNTL_LO), attr->config1); +} + static struct attribute *armv8_pmuv3_format_attrs[] = { &format_attr_event.attr, &format_attr_long.attr, &format_attr_rdpmc.attr, + &format_attr_threshold.attr, + &format_attr_threshold_control.attr, NULL, }; @@ -365,10 +384,31 @@ static ssize_t bus_width_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(bus_width); +static u32 threshold_max(struct arm_pmu *cpu_pmu) +{ + /* + * The largest value that can be written to PMEVTYPER_EL0.TH is + * (2 ^ PMMIR.THWIDTH) - 1 + */ + return (1 << FIELD_GET(ARMV8_PMU_THWIDTH, cpu_pmu->reg_pmmir)) - 1; +} + +static ssize_t threshold_max_show(struct device *dev, + struct device_attribute *attr, char *page) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); + + return sysfs_emit(page, "0x%08x\n", threshold_max(cpu_pmu)); +} + +static DEVICE_ATTR_RO(threshold_max); + static struct attribute *armv8_pmuv3_caps_attrs[] = { &dev_attr_slots.attr, &dev_attr_bus_slots.attr, &dev_attr_bus_width.attr, + &dev_attr_threshold_max.attr, NULL, }; @@ -552,7 +592,7 @@ static void armv8pmu_write_counter(struct perf_event *event, u64 value) armv8pmu_write_hw_counter(event, value); } -static inline void armv8pmu_write_evtype(int idx, u32 val) +static inline void armv8pmu_write_evtype(int idx, u64 val) { u32 counter = ARMV8_IDX_TO_COUNTER(idx); @@ -912,6 +952,10 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event, struct perf_event_attr *attr) { unsigned long config_base = 0; + struct perf_event *perf_event = container_of(attr, struct perf_event, + attr); + struct arm_pmu *cpu_pmu = to_arm_pmu(perf_event->pmu); + u32 th, th_max; if (attr->exclude_idle) return -EPERM; @@ -943,6 +987,19 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event, if (attr->exclude_user) config_base |= ARMV8_PMU_EXCLUDE_EL0; + /* + * Insert event counting threshold (FEAT_PMUv3_TH) values. If + * FEAT_PMUv3_TH isn't implemented, then THWIDTH (threshold_max) will be + * 0 and no values will be written. + */ + th_max = threshold_max(cpu_pmu); + if (th_max) { + th = min(armv8pmu_event_threshold(attr), th_max); + config_base |= FIELD_PREP(ARMV8_PMU_EVTYPE_TH, th); + config_base |= FIELD_PREP(ARMV8_PMU_EVTYPE_TC, + armv8pmu_event_threshold_control(attr)); + } + /* * Install the filter into config_base as this is used to * construct the event type. diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h index e3899bd77f5c..0e2a3c927150 100644 --- a/include/linux/perf/arm_pmuv3.h +++ b/include/linux/perf/arm_pmuv3.h @@ -228,7 +228,11 @@ /* * PMXEVTYPER: Event selection reg */ -#define ARMV8_PMU_EVTYPE_MASK 0xc800ffff /* Mask for writable bits */ +#define ARMV8_PMU_EVTYPE_TH GENMASK(43, 32) +#define ARMV8_PMU_EVTYPE_TC GENMASK(63, 61) +/* Mask for writable bits */ +#define ARMV8_PMU_EVTYPE_MASK (0xc800ffff | ARMV8_PMU_EVTYPE_TH | \ + ARMV8_PMU_EVTYPE_TC) #define ARMV8_PMU_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */ /* @@ -254,6 +258,7 @@ #define ARMV8_PMU_BUS_SLOTS_MASK 0xff #define ARMV8_PMU_BUS_WIDTH_SHIFT 16 #define ARMV8_PMU_BUS_WIDTH_MASK 0xf +#define ARMV8_PMU_THWIDTH GENMASK(23, 20) /* * This code is really good From patchwork Tue Sep 19 09:51:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Clark X-Patchwork-Id: 13391082 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 77508CD54A9 for ; Tue, 19 Sep 2023 09:52:43 +0000 (UTC) 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=K4VkTQRQnl7d1lybcLglPAcxER0AYk6P5MUr9dIjTeg=; b=hE0fIGXrZfE54E oqpOxIWHxtrTt3sAyyqABeieLHW5/Prs2QWfkJ6MW1OvwWtsvoX9WMClgcu9MqFzZrSN4LXxPYF49 p3yTkLgLzpB9qQcllBhdxpFT8i8QQMHFb9yq6ZXbQcvsI8wcrB4of6vnhsTlTeWioRu8oJpJAuEMM PSszeFLsdnDfSDClyetsozG8b+e7DuELEjbHyUQD9K/sPBf9JUWWpF2Uu+vfKUyJaJeHhClWJtzVC gfHvyK99vERLfDwzXUudZTyqbPSbU+krBKg4mbXqoMY3AO7ja2FLIAtdJa7gPmFl7AtLKm06cVOJ1 ztb/bFo1JTnnNY3HblRg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qiXP2-00HYI6-27; Tue, 19 Sep 2023 09:52:20 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qiXOz-00HYHH-0j for linux-arm-kernel@lists.infradead.org; Tue, 19 Sep 2023 09:52:18 +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 D19891FB; Tue, 19 Sep 2023 02:52:53 -0700 (PDT) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id ED23F3F67D; Tue, 19 Sep 2023 02:52:14 -0700 (PDT) From: James Clark To: linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: James Clark , Catalin Marinas , Will Deacon , Jonathan Corbet , Mark Rutland , Marc Zyngier , Zaid Al-Bassam , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 2/2] Documentation: arm64: Document the PMU event counting threshold feature Date: Tue, 19 Sep 2023 10:51:29 +0100 Message-Id: <20230919095137.360963-3-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230919095137.360963-1-james.clark@arm.com> References: <20230919095137.360963-1-james.clark@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230919_025217_314303_23D6C240 X-CRM114-Status: GOOD ( 13.83 ) 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 Add documentation for the two new Perf event open parameters and the threshold_max capability file. Signed-off-by: James Clark --- Documentation/arch/arm64/perf.rst | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Documentation/arch/arm64/perf.rst b/Documentation/arch/arm64/perf.rst index 1f87b57c2332..122a12607f37 100644 --- a/Documentation/arch/arm64/perf.rst +++ b/Documentation/arch/arm64/perf.rst @@ -164,3 +164,61 @@ and should be used to mask the upper bits as needed. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/arch/arm64/tests/user-events.c .. _tools/lib/perf/tests/test-evsel.c: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/perf/tests/test-evsel.c + +Event Counting Threshold +========================================== + +Overview +-------- + +FEAT_PMUv3_TH (Armv8.8) permits a PMU counter to increment only on +events whose count meets a specified threshold condition. For example if +threshold_control is set to 5 ('Greater than or equal, count'), and +the threshold is set to 2, then the PMU counter will now only increment +by 1 when an event would have previously incremented the PMU counter by +2 or more on a single processor cycle. + +To increment by the value of the event instead of 1, use the non 'count' +comparisons, in this case 4 ('Greater than or equal'). Each comparison +has a count and non count version, where the 'count' version always +increments the PMU counter by 1 instead of the value of the event. + +How-to +------ + +The threshold and threshold control values can be provided per event: + +.. code-block:: sh + + perf stat -e stall_slot/threshold=2,threshold_control=5/ \ + -e dtlb_walk/threshold=10,threshold_control=4/ + +And the following control values are supported: + +.. code-block:: + + 0: Not-equal + 1: Not-equal, count + 2: Equals + 3: Equals, count + 4: Greater-than-or-equal + 5: Greater-than-or-equal, count + 6: Less-than + 7: Less-than, count + +The maximum supported threshold value can be read from the caps of each +PMU, for example: + +.. code-block:: sh + + cat /sys/bus/event_source/devices/armv8_pmuv3/caps/threshold_max + + 0x000000ff + +If a value higher than this is given, then it will be silently clamped +to the maximum. The highest possible maximum is 4095, as the config +field for threshold is limited to 12 bits, and the Perf tool will refuse +to parse higher values. + +If the PMU doesn't support FEAT_PMUv3_TH, then threshold_max will read +0, and both threshold and threshold_control will be silently ignored.