Message ID | 20230120143702.4035046-3-james.clark@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | perf cs_etm: Basic support for virtual/kernel timestamps | expand |
Em Fri, Jan 20, 2023 at 02:36:55PM +0000, James Clark escreveu: > Remove some code that duplicates existing methods. Copy strings where > const strings are required. > > No functional changes. Have you used 'perf test'? [acme@quaco perf]$ perf test -v python Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc 19: 'import perf' in python : --- start --- test child forked, pid 232379 python usage test: "echo "import sys ; sys.path.append('/tmp/build/perf/python'); import perf" | '/usr/bin/python3' " Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: /tmp/build/perf/python/perf.cpython-310-x86_64-linux-gnu.so: undefined symbol: perf_pmu__scan_file test child finished with -1 ---- end ---- 'import perf' in python: FAILED! [acme@quaco perf]$ > Reviewed-by: Leo Yan <leo.yan@linaro.org> > Signed-off-by: James Clark <james.clark@arm.com> > --- > 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 = NULL, *p; > FILE *fp; > size_t len = 0; > @@ -432,12 +430,7 @@ static int load_hybrid_node(struct hybrid_topology_node *node, > if (!node->pmu_name) > return -1; > > - sysfs = sysfs__mountpoint(); > - if (!sysfs) > - goto err; > - > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, pmu->name); > - fp = fopen(path, "r"); > + fp = perf_pmu__open_file(pmu, "cpus"); > if (!fp) > goto err; > > 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); > > 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 = {.name = pmu_name}; > > if (strncmp(name, "cpu_", 4)) > return false; > > - sysfs = sysfs__mountpoint(); > - if (!sysfs) > - return false; > - > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name); > - if (!file_available(path)) > - return false; > - > - file = fopen(path, "r"); > - if (!file) > - return false; > - > - n = fscanf(file, "%u", &cpu); > - fclose(file); > - if (n <= 0) > - return false; > - > - return true; > + strlcpy(pmu_name, name, sizeof(pmu_name)); > + return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0; > } > > 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 1edbb714ff32..a771a5972fc5 100644 > --- a/tools/perf/util/pmu.c > +++ b/tools/perf/util/pmu.c > @@ -571,45 +571,31 @@ static void pmu_read_sysfs(void) > closedir(dir); > } > > -static struct perf_cpu_map *__pmu_cpumask(const char *path) > -{ > - FILE *file; > - struct perf_cpu_map *cpus; > - > - file = fopen(path, "r"); > - if (!file) > - return NULL; > - > - cpus = perf_cpu_map__read(file); > - fclose(file); > - return cpus; > -} > - > /* > * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) > * 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" > > static struct perf_cpu_map *pmu_cpumask(const char *name) > { > - char path[PATH_MAX]; > struct perf_cpu_map *cpus; > - const char *sysfs = sysfs__mountpoint(); > const char *templates[] = { > - CPUS_TEMPLATE_UNCORE, > - CPUS_TEMPLATE_CPU, > + "cpumask", > + "cpus", > NULL > }; > const char **template; > + char pmu_name[PATH_MAX]; > + struct perf_pmu pmu = {.name = pmu_name}; > + FILE *file; > > - if (!sysfs) > - return NULL; > - > + strlcpy(pmu_name, name, sizeof(pmu_name)); > for (template = templates; *template; template++) { > - snprintf(path, PATH_MAX, *template, sysfs, name); > - cpus = __pmu_cpumask(path); > + file = perf_pmu__open_file(&pmu, *template); > + if (!file) > + continue; > + cpus = perf_cpu_map__read(file); > if (cpus) > return cpus; > } > @@ -620,13 +606,11 @@ static struct perf_cpu_map *pmu_cpumask(const char *name) > static bool pmu_is_uncore(const char *name) > { > char path[PATH_MAX]; > - const char *sysfs; > > if (perf_pmu__hybrid_mounted(name)) > return false; > > - sysfs = sysfs__mountpoint(); > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); > + perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpumask"); > return file_available(path); > } > > @@ -1737,7 +1721,7 @@ bool pmu_have_event(const char *pname, const char *name) > return false; > } > > -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]; > > diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h > index 96d030c8b3b3..742d4db319a0 100644 > --- a/tools/perf/util/pmu.h > +++ b/tools/perf/util/pmu.h > @@ -7,6 +7,7 @@ > #include <linux/perf_event.h> > #include <linux/list.h> > #include <stdbool.h> > +#include <stdio.h> > #include "parse-events.h" > #include "pmu-events/pmu-events.h" > > @@ -22,7 +23,6 @@ enum { > }; > > #define PERF_PMU_FORMAT_BITS 64 > -#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" > #define MAX_PMU_NAME_LEN 128 > > struct perf_event_attr; > @@ -262,5 +262,6 @@ double perf_pmu__cpu_slots_per_cycle(void); > 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); > > #endif /* __PMU_H */ > -- > 2.25.1 >
Em Fri, Jan 20, 2023 at 02:21:56PM -0300, Arnaldo Carvalho de Melo escreveu: > Em Fri, Jan 20, 2023 at 02:36:55PM +0000, James Clark escreveu: > > Remove some code that duplicates existing methods. Copy strings where > > const strings are required. > > > > No functional changes. > > > Have you used 'perf test'? > > [acme@quaco perf]$ perf test -v python > Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc > 19: 'import perf' in python : > --- start --- > test child forked, pid 232379 > python usage test: "echo "import sys ; sys.path.append('/tmp/build/perf/python'); import perf" | '/usr/bin/python3' " > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > ImportError: /tmp/build/perf/python/perf.cpython-310-x86_64-linux-gnu.so: undefined symbol: perf_pmu__scan_file > test child finished with -1 > ---- end ---- > 'import perf' in python: FAILED! > [acme@quaco perf]$ I added this to this cset, now it passes. diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index d948455e5ed43656..9e5d881b098767a3 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -20,6 +20,7 @@ #include "stat.h" #include "metricgroup.h" #include "util/env.h" +#include "util/pmu.h" #include <internal/lib.h> #include "util.h" @@ -83,7 +84,7 @@ void perf_stat__collect_metric_expr(struct evlist *evsel_list) } /* - * This one is needed not to drag the PMU bandwagon, jevents generated + * These ones are needed not to drag the PMU bandwagon, jevents generated * pmu_sys_event_tables, etc and evsel__find_pmu() is used so far just for * doing per PMU perf_event_attr.exclude_guest handling, not really needed, so * far, for the perf python binding known usecases, revisit if this become @@ -94,6 +95,11 @@ struct perf_pmu *evsel__find_pmu(struct evsel *evsel __maybe_unused) return NULL; } +int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) +{ + return EOF; +} + /* * Add this one here not to drag util/metricgroup.c */ > > Reviewed-by: Leo Yan <leo.yan@linaro.org> > > Signed-off-by: James Clark <james.clark@arm.com> > > --- > > 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 = NULL, *p; > > FILE *fp; > > size_t len = 0; > > @@ -432,12 +430,7 @@ static int load_hybrid_node(struct hybrid_topology_node *node, > > if (!node->pmu_name) > > return -1; > > > > - sysfs = sysfs__mountpoint(); > > - if (!sysfs) > > - goto err; > > - > > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, pmu->name); > > - fp = fopen(path, "r"); > > + fp = perf_pmu__open_file(pmu, "cpus"); > > if (!fp) > > goto err; > > > > 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); > > > > 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 = {.name = pmu_name}; > > > > if (strncmp(name, "cpu_", 4)) > > return false; > > > > - sysfs = sysfs__mountpoint(); > > - if (!sysfs) > > - return false; > > - > > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name); > > - if (!file_available(path)) > > - return false; > > - > > - file = fopen(path, "r"); > > - if (!file) > > - return false; > > - > > - n = fscanf(file, "%u", &cpu); > > - fclose(file); > > - if (n <= 0) > > - return false; > > - > > - return true; > > + strlcpy(pmu_name, name, sizeof(pmu_name)); > > + return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0; > > } > > > > 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 1edbb714ff32..a771a5972fc5 100644 > > --- a/tools/perf/util/pmu.c > > +++ b/tools/perf/util/pmu.c > > @@ -571,45 +571,31 @@ static void pmu_read_sysfs(void) > > closedir(dir); > > } > > > > -static struct perf_cpu_map *__pmu_cpumask(const char *path) > > -{ > > - FILE *file; > > - struct perf_cpu_map *cpus; > > - > > - file = fopen(path, "r"); > > - if (!file) > > - return NULL; > > - > > - cpus = perf_cpu_map__read(file); > > - fclose(file); > > - return cpus; > > -} > > - > > /* > > * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) > > * 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" > > > > static struct perf_cpu_map *pmu_cpumask(const char *name) > > { > > - char path[PATH_MAX]; > > struct perf_cpu_map *cpus; > > - const char *sysfs = sysfs__mountpoint(); > > const char *templates[] = { > > - CPUS_TEMPLATE_UNCORE, > > - CPUS_TEMPLATE_CPU, > > + "cpumask", > > + "cpus", > > NULL > > }; > > const char **template; > > + char pmu_name[PATH_MAX]; > > + struct perf_pmu pmu = {.name = pmu_name}; > > + FILE *file; > > > > - if (!sysfs) > > - return NULL; > > - > > + strlcpy(pmu_name, name, sizeof(pmu_name)); > > for (template = templates; *template; template++) { > > - snprintf(path, PATH_MAX, *template, sysfs, name); > > - cpus = __pmu_cpumask(path); > > + file = perf_pmu__open_file(&pmu, *template); > > + if (!file) > > + continue; > > + cpus = perf_cpu_map__read(file); > > if (cpus) > > return cpus; > > } > > @@ -620,13 +606,11 @@ static struct perf_cpu_map *pmu_cpumask(const char *name) > > static bool pmu_is_uncore(const char *name) > > { > > char path[PATH_MAX]; > > - const char *sysfs; > > > > if (perf_pmu__hybrid_mounted(name)) > > return false; > > > > - sysfs = sysfs__mountpoint(); > > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); > > + perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpumask"); > > return file_available(path); > > } > > > > @@ -1737,7 +1721,7 @@ bool pmu_have_event(const char *pname, const char *name) > > return false; > > } > > > > -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]; > > > > diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h > > index 96d030c8b3b3..742d4db319a0 100644 > > --- a/tools/perf/util/pmu.h > > +++ b/tools/perf/util/pmu.h > > @@ -7,6 +7,7 @@ > > #include <linux/perf_event.h> > > #include <linux/list.h> > > #include <stdbool.h> > > +#include <stdio.h> > > #include "parse-events.h" > > #include "pmu-events/pmu-events.h" > > > > @@ -22,7 +23,6 @@ enum { > > }; > > > > #define PERF_PMU_FORMAT_BITS 64 > > -#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" > > #define MAX_PMU_NAME_LEN 128 > > > > struct perf_event_attr; > > @@ -262,5 +262,6 @@ double perf_pmu__cpu_slots_per_cycle(void); > > 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); > > > > #endif /* __PMU_H */ > > -- > > 2.25.1 > > > > -- > > - Arnaldo
Em Fri, Jan 20, 2023 at 02:32:30PM -0300, Arnaldo Carvalho de Melo escreveu: > Em Fri, Jan 20, 2023 at 02:21:56PM -0300, Arnaldo Carvalho de Melo escreveu: > > Em Fri, Jan 20, 2023 at 02:36:55PM +0000, James Clark escreveu: > > > Remove some code that duplicates existing methods. Copy strings where > > > const strings are required. > > > > > > No functional changes. > > > > > > Have you used 'perf test'? > > > > [acme@quaco perf]$ perf test -v python > > Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc > > 19: 'import perf' in python : > > --- start --- > > test child forked, pid 232379 > > python usage test: "echo "import sys ; sys.path.append('/tmp/build/perf/python'); import perf" | '/usr/bin/python3' " > > Traceback (most recent call last): > > File "<stdin>", line 1, in <module> > > ImportError: /tmp/build/perf/python/perf.cpython-310-x86_64-linux-gnu.so: undefined symbol: perf_pmu__scan_file > > test child finished with -1 > > ---- end ---- > > 'import perf' in python: FAILED! > > [acme@quaco perf]$ > > I added this to this cset, now it passes. So, what I have is now at my tmp.perf/core branch, pending container testing, later today probably will move to perf/core, so that it gets exposure on linux-next for v6.3. For your convenience: https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/log/?h=tmp.perf/core Thanks, - Arnaldo > diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c > index d948455e5ed43656..9e5d881b098767a3 100644 > --- a/tools/perf/util/python.c > +++ b/tools/perf/util/python.c > @@ -20,6 +20,7 @@ > #include "stat.h" > #include "metricgroup.h" > #include "util/env.h" > +#include "util/pmu.h" > #include <internal/lib.h> > #include "util.h" > > @@ -83,7 +84,7 @@ void perf_stat__collect_metric_expr(struct evlist *evsel_list) > } > > /* > - * This one is needed not to drag the PMU bandwagon, jevents generated > + * These ones are needed not to drag the PMU bandwagon, jevents generated > * pmu_sys_event_tables, etc and evsel__find_pmu() is used so far just for > * doing per PMU perf_event_attr.exclude_guest handling, not really needed, so > * far, for the perf python binding known usecases, revisit if this become > @@ -94,6 +95,11 @@ struct perf_pmu *evsel__find_pmu(struct evsel *evsel __maybe_unused) > return NULL; > } > > +int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) > +{ > + return EOF; > +} > + > /* > * Add this one here not to drag util/metricgroup.c > */ > > > > Reviewed-by: Leo Yan <leo.yan@linaro.org> > > > Signed-off-by: James Clark <james.clark@arm.com> > > > --- > > > 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 = NULL, *p; > > > FILE *fp; > > > size_t len = 0; > > > @@ -432,12 +430,7 @@ static int load_hybrid_node(struct hybrid_topology_node *node, > > > if (!node->pmu_name) > > > return -1; > > > > > > - sysfs = sysfs__mountpoint(); > > > - if (!sysfs) > > > - goto err; > > > - > > > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, pmu->name); > > > - fp = fopen(path, "r"); > > > + fp = perf_pmu__open_file(pmu, "cpus"); > > > if (!fp) > > > goto err; > > > > > > 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); > > > > > > 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 = {.name = pmu_name}; > > > > > > if (strncmp(name, "cpu_", 4)) > > > return false; > > > > > > - sysfs = sysfs__mountpoint(); > > > - if (!sysfs) > > > - return false; > > > - > > > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name); > > > - if (!file_available(path)) > > > - return false; > > > - > > > - file = fopen(path, "r"); > > > - if (!file) > > > - return false; > > > - > > > - n = fscanf(file, "%u", &cpu); > > > - fclose(file); > > > - if (n <= 0) > > > - return false; > > > - > > > - return true; > > > + strlcpy(pmu_name, name, sizeof(pmu_name)); > > > + return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0; > > > } > > > > > > 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 1edbb714ff32..a771a5972fc5 100644 > > > --- a/tools/perf/util/pmu.c > > > +++ b/tools/perf/util/pmu.c > > > @@ -571,45 +571,31 @@ static void pmu_read_sysfs(void) > > > closedir(dir); > > > } > > > > > > -static struct perf_cpu_map *__pmu_cpumask(const char *path) > > > -{ > > > - FILE *file; > > > - struct perf_cpu_map *cpus; > > > - > > > - file = fopen(path, "r"); > > > - if (!file) > > > - return NULL; > > > - > > > - cpus = perf_cpu_map__read(file); > > > - fclose(file); > > > - return cpus; > > > -} > > > - > > > /* > > > * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) > > > * 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" > > > > > > static struct perf_cpu_map *pmu_cpumask(const char *name) > > > { > > > - char path[PATH_MAX]; > > > struct perf_cpu_map *cpus; > > > - const char *sysfs = sysfs__mountpoint(); > > > const char *templates[] = { > > > - CPUS_TEMPLATE_UNCORE, > > > - CPUS_TEMPLATE_CPU, > > > + "cpumask", > > > + "cpus", > > > NULL > > > }; > > > const char **template; > > > + char pmu_name[PATH_MAX]; > > > + struct perf_pmu pmu = {.name = pmu_name}; > > > + FILE *file; > > > > > > - if (!sysfs) > > > - return NULL; > > > - > > > + strlcpy(pmu_name, name, sizeof(pmu_name)); > > > for (template = templates; *template; template++) { > > > - snprintf(path, PATH_MAX, *template, sysfs, name); > > > - cpus = __pmu_cpumask(path); > > > + file = perf_pmu__open_file(&pmu, *template); > > > + if (!file) > > > + continue; > > > + cpus = perf_cpu_map__read(file); > > > if (cpus) > > > return cpus; > > > } > > > @@ -620,13 +606,11 @@ static struct perf_cpu_map *pmu_cpumask(const char *name) > > > static bool pmu_is_uncore(const char *name) > > > { > > > char path[PATH_MAX]; > > > - const char *sysfs; > > > > > > if (perf_pmu__hybrid_mounted(name)) > > > return false; > > > > > > - sysfs = sysfs__mountpoint(); > > > - snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); > > > + perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpumask"); > > > return file_available(path); > > > } > > > > > > @@ -1737,7 +1721,7 @@ bool pmu_have_event(const char *pname, const char *name) > > > return false; > > > } > > > > > > -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]; > > > > > > diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h > > > index 96d030c8b3b3..742d4db319a0 100644 > > > --- a/tools/perf/util/pmu.h > > > +++ b/tools/perf/util/pmu.h > > > @@ -7,6 +7,7 @@ > > > #include <linux/perf_event.h> > > > #include <linux/list.h> > > > #include <stdbool.h> > > > +#include <stdio.h> > > > #include "parse-events.h" > > > #include "pmu-events/pmu-events.h" > > > > > > @@ -22,7 +23,6 @@ enum { > > > }; > > > > > > #define PERF_PMU_FORMAT_BITS 64 > > > -#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" > > > #define MAX_PMU_NAME_LEN 128 > > > > > > struct perf_event_attr; > > > @@ -262,5 +262,6 @@ double perf_pmu__cpu_slots_per_cycle(void); > > > 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); > > > > > > #endif /* __PMU_H */ > > > -- > > > 2.25.1 > > > > > > > -- > > > > - Arnaldo > > -- > > - Arnaldo
On 20/01/2023 17:43, Arnaldo Carvalho de Melo wrote: > Em Fri, Jan 20, 2023 at 02:32:30PM -0300, Arnaldo Carvalho de Melo escreveu: >> Em Fri, Jan 20, 2023 at 02:21:56PM -0300, Arnaldo Carvalho de Melo escreveu: >>> Em Fri, Jan 20, 2023 at 02:36:55PM +0000, James Clark escreveu: >>>> Remove some code that duplicates existing methods. Copy strings where >>>> const strings are required. >>>> >>>> No functional changes. >>> >>> >>> Have you used 'perf test'? >>> >>> [acme@quaco perf]$ perf test -v python >>> Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc >>> 19: 'import perf' in python : >>> --- start --- >>> test child forked, pid 232379 >>> python usage test: "echo "import sys ; sys.path.append('/tmp/build/perf/python'); import perf" | '/usr/bin/python3' " >>> Traceback (most recent call last): >>> File "<stdin>", line 1, in <module> >>> ImportError: /tmp/build/perf/python/perf.cpython-310-x86_64-linux-gnu.so: undefined symbol: perf_pmu__scan_file >>> test child finished with -1 >>> ---- end ---- >>> 'import perf' in python: FAILED! >>> [acme@quaco perf]$ >> >> I added this to this cset, now it passes. > > So, what I have is now at my tmp.perf/core branch, pending container > testing, later today probably will move to perf/core, so that it gets > exposure on linux-next for v6.3. > Gah! Sorry, I must have only run the Coresight tests. I will make sure all the tests are passing on my setup so it's easier to spot next time. Thanks for the fix.
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 = NULL, *p; FILE *fp; size_t len = 0; @@ -432,12 +430,7 @@ static int load_hybrid_node(struct hybrid_topology_node *node, if (!node->pmu_name) return -1; - sysfs = sysfs__mountpoint(); - if (!sysfs) - goto err; - - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, pmu->name); - fp = fopen(path, "r"); + fp = perf_pmu__open_file(pmu, "cpus"); if (!fp) goto err; 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); 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 = {.name = pmu_name}; if (strncmp(name, "cpu_", 4)) return false; - sysfs = sysfs__mountpoint(); - if (!sysfs) - return false; - - snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name); - if (!file_available(path)) - return false; - - file = fopen(path, "r"); - if (!file) - return false; - - n = fscanf(file, "%u", &cpu); - fclose(file); - if (n <= 0) - return false; - - return true; + strlcpy(pmu_name, name, sizeof(pmu_name)); + return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0; } 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 1edbb714ff32..a771a5972fc5 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -571,45 +571,31 @@ static void pmu_read_sysfs(void) closedir(dir); } -static struct perf_cpu_map *__pmu_cpumask(const char *path) -{ - FILE *file; - struct perf_cpu_map *cpus; - - file = fopen(path, "r"); - if (!file) - return NULL; - - cpus = perf_cpu_map__read(file); - fclose(file); - return cpus; -} - /* * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) * 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" static struct perf_cpu_map *pmu_cpumask(const char *name) { - char path[PATH_MAX]; struct perf_cpu_map *cpus; - const char *sysfs = sysfs__mountpoint(); const char *templates[] = { - CPUS_TEMPLATE_UNCORE, - CPUS_TEMPLATE_CPU, + "cpumask", + "cpus", NULL }; const char **template; + char pmu_name[PATH_MAX]; + struct perf_pmu pmu = {.name = pmu_name}; + FILE *file; - if (!sysfs) - return NULL; - + strlcpy(pmu_name, name, sizeof(pmu_name)); for (template = templates; *template; template++) { - snprintf(path, PATH_MAX, *template, sysfs, name); - cpus = __pmu_cpumask(path); + file = perf_pmu__open_file(&pmu, *template); + if (!file) + continue; + cpus = perf_cpu_map__read(file); if (cpus) return cpus; } @@ -620,13 +606,11 @@ static struct perf_cpu_map *pmu_cpumask(const char *name) static bool pmu_is_uncore(const char *name) { char path[PATH_MAX]; - const char *sysfs; if (perf_pmu__hybrid_mounted(name)) return false; - sysfs = sysfs__mountpoint(); - snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); + perf_pmu__pathname_scnprintf(path, sizeof(path), name, "cpumask"); return file_available(path); } @@ -1737,7 +1721,7 @@ bool pmu_have_event(const char *pname, const char *name) return false; } -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]; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 96d030c8b3b3..742d4db319a0 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -7,6 +7,7 @@ #include <linux/perf_event.h> #include <linux/list.h> #include <stdbool.h> +#include <stdio.h> #include "parse-events.h" #include "pmu-events/pmu-events.h" @@ -22,7 +23,6 @@ enum { }; #define PERF_PMU_FORMAT_BITS 64 -#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" #define MAX_PMU_NAME_LEN 128 struct perf_event_attr; @@ -262,5 +262,6 @@ double perf_pmu__cpu_slots_per_cycle(void); 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); #endif /* __PMU_H */