Commit 003be8c4 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf stat: Make cputype filter generic

Rather than limit the --cputype argument for "perf list" and "perf
stat" to hybrid PMUs of just cpu_atom and cpu_core, allow any PMU.

Note, that if cpu_atom isn't mounted but a filter of cpu_atom is
requested, then this will now fail. As such a filter would never
succeed, no events can come from that unmounted PMU, then this
behavior could never have been useful and failing is clearer.
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Tested-by: default avatarKan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ahmad Yasin <ahmad.yasin@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Edward Baker <edward.baker@intel.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kang Minchul <tegongkang@gmail.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Samantha Alt <samantha.alt@intel.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20230502223851.2234828-31-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 411ad22e
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include "builtin.h" #include "builtin.h"
#include "util/print-events.h" #include "util/print-events.h"
#include "util/pmus.h"
#include "util/pmu.h" #include "util/pmu.h"
#include "util/pmu-hybrid.h"
#include "util/debug.h" #include "util/debug.h"
#include "util/metricgroup.h" #include "util/metricgroup.h"
#include "util/string2.h" #include "util/string2.h"
...@@ -429,7 +429,7 @@ int cmd_list(int argc, const char **argv) ...@@ -429,7 +429,7 @@ int cmd_list(int argc, const char **argv)
.print_event = default_print_event, .print_event = default_print_event,
.print_metric = default_print_metric, .print_metric = default_print_metric,
}; };
const char *hybrid_name = NULL; const char *cputype = NULL;
const char *unit_name = NULL; const char *unit_name = NULL;
bool json = false; bool json = false;
struct option list_options[] = { struct option list_options[] = {
...@@ -443,8 +443,8 @@ int cmd_list(int argc, const char **argv) ...@@ -443,8 +443,8 @@ int cmd_list(int argc, const char **argv)
"Print information on the perf event names and expressions used internally by events."), "Print information on the perf event names and expressions used internally by events."),
OPT_BOOLEAN(0, "deprecated", &default_ps.deprecated, OPT_BOOLEAN(0, "deprecated", &default_ps.deprecated,
"Print deprecated events."), "Print deprecated events."),
OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", OPT_STRING(0, "cputype", &cputype, "cpu type",
"Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), "Limit PMU or metric printing to the given PMU (e.g. cpu, core or atom)."),
OPT_STRING(0, "unit", &unit_name, "PMU name", OPT_STRING(0, "unit", &unit_name, "PMU name",
"Limit PMU or metric printing to the specified PMU."), "Limit PMU or metric printing to the specified PMU."),
OPT_INCR(0, "debug", &verbose, OPT_INCR(0, "debug", &verbose,
...@@ -484,10 +484,15 @@ int cmd_list(int argc, const char **argv) ...@@ -484,10 +484,15 @@ int cmd_list(int argc, const char **argv)
assert(default_ps.visited_metrics); assert(default_ps.visited_metrics);
if (unit_name) if (unit_name)
default_ps.pmu_glob = strdup(unit_name); default_ps.pmu_glob = strdup(unit_name);
else if (hybrid_name) { else if (cputype) {
default_ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype);
if (!default_ps.pmu_glob)
pr_warning("WARNING: hybrid cputype is not supported!\n"); if (!pmu) {
pr_err("ERROR: cputype is not supported!\n");
ret = -1;
goto out;
}
default_ps.pmu_glob = pmu->name;
} }
} }
print_cb.print_start(ps); print_cb.print_start(ps);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "util/cgroup.h" #include "util/cgroup.h"
#include <subcmd/parse-options.h> #include <subcmd/parse-options.h>
#include "util/parse-events.h" #include "util/parse-events.h"
#include "util/pmus.h"
#include "util/pmu.h" #include "util/pmu.h"
#include "util/event.h" #include "util/event.h"
#include "util/evlist.h" #include "util/evlist.h"
...@@ -69,7 +70,6 @@ ...@@ -69,7 +70,6 @@
#include "util/pfm.h" #include "util/pfm.h"
#include "util/bpf_counter.h" #include "util/bpf_counter.h"
#include "util/iostat.h" #include "util/iostat.h"
#include "util/pmu-hybrid.h"
#include "util/util.h" #include "util/util.h"
#include "asm/bug.h" #include "asm/bug.h"
...@@ -1089,10 +1089,11 @@ static int parse_stat_cgroups(const struct option *opt, ...@@ -1089,10 +1089,11 @@ static int parse_stat_cgroups(const struct option *opt,
return parse_cgroups(opt, str, unset); return parse_cgroups(opt, str, unset);
} }
static int parse_hybrid_type(const struct option *opt, static int parse_cputype(const struct option *opt,
const char *str, const char *str,
int unset __maybe_unused) int unset __maybe_unused)
{ {
const struct perf_pmu *pmu;
struct evlist *evlist = *(struct evlist **)opt->value; struct evlist *evlist = *(struct evlist **)opt->value;
if (!list_empty(&evlist->core.entries)) { if (!list_empty(&evlist->core.entries)) {
...@@ -1100,11 +1101,12 @@ static int parse_hybrid_type(const struct option *opt, ...@@ -1100,11 +1101,12 @@ static int parse_hybrid_type(const struct option *opt,
return -1; return -1;
} }
parse_events_option_args.pmu_filter = perf_pmu__hybrid_type_to_pmu(str); pmu = perf_pmus__pmu_for_pmu_filter(str);
if (!parse_events_option_args.pmu_filter) { if (!pmu) {
fprintf(stderr, "--cputype %s is not supported!\n", str); fprintf(stderr, "--cputype %s is not supported!\n", str);
return -1; return -1;
} }
parse_events_option_args.pmu_filter = pmu->name;
return 0; return 0;
} }
...@@ -1230,7 +1232,7 @@ static struct option stat_options[] = { ...@@ -1230,7 +1232,7 @@ static struct option stat_options[] = {
OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type", OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type",
"Only enable events on applying cpu with this type " "Only enable events on applying cpu with this type "
"for hybrid platform (e.g. core or atom)", "for hybrid platform (e.g. core or atom)",
parse_hybrid_type), parse_cputype),
#ifdef HAVE_LIBPFM #ifdef HAVE_LIBPFM
OPT_CALLBACK(0, "pfm-events", &evsel_list, "event", OPT_CALLBACK(0, "pfm-events", &evsel_list, "event",
"libpfm4 event selector. use 'perf list' to list available events", "libpfm4 event selector. use 'perf list' to list available events",
......
...@@ -50,23 +50,3 @@ bool perf_pmu__is_hybrid(const char *name) ...@@ -50,23 +50,3 @@ bool perf_pmu__is_hybrid(const char *name)
{ {
return perf_pmu__find_hybrid_pmu(name) != NULL; return perf_pmu__find_hybrid_pmu(name) != NULL;
} }
char *perf_pmu__hybrid_type_to_pmu(const char *type)
{
char *pmu_name = NULL;
if (asprintf(&pmu_name, "cpu_%s", type) < 0)
return NULL;
if (perf_pmu__is_hybrid(pmu_name))
return pmu_name;
/*
* pmu may be not scanned, check the sysfs.
*/
if (perf_pmu__hybrid_mounted(pmu_name))
return pmu_name;
free(pmu_name);
return NULL;
}
...@@ -17,7 +17,6 @@ bool perf_pmu__hybrid_mounted(const char *name); ...@@ -17,7 +17,6 @@ bool perf_pmu__hybrid_mounted(const char *name);
struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name); struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name);
bool perf_pmu__is_hybrid(const char *name); bool perf_pmu__is_hybrid(const char *name);
char *perf_pmu__hybrid_type_to_pmu(const char *type);
static inline int perf_pmu__hybrid_pmu_num(void) static inline int perf_pmu__hybrid_pmu_num(void)
{ {
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/list.h> #include <linux/list.h>
#include <pmus.h> #include <string.h>
#include "pmus.h"
#include "pmu.h"
LIST_HEAD(pmus); LIST_HEAD(pmus);
const struct perf_pmu *perf_pmus__pmu_for_pmu_filter(const char *str)
{
struct perf_pmu *pmu = NULL;
while ((pmu = perf_pmu__scan(pmu)) != NULL) {
if (!strcmp(pmu->name, str))
return pmu;
/* Ignore "uncore_" prefix. */
if (!strncmp(pmu->name, "uncore_", 7)) {
if (!strcmp(pmu->name + 7, str))
return pmu;
}
/* Ignore "cpu_" prefix on Intel hybrid PMUs. */
if (!strncmp(pmu->name, "cpu_", 4)) {
if (!strcmp(pmu->name + 4, str))
return pmu;
}
}
return NULL;
}
...@@ -3,7 +3,10 @@ ...@@ -3,7 +3,10 @@
#define __PMUS_H #define __PMUS_H
extern struct list_head pmus; extern struct list_head pmus;
struct perf_pmu;
#define perf_pmus__for_each_pmu(pmu) list_for_each_entry(pmu, &pmus, list) #define perf_pmus__for_each_pmu(pmu) list_for_each_entry(pmu, &pmus, list)
const struct perf_pmu *perf_pmus__pmu_for_pmu_filter(const char *str);
#endif /* __PMUS_H */ #endif /* __PMUS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment