From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A80FDC54EBC for ; Tue, 3 Jan 2023 16:22:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238057AbjACQWQ (ORCPT ); Tue, 3 Jan 2023 11:22:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238189AbjACQVv (ORCPT ); Tue, 3 Jan 2023 11:21:51 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 563F612D2E; Tue, 3 Jan 2023 08:21:24 -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 BEB0C152B; Tue, 3 Jan 2023 08:22:05 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 2B5E73F71A; Tue, 3 Jan 2023 08:21:21 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/7] perf: Remove duplication around EVENT_SOURCE_DEVICE_PATH Date: Tue, 3 Jan 2023 16:20:35 +0000 Message-Id: <20230103162042.423694-2-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The pattern for accessing EVENT_SOURCE_DEVICE_PATH is duplicated in a few places, so add two utility functions to cover it. Also just use perf_pmu__scan_file() instead of pmu_type() which already does the same thing. No functional changes. Reviewed-by: Leo Yan Signed-off-by: James Clark Tested-by: Tanmay Jagdale --- tools/perf/arch/arm/util/auxtrace.c | 5 +- tools/perf/arch/x86/util/pmu.c | 12 +-- tools/perf/util/pmu.c | 110 +++++++++++----------------- tools/perf/util/pmu.h | 5 +- 4 files changed, 49 insertions(+), 83 deletions(-) diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util= /auxtrace.c index deeb163999ce..adec6c9ee11d 100644 --- a/tools/perf/arch/arm/util/auxtrace.c +++ b/tools/perf/arch/arm/util/auxtrace.c @@ -55,17 +55,16 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_= spes, int *err) =20 static struct perf_pmu **find_all_hisi_ptt_pmus(int *nr_ptts, int *err) { - const char *sysfs =3D sysfs__mountpoint(); struct perf_pmu **hisi_ptt_pmus =3D NULL; struct dirent *dent; char path[PATH_MAX]; DIR *dir =3D NULL; int idx =3D 0; =20 - snprintf(path, PATH_MAX, "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); + perf_pmu__event_source_devices_scnprintf(path, sizeof(path)); dir =3D opendir(path); if (!dir) { - pr_err("can't read directory '%s'\n", EVENT_SOURCE_DEVICE_PATH); + pr_err("can't read directory '%s'\n", path); *err =3D -EINVAL; return NULL; } diff --git a/tools/perf/arch/x86/util/pmu.c b/tools/perf/arch/x86/util/pmu.c index 74d69db1ea99..358340b34243 100644 --- a/tools/perf/arch/x86/util/pmu.c +++ b/tools/perf/arch/x86/util/pmu.c @@ -15,8 +15,6 @@ #include "../../../util/pmu.h" #include "../../../util/fncache.h" =20 -#define TEMPLATE_ALIAS "%s/bus/event_source/devices/%s/alias" - struct pmu_alias { char *name; char *alias; @@ -72,18 +70,14 @@ static int setup_pmu_alias_list(void) char path[PATH_MAX]; DIR *dir; struct dirent *dent; - const char *sysfs =3D sysfs__mountpoint(); struct pmu_alias *pmu_alias; char buf[MAX_PMU_NAME_LEN]; FILE *file; int ret =3D -ENOMEM; =20 - if (!sysfs) + if (!perf_pmu__event_source_devices_scnprintf(path, sizeof(path))) return -1; =20 - snprintf(path, PATH_MAX, - "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); - dir =3D opendir(path); if (!dir) return -errno; @@ -93,9 +87,7 @@ static int setup_pmu_alias_list(void) !strcmp(dent->d_name, "..")) continue; =20 - snprintf(path, PATH_MAX, - TEMPLATE_ALIAS, sysfs, dent->d_name); - + perf_pmu__pathname_scnprintf(path, sizeof(path), dent->d_name, "alias"); if (!file_available(path)) continue; =20 diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 2bdeb89352e7..0d9619dde3a8 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -107,14 +107,10 @@ int perf_pmu__format_parse(char *dir, struct list_hea= d *head) static int pmu_format(const char *name, struct list_head *format) { char path[PATH_MAX]; - const char *sysfs =3D sysfs__mountpoint(); =20 - if (!sysfs) + if (!perf_pmu__pathname_scnprintf(path, sizeof(path), name, "format")) return -1; =20 - snprintf(path, PATH_MAX, - "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name); - if (!file_available(path)) return 0; =20 @@ -513,14 +509,10 @@ static int pmu_aliases_parse(char *dir, struct list_h= ead *head) static int pmu_aliases(const char *name, struct list_head *head) { char path[PATH_MAX]; - const char *sysfs =3D sysfs__mountpoint(); =20 - if (!sysfs) + if (!perf_pmu__pathname_scnprintf(path, sizeof(path), name, "events")) return -1; =20 - snprintf(path, PATH_MAX, - "%s/bus/event_source/devices/%s/events", sysfs, name); - if (!file_available(path)) return 0; =20 @@ -554,52 +546,16 @@ static int pmu_alias_terms(struct perf_pmu_alias *ali= as, return 0; } =20 -/* - * Reading/parsing the default pmu type value, which should be - * located at: - * /sys/bus/event_source/devices//type as sysfs attribute. - */ -static int pmu_type(const char *name, __u32 *type) -{ - char path[PATH_MAX]; - FILE *file; - int ret =3D 0; - const char *sysfs =3D sysfs__mountpoint(); - - if (!sysfs) - return -1; - - snprintf(path, PATH_MAX, - "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name); - - if (access(path, R_OK) < 0) - return -1; - - file =3D fopen(path, "r"); - if (!file) - return -EINVAL; - - if (1 !=3D fscanf(file, "%u", type)) - ret =3D -1; - - fclose(file); - return ret; -} - /* Add all pmus in sysfs to pmu list: */ static void pmu_read_sysfs(void) { char path[PATH_MAX]; DIR *dir; struct dirent *dent; - const char *sysfs =3D sysfs__mountpoint(); =20 - if (!sysfs) + if (!perf_pmu__event_source_devices_scnprintf(path, sizeof(path))) return; =20 - snprintf(path, PATH_MAX, - "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); - dir =3D opendir(path); if (!dir) return; @@ -696,14 +652,9 @@ static char *pmu_id(const char *name) static int is_arm_pmu_core(const char *name) { char path[PATH_MAX]; - const char *sysfs =3D sysfs__mountpoint(); =20 - if (!sysfs) + if (!perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpus")) return 0; - - /* Look for cpu sysfs (specific to arm) */ - scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus", - sysfs, name); return file_available(path); } =20 @@ -969,11 +920,8 @@ static struct perf_pmu *pmu_lookup(const char *lookup_= name) return NULL; =20 /* - * Check the type first to avoid unnecessary work. + * Check the aliases first to avoid unnecessary work. */ - if (pmu_type(name, &type)) - return NULL; - if (pmu_aliases(name, &aliases)) return NULL; =20 @@ -983,9 +931,14 @@ static struct perf_pmu *pmu_lookup(const char *lookup_= name) =20 pmu->cpus =3D pmu_cpumask(name); pmu->name =3D strdup(name); + if (!pmu->name) goto err; =20 + /* Read type, and ensure that type value is successfully assigned (return= 1) */ + if (perf_pmu__scan_file(pmu, "type", "%u", &type) !=3D 1) + goto err; + alias_name =3D pmu_find_alias_name(name); if (alias_name) { pmu->alias_name =3D strdup(alias_name); @@ -1786,16 +1739,11 @@ bool pmu_have_event(const char *pname, const char *= name) static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) { char path[PATH_MAX]; - const char *sysfs; =20 - sysfs =3D sysfs__mountpoint(); - if (!sysfs) + if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, name) || + !file_available(path)) return NULL; =20 - snprintf(path, PATH_MAX, - "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name); - if (!file_available(path)) - return NULL; return fopen(path, "r"); } =20 @@ -1849,7 +1797,6 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu) { struct stat st; char caps_path[PATH_MAX]; - const char *sysfs =3D sysfs__mountpoint(); DIR *caps_dir; struct dirent *evt_ent; =20 @@ -1858,12 +1805,9 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu) =20 pmu->nr_caps =3D 0; =20 - if (!sysfs) + if (!perf_pmu__pathname_scnprintf(caps_path, sizeof(caps_path), pmu->name= , "caps")) return -1; =20 - snprintf(caps_path, PATH_MAX, - "%s" EVENT_SOURCE_DEVICE_PATH "%s/caps", sysfs, pmu->name); - if (stat(caps_path, &st) < 0) { pmu->caps_initialized =3D true; return 0; /* no error if caps does not exist */ @@ -1993,3 +1937,31 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, struc= t perf_cpu_map *cpus, *ucpus_ptr =3D unmatched_cpus; return 0; } + +int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size) +{ + const char *sysfs =3D sysfs__mountpoint(); + + if (!sysfs) + return 0; + return scnprintf(pathname, size, "%s/bus/event_source/devices/", sysfs); +} + +/* + * Fill 'buf' with the path to a file or folder in 'pmu_name' in + * sysfs. For example if pmu_name =3D "cs_etm" and 'filename' =3D "format" + * then pathname will be filled with + * "/sys/bus/event_source/devices/cs_etm/format" + * + * Return 0 if the sysfs mountpoint couldn't be found or if no + * characters were written. + */ +int perf_pmu__pathname_scnprintf(char *buf, size_t size, + const char *pmu_name, const char *filename) +{ + char base_path[PATH_MAX]; + + if (!perf_pmu__event_source_devices_scnprintf(base_path, sizeof(base_path= ))) + return 0; + return scnprintf(buf, size, "%s%s/%s", base_path, pmu_name, filename); +} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 69ca0004f94f..2f2bb0286e2a 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -22,7 +22,6 @@ enum { }; =20 #define PERF_PMU_FORMAT_BITS 64 -#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/" #define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" #define MAX_PMU_NAME_LEN 128 =20 @@ -259,4 +258,8 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, struct p= erf_cpu_map *cpus, =20 char *pmu_find_real_name(const char *name); char *pmu_find_alias_name(const char *name); +int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size); +int perf_pmu__pathname_scnprintf(char *buf, size_t size, + const char *pmu_name, const char *filename); + #endif /* __PMU_H */ --=20 2.25.1 From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98611C53210 for ; Tue, 3 Jan 2023 16:22:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238152AbjACQW0 (ORCPT ); Tue, 3 Jan 2023 11:22:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238209AbjACQV5 (ORCPT ); Tue, 3 Jan 2023 11:21:57 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 92568F5B9; Tue, 3 Jan 2023 08:21:28 -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 067201516; Tue, 3 Jan 2023 08:22:10 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 6771A3F71A; Tue, 3 Jan 2023 08:21:25 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/7] perf: Use perf_pmu__open_file() and perf_pmu__scan_file() Date: Tue, 3 Jan 2023 16:20:36 +0000 Message-Id: <20230103162042.423694-3-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Remove some code that duplicates existing methods. This requires that some consts are removed because one of the existing helper methods takes a struct perf_pmu instead of a name which has a non const name field. But except for the tests, the strings were already non const. No functional changes. Signed-off-by: James Clark Reviewed-by: Leo Yan Tested-by: Tanmay Jagdale --- tools/perf/util/cputopo.c | 9 +------- tools/perf/util/pmu-hybrid.c | 27 +++++------------------- tools/perf/util/pmu.c | 40 +++++++++++------------------------- tools/perf/util/pmu.h | 3 ++- 4 files changed, 20 insertions(+), 59 deletions(-) diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 1a3ff6449158..e08797c3cdbc 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -422,8 +422,6 @@ void numa_topology__delete(struct numa_topology *tp) static int load_hybrid_node(struct hybrid_topology_node *node, struct perf_pmu *pmu) { - const char *sysfs; - char path[PATH_MAX]; char *buf =3D NULL, *p; FILE *fp; size_t len =3D 0; @@ -432,12 +430,7 @@ static int load_hybrid_node(struct hybrid_topology_nod= e *node, if (!node->pmu_name) return -1; =20 - sysfs =3D sysfs__mountpoint(); - if (!sysfs) - goto err; - - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, pmu->name); - fp =3D fopen(path, "r"); + fp =3D perf_pmu__open_file(pmu, "cpus"); if (!fp) goto err; =20 diff --git a/tools/perf/util/pmu-hybrid.c b/tools/perf/util/pmu-hybrid.c index f51ccaac60ee..38628805a952 100644 --- a/tools/perf/util/pmu-hybrid.c +++ b/tools/perf/util/pmu-hybrid.c @@ -20,32 +20,15 @@ LIST_HEAD(perf_pmu__hybrid_pmus); =20 bool perf_pmu__hybrid_mounted(const char *name) { - char path[PATH_MAX]; - const char *sysfs; - FILE *file; - int n, cpu; + int cpu; + char pmu_name[PATH_MAX]; + struct perf_pmu pmu =3D {.name =3D pmu_name}; =20 if (strncmp(name, "cpu_", 4)) return false; =20 - sysfs =3D sysfs__mountpoint(); - if (!sysfs) - return false; - - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name); - if (!file_available(path)) - return false; - - file =3D fopen(path, "r"); - if (!file) - return false; - - n =3D fscanf(file, "%u", &cpu); - fclose(file); - if (n <=3D 0) - return false; - - return true; + strlcpy(pmu_name, name, sizeof(pmu_name)); + return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0; } =20 struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 0d9619dde3a8..683cc7953f11 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -570,45 +570,31 @@ static void pmu_read_sysfs(void) closedir(dir); } =20 -static struct perf_cpu_map *__pmu_cpumask(const char *path) -{ - FILE *file; - struct perf_cpu_map *cpus; - - file =3D fopen(path, "r"); - if (!file) - return NULL; - - cpus =3D perf_cpu_map__read(file); - fclose(file); - return cpus; -} - /* * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/ar= m64) * may have a "cpus" file. */ #define SYS_TEMPLATE_ID "./bus/event_source/devices/%s/identifier" -#define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask" =20 static struct perf_cpu_map *pmu_cpumask(const char *name) { - char path[PATH_MAX]; struct perf_cpu_map *cpus; - const char *sysfs =3D sysfs__mountpoint(); const char *templates[] =3D { - CPUS_TEMPLATE_UNCORE, - CPUS_TEMPLATE_CPU, + "cpumask", + "cpus", NULL }; const char **template; + char pmu_name[PATH_MAX]; + struct perf_pmu pmu =3D {.name =3D pmu_name}; + FILE *file; =20 - if (!sysfs) - return NULL; - + strlcpy(pmu_name, name, sizeof(pmu_name)); for (template =3D templates; *template; template++) { - snprintf(path, PATH_MAX, *template, sysfs, name); - cpus =3D __pmu_cpumask(path); + file =3D perf_pmu__open_file(&pmu, *template); + if (!file) + continue; + cpus =3D perf_cpu_map__read(file); if (cpus) return cpus; } @@ -619,13 +605,11 @@ static struct perf_cpu_map *pmu_cpumask(const char *n= ame) static bool pmu_is_uncore(const char *name) { char path[PATH_MAX]; - const char *sysfs; =20 if (perf_pmu__hybrid_mounted(name)) return false; =20 - sysfs =3D sysfs__mountpoint(); - snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); + perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpumask"); return file_available(path); } =20 @@ -1736,7 +1720,7 @@ bool pmu_have_event(const char *pname, const char *na= me) return false; } =20 -static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) +FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) { char path[PATH_MAX]; =20 diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 2f2bb0286e2a..8f39e2d17fb1 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -2,6 +2,7 @@ #ifndef __PMU_H #define __PMU_H =20 +#include #include #include #include @@ -22,7 +23,6 @@ enum { }; =20 #define PERF_PMU_FORMAT_BITS 64 -#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" #define MAX_PMU_NAME_LEN 128 =20 struct perf_event_attr; @@ -261,5 +261,6 @@ char *pmu_find_alias_name(const char *name); int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size); int perf_pmu__pathname_scnprintf(char *buf, size_t size, const char *pmu_name, const char *filename); +FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name); =20 #endif /* __PMU_H */ --=20 2.25.1 From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AEF43C54EBE for ; Tue, 3 Jan 2023 16:22:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238175AbjACQWc (ORCPT ); Tue, 3 Jan 2023 11:22:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47604 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238221AbjACQWA (ORCPT ); Tue, 3 Jan 2023 11:22:00 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C78CF13CF4; Tue, 3 Jan 2023 08:21:32 -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 3B47F1570; Tue, 3 Jan 2023 08:22:14 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 9C4EF3F71A; Tue, 3 Jan 2023 08:21:29 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/7] perf: Remove remaining duplication of bus/event_source/devices/... Date: Tue, 3 Jan 2023 16:20:37 +0000 Message-Id: <20230103162042.423694-4-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Use the new perf_pmu__pathname_scnprintf() instead. No functional changes. Reviewed-by: Leo Yan Signed-off-by: James Clark Tested-by: Tanmay Jagdale --- tools/perf/util/pmu.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 683cc7953f11..7a4e243a370d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -574,8 +574,6 @@ static void pmu_read_sysfs(void) * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/ar= m64) * may have a "cpus" file. */ -#define SYS_TEMPLATE_ID "./bus/event_source/devices/%s/identifier" - static struct perf_cpu_map *pmu_cpumask(const char *name) { struct perf_cpu_map *cpus; @@ -618,9 +616,9 @@ static char *pmu_id(const char *name) char path[PATH_MAX], *str; size_t len; =20 - snprintf(path, PATH_MAX, SYS_TEMPLATE_ID, name); + perf_pmu__pathname_scnprintf(path, sizeof(path), name, "identifier"); =20 - if (sysfs__read_str(path, &str, &len) < 0) + if (filename__read_str(path, &str, &len) < 0) return NULL; =20 str[len - 1] =3D 0; /* remove line feed */ @@ -866,16 +864,11 @@ pmu_find_alias_name(const char *name __maybe_unused) return NULL; } =20 -static int pmu_max_precise(const char *name) +static int pmu_max_precise(struct perf_pmu *pmu) { - char path[PATH_MAX]; int max_precise =3D -1; =20 - scnprintf(path, PATH_MAX, - "bus/event_source/devices/%s/caps/max_precise", - name); - - sysfs__read_int(path, &max_precise); + perf_pmu__scan_file(pmu, "caps/max_precise", "%d", &max_precise); return max_precise; } =20 @@ -934,7 +927,7 @@ static struct perf_pmu *pmu_lookup(const char *lookup_n= ame) pmu->is_uncore =3D pmu_is_uncore(name); if (pmu->is_uncore) pmu->id =3D pmu_id(name); - pmu->max_precise =3D pmu_max_precise(name); + pmu->max_precise =3D pmu_max_precise(pmu); pmu_add_cpu_aliases(&aliases, pmu); pmu_add_sys_aliases(&aliases, pmu); =20 --=20 2.25.1 From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BD16C3DA7D for ; Tue, 3 Jan 2023 16:22:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233688AbjACQWs (ORCPT ); Tue, 3 Jan 2023 11:22:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238263AbjACQWI (ORCPT ); Tue, 3 Jan 2023 11:22:08 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 246EA13D36; Tue, 3 Jan 2023 08:21:37 -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 89C221516; Tue, 3 Jan 2023 08:22:18 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id CFA183F71A; Tue, 3 Jan 2023 08:21:33 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, German Gomez , James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/7] perf pmu: Add function to check if a pmu file exists Date: Tue, 3 Jan 2023 16:20:38 +0000 Message-Id: <20230103162042.423694-5-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: German Gomez Add a utility function perf_pmu__file_exists() to check if a given pmu file exists in the sysfs filesystem. Signed-off-by: German Gomez Signed-off-by: James Clark Tested-by: Tanmay Jagdale --- tools/perf/util/pmu.c | 10 ++++++++++ tools/perf/util/pmu.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a4e243a370d..3529556d57dc 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1741,6 +1741,16 @@ int perf_pmu__scan_file(struct perf_pmu *pmu, const = char *name, const char *fmt, return ret; } =20 +bool perf_pmu__file_exists(struct perf_pmu *pmu, const char *name) +{ + char path[PATH_MAX]; + + if (!perf_pmu__pathname_scnprintf(path, sizeof(path), pmu->name, name)) + return false; + + return file_available(path); +} + static int perf_pmu__new_caps(struct list_head *list, char *name, char *va= lue) { struct perf_pmu_caps *caps =3D zalloc(sizeof(*caps)); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 8f39e2d17fb1..c1d138fe9602 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -230,6 +230,8 @@ bool pmu_have_event(const char *pname, const char *name= ); =20 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char= *fmt, ...) __scanf(3, 4); =20 +bool perf_pmu__file_exists(struct perf_pmu *pmu, const char *name); + int perf_pmu__test(void); =20 struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu); --=20 2.25.1 From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7ED70C46467 for ; Tue, 3 Jan 2023 16:23:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237551AbjACQWx (ORCPT ); Tue, 3 Jan 2023 11:22:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233708AbjACQWO (ORCPT ); Tue, 3 Jan 2023 11:22:14 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7426D13D47; Tue, 3 Jan 2023 08:21:41 -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 DBAC7152B; Tue, 3 Jan 2023 08:22:22 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 2D92F3F71A; Tue, 3 Jan 2023 08:21:38 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, German Gomez , James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/7] perf cs_etm: Keep separate symbols for ETMv4 and ETE parameters Date: Tue, 3 Jan 2023 16:20:39 +0000 Message-Id: <20230103162042.423694-6-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: German Gomez Previously, adding a new parameter at the end of ETMv4 meant adding it somewhere in the middle of ETE, which is not supported by the current header version. Reviewed-by: Mike Leach Signed-off-by: German Gomez Signed-off-by: James Clark Tested-by: Tanmay Jagdale --- tools/perf/arch/arm/util/cs-etm.c | 43 ++++++++++++++++++++++++++----- tools/perf/util/cs-etm-base.c | 32 +++++++++++++++++------ tools/perf/util/cs-etm.c | 12 ++++----- tools/perf/util/cs-etm.h | 11 +++++++- 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/c= s-etm.c index a346d5f3dafa..b526ffe550a5 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -53,7 +53,15 @@ static const char * const metadata_etmv4_ro[] =3D { [CS_ETMV4_TRCIDR2] =3D "trcidr/trcidr2", [CS_ETMV4_TRCIDR8] =3D "trcidr/trcidr8", [CS_ETMV4_TRCAUTHSTATUS] =3D "mgmt/trcauthstatus", - [CS_ETE_TRCDEVARCH] =3D "mgmt/trcdevarch" +}; + +static const char * const metadata_ete_ro[] =3D { + [CS_ETE_TRCIDR0] =3D "trcidr/trcidr0", + [CS_ETE_TRCIDR1] =3D "trcidr/trcidr1", + [CS_ETE_TRCIDR2] =3D "trcidr/trcidr2", + [CS_ETE_TRCIDR8] =3D "trcidr/trcidr8", + [CS_ETE_TRCAUTHSTATUS] =3D "mgmt/trcauthstatus", + [CS_ETE_TRCDEVARCH] =3D "mgmt/trcdevarch", }; =20 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu); @@ -617,7 +625,7 @@ static bool cs_etm_is_ete(struct auxtrace_record *itr, = int cpu) { struct cs_etm_recording *ptr =3D container_of(itr, struct cs_etm_recordin= g, itr); struct perf_pmu *cs_etm_pmu =3D ptr->cs_etm_pmu; - int trcdevarch =3D cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ET= E_TRCDEVARCH]); + int trcdevarch =3D cs_etm_get_ro(cs_etm_pmu, cpu, metadata_ete_ro[CS_ETE_= TRCDEVARCH]); =20 /* * ETE if ARCHVER is 5 (ARCHVER is 4 for ETM) and ARCHPART is 0xA13. @@ -648,6 +656,31 @@ static void cs_etm_save_etmv4_header(__u64 data[], str= uct auxtrace_record *itr, metadata_etmv4_ro[CS_ETMV4_TRCAUTHSTATUS]); } =20 +static void cs_etm_save_ete_header(__u64 data[], struct auxtrace_record *i= tr, int cpu) +{ + struct cs_etm_recording *ptr =3D container_of(itr, struct cs_etm_recordin= g, itr); + struct perf_pmu *cs_etm_pmu =3D ptr->cs_etm_pmu; + + /* Get trace configuration register */ + data[CS_ETE_TRCCONFIGR] =3D cs_etmv4_get_config(itr); + /* Get traceID from the framework */ + data[CS_ETE_TRCTRACEIDR] =3D coresight_get_trace_id(cpu); + /* Get read-only information from sysFS */ + data[CS_ETE_TRCIDR0] =3D cs_etm_get_ro(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TRCIDR0]); + data[CS_ETE_TRCIDR1] =3D cs_etm_get_ro(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TRCIDR1]); + data[CS_ETE_TRCIDR2] =3D cs_etm_get_ro(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TRCIDR2]); + data[CS_ETE_TRCIDR8] =3D cs_etm_get_ro(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TRCIDR8]); + data[CS_ETE_TRCAUTHSTATUS] =3D cs_etm_get_ro(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TRCAUTHSTATUS]); + /* ETE uses the same registers as ETMv4 plus TRCDEVARCH */ + data[CS_ETE_TRCDEVARCH] =3D cs_etm_get_ro(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TRCDEVARCH]); +} + static void cs_etm_get_metadata(int cpu, u32 *offset, struct auxtrace_record *itr, struct perf_record_auxtrace_info *info) @@ -661,11 +694,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset, /* first see what kind of tracer this cpu is affined to */ if (cs_etm_is_ete(itr, cpu)) { magic =3D __perf_cs_ete_magic; - /* ETE uses the same registers as ETMv4 plus TRCDEVARCH */ - cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu); - info->priv[*offset + CS_ETE_TRCDEVARCH] =3D - cs_etm_get_ro(cs_etm_pmu, cpu, - metadata_etmv4_ro[CS_ETE_TRCDEVARCH]); + cs_etm_save_ete_header(&info->priv[*offset], itr, cpu); =20 /* How much space was used */ increment =3D CS_ETE_PRIV_MAX; diff --git a/tools/perf/util/cs-etm-base.c b/tools/perf/util/cs-etm-base.c index 597542410854..282042c6e944 100644 --- a/tools/perf/util/cs-etm-base.c +++ b/tools/perf/util/cs-etm-base.c @@ -36,7 +36,20 @@ static const char * const cs_etmv4_priv_fmts[] =3D { [CS_ETMV4_TRCIDR2] =3D " TRCIDR2 %llx\n", [CS_ETMV4_TRCIDR8] =3D " TRCIDR8 %llx\n", [CS_ETMV4_TRCAUTHSTATUS] =3D " TRCAUTHSTATUS %llx\n", - [CS_ETE_TRCDEVARCH] =3D " TRCDEVARCH %llx\n" +}; + +static const char * const cs_ete_priv_fmts[] =3D { + [CS_ETM_MAGIC] =3D " Magic number %llx\n", + [CS_ETM_CPU] =3D " CPU %lld\n", + [CS_ETM_NR_TRC_PARAMS] =3D " NR_TRC_PARAMS %llx\n", + [CS_ETE_TRCCONFIGR] =3D " TRCCONFIGR %llx\n", + [CS_ETE_TRCTRACEIDR] =3D " TRCTRACEIDR %llx\n", + [CS_ETE_TRCIDR0] =3D " TRCIDR0 %llx\n", + [CS_ETE_TRCIDR1] =3D " TRCIDR1 %llx\n", + [CS_ETE_TRCIDR2] =3D " TRCIDR2 %llx\n", + [CS_ETE_TRCIDR8] =3D " TRCIDR8 %llx\n", + [CS_ETE_TRCAUTHSTATUS] =3D " TRCAUTHSTATUS %llx\n", + [CS_ETE_TRCDEVARCH] =3D " TRCDEVARCH %llx\n", }; =20 static const char * const param_unk_fmt =3D @@ -96,19 +109,22 @@ static int cs_etm__print_cpu_metadata_v1(u64 *val, int= *offset) else fprintf(stdout, cs_etm_priv_fmts[j], val[i]); } - } else if (magic =3D=3D __perf_cs_etmv4_magic || magic =3D=3D __perf_cs_e= te_magic) { - /* - * ETE and ETMv4 can be printed in the same block because the number of = parameters - * is saved and they share the list of parameter names. ETE is also only= supported - * in V1 files. - */ + } else if (magic =3D=3D __perf_cs_etmv4_magic) { for (j =3D 0; j < total_params; j++, i++) { /* if newer record - could be excess params */ - if (j >=3D CS_ETE_PRIV_MAX) + if (j >=3D CS_ETMV4_PRIV_MAX) fprintf(stdout, param_unk_fmt, j, val[i]); else fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]); } + } else if (magic =3D=3D __perf_cs_ete_magic) { + for (j =3D 0; j < total_params; j++, i++) { + /* if newer record - could be excess params */ + if (j >=3D CS_ETE_PRIV_MAX) + fprintf(stdout, param_unk_fmt, j, val[i]); + else + fprintf(stdout, cs_ete_priv_fmts[j], val[i]); + } } else { /* failure - note bad magic value and error out */ fprintf(stdout, magic_unk_fmt, magic); diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 33303d03c2fa..879576d5f899 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -464,12 +464,12 @@ static void cs_etm__set_trace_param_ete(struct cs_etm= _trace_params *t_params, u64 **metadata =3D etm->metadata; =20 t_params[idx].protocol =3D CS_ETM_PROTO_ETE; - t_params[idx].ete.reg_idr0 =3D metadata[idx][CS_ETMV4_TRCIDR0]; - t_params[idx].ete.reg_idr1 =3D metadata[idx][CS_ETMV4_TRCIDR1]; - t_params[idx].ete.reg_idr2 =3D metadata[idx][CS_ETMV4_TRCIDR2]; - t_params[idx].ete.reg_idr8 =3D metadata[idx][CS_ETMV4_TRCIDR8]; - t_params[idx].ete.reg_configr =3D metadata[idx][CS_ETMV4_TRCCONFIGR]; - t_params[idx].ete.reg_traceidr =3D metadata[idx][CS_ETMV4_TRCTRACEIDR]; + t_params[idx].ete.reg_idr0 =3D metadata[idx][CS_ETE_TRCIDR0]; + t_params[idx].ete.reg_idr1 =3D metadata[idx][CS_ETE_TRCIDR1]; + t_params[idx].ete.reg_idr2 =3D metadata[idx][CS_ETE_TRCIDR2]; + t_params[idx].ete.reg_idr8 =3D metadata[idx][CS_ETE_TRCIDR8]; + t_params[idx].ete.reg_configr =3D metadata[idx][CS_ETE_TRCCONFIGR]; + t_params[idx].ete.reg_traceidr =3D metadata[idx][CS_ETE_TRCTRACEIDR]; t_params[idx].ete.reg_devarch =3D metadata[idx][CS_ETE_TRCDEVARCH]; } =20 diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 5da50d5dae6b..c5925428afa9 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -82,7 +82,16 @@ enum { * added in header V1 */ enum { - CS_ETE_TRCDEVARCH =3D CS_ETMV4_PRIV_MAX, + /* Dynamic, configurable parameters */ + CS_ETE_TRCCONFIGR =3D CS_ETM_COMMON_BLK_MAX_V1, + CS_ETE_TRCTRACEIDR, + /* RO, taken from sysFS */ + CS_ETE_TRCIDR0, + CS_ETE_TRCIDR1, + CS_ETE_TRCIDR2, + CS_ETE_TRCIDR8, + CS_ETE_TRCAUTHSTATUS, + CS_ETE_TRCDEVARCH, CS_ETE_PRIV_MAX }; =20 --=20 2.25.1 From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95373C3DA7D for ; Tue, 3 Jan 2023 16:23:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238065AbjACQW6 (ORCPT ); Tue, 3 Jan 2023 11:22:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47644 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238136AbjACQWU (ORCPT ); Tue, 3 Jan 2023 11:22:20 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CEE4A13D40; Tue, 3 Jan 2023 08:21:45 -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 3D7101516; Tue, 3 Jan 2023 08:22:27 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 835C73F71A; Tue, 3 Jan 2023 08:21:42 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, German Gomez , James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 6/7] perf cs_etm: Record ts_source in AUXTRACE_INFO for ETMv4 and ETE Date: Tue, 3 Jan 2023 16:20:40 +0000 Message-Id: <20230103162042.423694-7-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: German Gomez Read the value of ts_source exposed by the driver and store it in the ETMv4 and ETE header. If the interface doesn't exist (such as in older Kernels), defaults to a safe value of -1. Signed-off-by: German Gomez Signed-off-by: James Clark Tested-by: Tanmay Jagdale --- tools/perf/arch/arm/util/cs-etm.c | 48 +++++++++++++++++++++++++++++++ tools/perf/util/cs-etm-base.c | 2 ++ tools/perf/util/cs-etm.h | 2 ++ 3 files changed, 52 insertions(+) diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/c= s-etm.c index b526ffe550a5..481e170cd3f1 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -53,6 +53,7 @@ static const char * const metadata_etmv4_ro[] =3D { [CS_ETMV4_TRCIDR2] =3D "trcidr/trcidr2", [CS_ETMV4_TRCIDR8] =3D "trcidr/trcidr8", [CS_ETMV4_TRCAUTHSTATUS] =3D "mgmt/trcauthstatus", + [CS_ETMV4_TS_SOURCE] =3D "ts_source", }; =20 static const char * const metadata_ete_ro[] =3D { @@ -62,6 +63,7 @@ static const char * const metadata_ete_ro[] =3D { [CS_ETE_TRCIDR8] =3D "trcidr/trcidr8", [CS_ETE_TRCAUTHSTATUS] =3D "mgmt/trcauthstatus", [CS_ETE_TRCDEVARCH] =3D "mgmt/trcdevarch", + [CS_ETE_TS_SOURCE] =3D "ts_source", }; =20 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu); @@ -613,6 +615,32 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu= , const char *path) return val; } =20 +static int cs_etm_get_ro_signed(struct perf_pmu *pmu, int cpu, const char = *path) +{ + char pmu_path[PATH_MAX]; + int scan; + int val =3D 0; + + /* Get RO metadata from sysfs */ + snprintf(pmu_path, PATH_MAX, "cpu%d/%s", cpu, path); + + scan =3D perf_pmu__scan_file(pmu, pmu_path, "%d", &val); + if (scan !=3D 1) + pr_err("%s: error reading: %s\n", __func__, pmu_path); + + return val; +} + +static bool cs_etm_pmu_path_exists(struct perf_pmu *pmu, int cpu, const ch= ar *path) +{ + char pmu_path[PATH_MAX]; + + /* Get RO metadata from sysfs */ + snprintf(pmu_path, PATH_MAX, "cpu%d/%s", cpu, path); + + return perf_pmu__file_exists(pmu, pmu_path); +} + #define TRCDEVARCH_ARCHPART_SHIFT 0 #define TRCDEVARCH_ARCHPART_MASK GENMASK(11, 0) #define TRCDEVARCH_ARCHPART(x) (((x) & TRCDEVARCH_ARCHPART_MASK) >> TRC= DEVARCH_ARCHPART_SHIFT) @@ -654,6 +682,16 @@ static void cs_etm_save_etmv4_header(__u64 data[], str= uct auxtrace_record *itr, metadata_etmv4_ro[CS_ETMV4_TRCIDR8]); data[CS_ETMV4_TRCAUTHSTATUS] =3D cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCAUTHSTATUS]); + + /* Kernels older than 5.19 may not expose ts_source */ + if (cs_etm_pmu_path_exists(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TS= _SOURCE])) + data[CS_ETMV4_TS_SOURCE] =3D (__u64) cs_etm_get_ro_signed(cs_etm_pmu, cp= u, + metadata_etmv4_ro[CS_ETMV4_TS_SOURCE]); + else { + pr_warning("[%03d] pmu file 'ts_source' not found. Fallback to safe valu= e (-1)\n", + cpu); + data[CS_ETMV4_TS_SOURCE] =3D (__u64) -1; + } } =20 static void cs_etm_save_ete_header(__u64 data[], struct auxtrace_record *i= tr, int cpu) @@ -679,6 +717,16 @@ static void cs_etm_save_ete_header(__u64 data[], struc= t auxtrace_record *itr, in /* ETE uses the same registers as ETMv4 plus TRCDEVARCH */ data[CS_ETE_TRCDEVARCH] =3D cs_etm_get_ro(cs_etm_pmu, cpu, metadata_ete_ro[CS_ETE_TRCDEVARCH]); + + /* Kernels older than 5.19 may not expose ts_source */ + if (cs_etm_pmu_path_exists(cs_etm_pmu, cpu, metadata_ete_ro[CS_ETE_TS_SOU= RCE])) + data[CS_ETE_TS_SOURCE] =3D (__u64) cs_etm_get_ro_signed(cs_etm_pmu, cpu, + metadata_ete_ro[CS_ETE_TS_SOURCE]); + else { + pr_warning("[%03d] pmu file 'ts_source' not found. Fallback to safe valu= e (-1)\n", + cpu); + data[CS_ETE_TS_SOURCE] =3D (__u64) -1; + } } =20 static void cs_etm_get_metadata(int cpu, u32 *offset, diff --git a/tools/perf/util/cs-etm-base.c b/tools/perf/util/cs-etm-base.c index 282042c6e944..5f48b756c4cf 100644 --- a/tools/perf/util/cs-etm-base.c +++ b/tools/perf/util/cs-etm-base.c @@ -36,6 +36,7 @@ static const char * const cs_etmv4_priv_fmts[] =3D { [CS_ETMV4_TRCIDR2] =3D " TRCIDR2 %llx\n", [CS_ETMV4_TRCIDR8] =3D " TRCIDR8 %llx\n", [CS_ETMV4_TRCAUTHSTATUS] =3D " TRCAUTHSTATUS %llx\n", + [CS_ETMV4_TS_SOURCE] =3D " TS_SOURCE %lld\n", }; =20 static const char * const cs_ete_priv_fmts[] =3D { @@ -50,6 +51,7 @@ static const char * const cs_ete_priv_fmts[] =3D { [CS_ETE_TRCIDR8] =3D " TRCIDR8 %llx\n", [CS_ETE_TRCAUTHSTATUS] =3D " TRCAUTHSTATUS %llx\n", [CS_ETE_TRCDEVARCH] =3D " TRCDEVARCH %llx\n", + [CS_ETE_TS_SOURCE] =3D " TS_SOURCE %lld\n", }; =20 static const char * const param_unk_fmt =3D diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index c5925428afa9..ad790930bcbc 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -71,6 +71,7 @@ enum { CS_ETMV4_TRCIDR2, CS_ETMV4_TRCIDR8, CS_ETMV4_TRCAUTHSTATUS, + CS_ETMV4_TS_SOURCE, CS_ETMV4_PRIV_MAX, }; =20 @@ -92,6 +93,7 @@ enum { CS_ETE_TRCIDR8, CS_ETE_TRCAUTHSTATUS, CS_ETE_TRCDEVARCH, + CS_ETE_TS_SOURCE, CS_ETE_PRIV_MAX }; =20 --=20 2.25.1 From nobody Tue Sep 16 12:32:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60A2BC3DA7D for ; Tue, 3 Jan 2023 16:23:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237975AbjACQX0 (ORCPT ); Tue, 3 Jan 2023 11:23:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238176AbjACQWc (ORCPT ); Tue, 3 Jan 2023 11:22:32 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 2E50113D54; Tue, 3 Jan 2023 08:21:50 -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 926D31576; Tue, 3 Jan 2023 08:22:31 -0800 (PST) Received: from e126815.warwick.arm.com (e126815.arm.com [10.32.32.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D840B3F71A; Tue, 3 Jan 2023 08:21:46 -0800 (PST) From: James Clark To: linux-perf-users@vger.kernel.org, tanmay@marvell.com, leo.yan@linaro.org, mike.leach@linaro.org Cc: sgoutham@marvell.com, gcherian@marvell.com, lcherian@marvell.com, bbhushan2@marvell.com, German Gomez , James Clark , Mathieu Poirier , Suzuki K Poulose , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 7/7] perf cs_etm: Set the time field in the synthetic samples Date: Tue, 3 Jan 2023 16:20:41 +0000 Message-Id: <20230103162042.423694-8-james.clark@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230103162042.423694-1-james.clark@arm.com> References: <20230103162042.423694-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: German Gomez If virtual timestamps are detected, set sample time field accordingly, otherwise warn the user that the samples will not include the time data. | Test notes (FEAT_TRF platform) | | $ ./perf record -e cs_etm//u -a -- sleep 4 | $ ./perf script --fields +time | perf 422 [000] 163.375100: 1 branches:uH: = 0 [unknown] ([unknown]) | perf 422 [000] 163.375100: 1 branches:uH: ffffb80= 09544 ioctl+0x14 (/lib/aarch64-linux-gnu/libc-2.27.so) | perf 422 [000] 163.375100: 1 branches:uH: aaaaab6= bebf4 perf_evsel__run_ioctl+0x90 (/home/german/linux/tools/perf/perf) | [...] | perf 422 [000] 167.393100: 1 branches:uH: aaaaab6= bda00 __xyarray__entry+0x74 (/home/german/linux/tools/perf/perf) | perf 422 [000] 167.393099: 1 branches:uH: aaaaab6= bda0c __xyarray__entry+0x80 (/home/german/linux/tools/perf/perf) | perf 422 [000] 167.393099: 1 branches:uH: ffffb80= 09538 ioctl+0x8 (/lib/aarch64-linux-gnu/libc-2.27.so) | | The time from the first sample to the last sample is 4 seconds Signed-off-by: German Gomez Signed-off-by: James Clark Tested-by: Tanmay Jagdale --- tools/perf/util/cs-etm.c | 74 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 879576d5f899..19784baef5b8 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -35,6 +35,7 @@ #include "tool.h" #include "thread.h" #include "thread-stack.h" +#include "tsc.h" #include #include "util/synthetic-events.h" =20 @@ -46,10 +47,12 @@ struct cs_etm_auxtrace { struct perf_session *session; struct machine *machine; struct thread *unknown_thread; + struct perf_tsc_conversion tc; =20 u8 timeless_decoding; u8 snapshot_mode; u8 data_queued; + u8 has_virtual_ts; /* Virtual/Kernel timestamps in the trace. */ =20 int num_cpu; u64 latest_kernel_timestamp; @@ -1161,6 +1164,22 @@ static void cs_etm__copy_insn(struct cs_etm_queue *e= tmq, sample->insn_len, (void *)sample->insn); } =20 +static inline void cs_etm__resolve_sample_time(struct cs_etm_queue *etmq, + struct cs_etm_traceid_queue *tidq, + u64 *time) +{ + struct cs_etm_auxtrace *etm =3D etmq->etm; + struct cs_etm_packet_queue *packet_queue =3D &tidq->packet_queue; + + if (etm->timeless_decoding) + *time =3D 0; + else if (etm->has_virtual_ts) + *time =3D tsc_to_perf_time(packet_queue->cs_timestamp, &etm->tc); + else + *time =3D etm->latest_kernel_timestamp; + +} + static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq, struct cs_etm_traceid_queue *tidq, u64 addr, u64 period) @@ -1174,8 +1193,9 @@ static int cs_etm__synth_instruction_sample(struct cs= _etm_queue *etmq, event->sample.header.misc =3D cs_etm__cpu_mode(etmq, addr); event->sample.header.size =3D sizeof(struct perf_event_header); =20 - if (!etm->timeless_decoding) - sample.time =3D etm->latest_kernel_timestamp; + /* Set time field based con etm auxtrace config. */ + cs_etm__resolve_sample_time(etmq, tidq, &sample.time); + sample.ip =3D addr; sample.pid =3D tidq->pid; sample.tid =3D tidq->tid; @@ -1232,8 +1252,9 @@ static int cs_etm__synth_branch_sample(struct cs_etm_= queue *etmq, event->sample.header.misc =3D cs_etm__cpu_mode(etmq, ip); event->sample.header.size =3D sizeof(struct perf_event_header); =20 - if (!etm->timeless_decoding) - sample.time =3D etm->latest_kernel_timestamp; + /* Set time field based con etm auxtrace config. */ + cs_etm__resolve_sample_time(etmq, tidq, &sample.time); + sample.ip =3D ip; sample.pid =3D tidq->pid; sample.tid =3D tidq->tid; @@ -2746,12 +2767,42 @@ static int cs_etm__queue_aux_records(struct perf_se= ssion *session) return 0; } =20 +#define HAS_PARAM(j, type, param) (metadata[(j)][CS_ETM_NR_TRC_PARAMS] <= =3D \ + (CS_##type##_##param - CS_ETM_COMMON_BLK_MAX_V1)) + +/* + * Loop through the ETMs and complain if we find at least one where ts_sou= rce !=3D 1 (virtual + * timestamps). + */ +static bool cs_etm__has_virtual_ts(u64 **metadata, int num_cpu) +{ + int j; + + for (j =3D 0; j < num_cpu; j++) { + switch (metadata[j][CS_ETM_MAGIC]) { + case __perf_cs_etmv4_magic: + if (HAS_PARAM(j, ETMV4, TS_SOURCE) || metadata[j][CS_ETMV4_TS_SOURCE] != =3D 1) + return false; + break; + case __perf_cs_ete_magic: + if (HAS_PARAM(j, ETE, TS_SOURCE) || metadata[j][CS_ETE_TS_SOURCE] !=3D = 1) + return false; + break; + default: + /* Unknown / unsupported magic number. */ + return false; + } + } + return true; +} + int cs_etm__process_auxtrace_info_full(union perf_event *event, struct perf_session *session) { struct perf_record_auxtrace_info *auxtrace_info =3D &event->auxtrace_info; struct cs_etm_auxtrace *etm =3D NULL; struct int_node *inode; + struct perf_record_time_conv *tc =3D &session->time_conv; int event_header_size =3D sizeof(struct perf_event_header); int total_size =3D auxtrace_info->header.size; int priv_size =3D 0; @@ -2886,6 +2937,12 @@ int cs_etm__process_auxtrace_info_full(union perf_ev= ent *event, etm->auxtrace_type =3D auxtrace_info->type; etm->timeless_decoding =3D cs_etm__is_timeless_decoding(etm); =20 + /* Use virtual timestamps if all ETMs report ts_source =3D 1 */ + etm->has_virtual_ts =3D cs_etm__has_virtual_ts(metadata, num_cpu); + + if (!etm->has_virtual_ts) + ui__warning("Virtual timestamps are not enabled, or not supported by the= traced system.\n\nThe time field of the samples will not be set accurately= .\n\n"); + etm->auxtrace.process_event =3D cs_etm__process_event; etm->auxtrace.process_auxtrace_event =3D cs_etm__process_auxtrace_event; etm->auxtrace.flush_events =3D cs_etm__flush_events; @@ -2915,6 +2972,15 @@ int cs_etm__process_auxtrace_info_full(union perf_ev= ent *event, goto err_delete_thread; } =20 + etm->tc.time_shift =3D tc->time_shift; + etm->tc.time_mult =3D tc->time_mult; + etm->tc.time_zero =3D tc->time_zero; + if (event_contains(*tc, time_cycles)) { + etm->tc.time_cycles =3D tc->time_cycles; + etm->tc.time_mask =3D tc->time_mask; + etm->tc.cap_user_time_zero =3D tc->cap_user_time_zero; + etm->tc.cap_user_time_short =3D tc->cap_user_time_short; + } err =3D cs_etm__synth_events(etm, session); if (err) goto err_delete_thread; --=20 2.25.1