diff options
| author | Ian Rogers <irogers@google.com> | 2025-11-13 10:05:13 -0800 |
|---|---|---|
| committer | Namhyung Kim <namhyung@kernel.org> | 2025-11-17 18:43:09 -0800 |
| commit | d8d8a0b3603a9a8fa207cf9e4f292e81dc5d1008 (patch) | |
| tree | 1c4619d45ce616b6739935963150a3e745f218f9 /tools/perf | |
| parent | d702c0f4af6e065846e67ff89b34aec2cca7ffa7 (diff) | |
perf tool_pmu: More accurately set the cpus for tool events
The user and system time events can record on different CPUs, but for
all other events a single CPU map of just CPU 0 makes sense. In
parse-events detect a tool PMU and then pass the perf_event_attr so
that the tool_pmu can return CPUs specific for the event. This avoids
a CPU map of all online CPUs being used for events like
duration_time. Avoiding this avoids the evlist CPUs containing CPUs
for which duration_time just gives 0. Minimizing the evlist CPUs can
remove unnecessary sched_setaffinity syscalls that delay metric
calculations.
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/util/parse-events.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/tool_pmu.c | 19 | ||||
| -rw-r--r-- | tools/perf/util/tool_pmu.h | 1 |
3 files changed, 27 insertions, 2 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index e522082c5a21..5ffeb7b416d9 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -30,6 +30,7 @@ #include "util/event.h" #include "util/bpf-filter.h" #include "util/stat.h" +#include "util/tool_pmu.h" #include "util/util.h" #include "tracepoint.h" #include <api/fs/tracing_path.h> @@ -227,8 +228,12 @@ __add_event(struct list_head *list, int *idx, if (pmu) { is_pmu_core = pmu->is_core; pmu_cpus = perf_cpu_map__get(pmu->cpus); - if (perf_cpu_map__is_empty(pmu_cpus)) - pmu_cpus = cpu_map__online(); + if (perf_cpu_map__is_empty(pmu_cpus)) { + if (perf_pmu__is_tool(pmu)) + pmu_cpus = tool_pmu__cpus(attr); + else + pmu_cpus = cpu_map__online(); + } } else { is_pmu_core = (attr->type == PERF_TYPE_HARDWARE || attr->type == PERF_TYPE_HW_CACHE); diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index 6a9df3dc0e07..37c4eae0bef1 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -2,6 +2,7 @@ #include "cgroup.h" #include "counts.h" #include "cputopo.h" +#include "debug.h" #include "evsel.h" #include "pmu.h" #include "print-events.h" @@ -13,6 +14,7 @@ #include <api/fs/fs.h> #include <api/io.h> #include <internal/threadmap.h> +#include <perf/cpumap.h> #include <perf/threadmap.h> #include <fcntl.h> #include <strings.h> @@ -109,6 +111,23 @@ const char *evsel__tool_pmu_event_name(const struct evsel *evsel) return tool_pmu__event_to_str(evsel->core.attr.config); } +struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr) +{ + static struct perf_cpu_map *cpu0_map; + enum tool_pmu_event event = (enum tool_pmu_event)attr->config; + + if (event <= TOOL_PMU__EVENT_NONE || event >= TOOL_PMU__EVENT_MAX) { + pr_err("Invalid tool PMU event config %llx\n", attr->config); + return NULL; + } + if (event == TOOL_PMU__EVENT_USER_TIME || event == TOOL_PMU__EVENT_SYSTEM_TIME) + return cpu_map__online(); + + if (!cpu0_map) + cpu0_map = perf_cpu_map__new_int(0); + return perf_cpu_map__get(cpu0_map); +} + static bool read_until_char(struct io *io, char e) { int c; diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h index f1714001bc1d..ea343d1983d3 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -46,6 +46,7 @@ bool tool_pmu__read_event(enum tool_pmu_event ev, u64 tool_pmu__cpu_slots_per_cycle(void); bool perf_pmu__is_tool(const struct perf_pmu *pmu); +struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr); bool evsel__is_tool(const struct evsel *evsel); enum tool_pmu_event evsel__tool_event(const struct evsel *evsel); |
