From 72c6f57a4193f2eadceb52261315438719c4c1ad Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 26 Feb 2025 10:41:00 +0000 Subject: [PATCH] perf pmu: Dynamically allocate tool PMU perf_pmus__destroy() treats all PMUs as allocated and free's them so we can't have any static PMUs that are added to the PMU lists. Fix it by allocating the tool PMU in the same way as the others. Current users of the tool PMU already use find_pmu() and not perf_pmus__tool_pmu(), so rename the function to add 'new' to avoid it being misused in the future. perf_pmus__fake_pmu() can remain as static as it's not added to the PMU lists. Fixes the following error: $ perf bench internals pmu-scan # Running 'internals/pmu-scan' benchmark: Computing performance of sysfs PMU event scan for 100 times munmap_chunk(): invalid pointer Aborted (core dumped) Fixes: 240505b2d0ad ("perf tool_pmu: Factor tool events into their own PMU") Reviewed-by: Ian Rogers Signed-off-by: James Clark Link: https://lore.kernel.org/r/20250226104111.564443-2-james.clark@linaro.org Signed-off-by: Namhyung Kim --- tools/perf/util/pmus.c | 2 +- tools/perf/util/tool_pmu.c | 23 +++++++++++------------ tools/perf/util/tool_pmu.h | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c index afd59d678fd0..dd7c2ffdab38 100644 --- a/tools/perf/util/pmus.c +++ b/tools/perf/util/pmus.c @@ -264,7 +264,7 @@ skip_pe_pmus: if ((to_read_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) != 0 && (read_pmu_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) == 0) { - tool_pmu = perf_pmus__tool_pmu(); + tool_pmu = tool_pmu__new(); list_add_tail(&tool_pmu->list, &other_pmus); } if ((to_read_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) != 0 && diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index 3a68debe7143..9156745ea180 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -490,17 +490,16 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread) return 0; } -struct perf_pmu *perf_pmus__tool_pmu(void) +struct perf_pmu *tool_pmu__new(void) { - static struct perf_pmu tool = { - .name = "tool", - .type = PERF_PMU_TYPE_TOOL, - .aliases = LIST_HEAD_INIT(tool.aliases), - .caps = LIST_HEAD_INIT(tool.caps), - .format = LIST_HEAD_INIT(tool.format), - }; - if (!tool.events_table) - tool.events_table = find_core_events_table("common", "common"); - - return &tool; + struct perf_pmu *tool = zalloc(sizeof(struct perf_pmu)); + + tool->name = strdup("tool"); + tool->type = PERF_PMU_TYPE_TOOL; + INIT_LIST_HEAD(&tool->aliases); + INIT_LIST_HEAD(&tool->caps); + INIT_LIST_HEAD(&tool->format); + tool->events_table = find_core_events_table("common", "common"); + + return tool; } diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h index a60184859080..c6ad1dd90a56 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -51,6 +51,6 @@ int evsel__tool_pmu_open(struct evsel *evsel, int start_cpu_map_idx, int end_cpu_map_idx); int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread); -struct perf_pmu *perf_pmus__tool_pmu(void); +struct perf_pmu *tool_pmu__new(void); #endif /* __TOOL_PMU_H */ -- 2.50.1