[PATCH v2 6/8] perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str

Ian Rogers
2024-11-07T16:50:32Z

On ARM the cpuid is dependent on the core type of the CPU in
question. The PMU was passed for the sake of the CPU map but this
means in places a temporary PMU is created just to pass a CPU
value. Just pass the CPU and fix up the callers.

As there are no longer PMU users in header.h, shuffle forward
declarations earlier to work around build failures.

Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/arch/arm64/util/arm-spe.c | 14 ++------------
tools/perf/arch/arm64/util/header.c | 12 ++++--------
tools/perf/arch/loongarch/util/header.c | 2 +-
tools/perf/arch/powerpc/util/header.c | 2 +-
tools/perf/arch/riscv/util/header.c | 2 +-
tools/perf/arch/s390/util/header.c | 4 ++--
tools/perf/arch/x86/util/header.c | 3 +--
tools/perf/pmu-events/empty-pmu-events.c | 5 ++++-
tools/perf/pmu-events/jevents.py | 5 ++++-
tools/perf/tests/expr.c | 7 +++----
tools/perf/util/expr.c | 6 +++---
tools/perf/util/header.c | 22 +++++++++++++++++++++-
tools/perf/util/header.h | 19 ++++++++++---------
tools/perf/util/pmu.c | 20 --------------------
tools/perf/util/pmu.h | 1 -
15 files changed, 57 insertions(+), 67 deletions(-)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 7ccdea3cd461..22b19dcc6beb 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -23,6 +23,7 @@
#include "../../../util/debug.h"
#include "../../../util/auxtrace.h"
#include "../../../util/record.h"
+#include "../../../util/header.h"
#include "../../../util/arm-spe.h"
#include <tools/libc_compat.h> // reallocarray

@@ -85,22 +86,11 @@ static int arm_spe_save_cpu_header(struct auxtrace_record *itr,
struct arm_spe_recording *sper =
container_of(itr, struct arm_spe_recording, itr);
struct perf_pmu *pmu = NULL;
- struct perf_pmu tmp_pmu;
- char cpu_id_str[16];
char *cpuid = NULL;
u64 val;

- snprintf(cpu_id_str, sizeof(cpu_id_str), "%d", cpu.cpu);
- tmp_pmu.cpus = perf_cpu_map__new(cpu_id_str);
- if (!tmp_pmu.cpus)
- return -ENOMEM;
-
/* Read CPU MIDR */
- cpuid = perf_pmu__getcpuid(&tmp_pmu);
-
- /* The CPU map will not be used anymore, release it */
- perf_cpu_map__put(tmp_pmu.cpus);
-
+ cpuid = get_cpuid_allow_env_override(cpu);
if (!cpuid)
return -ENOMEM;
val = strtol(cpuid, NULL, 16);
diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index f0907daad3ae..f445a2dd6293 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -62,22 +62,18 @@ int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
return EINVAL;
}

-char *get_cpuid_str(struct perf_pmu *pmu)
+char *get_cpuid_str(struct perf_cpu cpu)
{
- char *buf = NULL;
+ char *buf = malloc(MIDR_SIZE);
int res;

- if (!pmu || !pmu->cpus)
- return NULL;
-
- buf = malloc(MIDR_SIZE);
if (!buf)
return NULL;

/* read midr from list of cpus mapped to this pmu */
- res = get_cpuid(buf, MIDR_SIZE, perf_cpu_map__min(pmu->cpus));
+ res = get_cpuid(buf, MIDR_SIZE, cpu);
if (res) {
- pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
+ pr_err("failed to get cpuid string for CPU %d\n", cpu.cpu);
free(buf);
buf = NULL;
}
diff --git a/tools/perf/arch/loongarch/util/header.c b/tools/perf/arch/loongarch/util/header.c
index f1f0b116962d..0c6d823334a2 100644
--- a/tools/perf/arch/loongarch/util/header.c
+++ b/tools/perf/arch/loongarch/util/header.c
@@ -90,7 +90,7 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
return ret;
}

-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu __maybe_unused)
{
return _get_cpuid();
}
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 6d1a63a2922f..c7df534dbf8f 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -42,7 +42,7 @@ get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
}

char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+get_cpuid_str(struct perf_cpu cpu __maybe_unused)
{
char *bufp;
unsigned long pvr;
diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c
index ebac294c877f..4b839203d4a5 100644
--- a/tools/perf/arch/riscv/util/header.c
+++ b/tools/perf/arch/riscv/util/header.c
@@ -98,7 +98,7 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
}

char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+get_cpuid_str(struct perf_cpu cpu __maybe_unused)
{
return _get_cpuid();
}
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
index 2add1a561242..db54677a17d2 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -137,11 +137,11 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
return (nbytes >= sz) ? ENOBUFS : 0;
}

-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu)
{
char *buf = malloc(128);

- if (buf && get_cpuid(buf, 128))
+ if (buf && get_cpuid(buf, 128, cpu))
zfree(&buf);
return buf;
}
diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index 690f86cbbb1c..412977f8aa83 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -63,8 +63,7 @@ get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
}

-char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu __maybe_unused)
{
char *buf = malloc(128);

diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index b8719dab264d..51ca8d61c15d 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -515,13 +515,16 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
} last_map_search;
static bool has_last_result, has_last_map_search;
const struct pmu_events_map *map = NULL;
+ struct perf_cpu cpu = {-1};
char *cpuid = NULL;
size_t i;

if (has_last_result && last_result.pmu == pmu)
return last_result.map;

- cpuid = perf_pmu__getcpuid(pmu);
+ if (pmu)
+ cpu = perf_cpu_map__min(pmu->cpus);
+ cpuid = get_cpuid_allow_env_override(cpu);

/*
* On some platforms which uses cpus map, cpuid can be NULL for
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 70f4fd5395fb..b5ff872e2beb 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1031,13 +1031,16 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
} last_map_search;
static bool has_last_result, has_last_map_search;
const struct pmu_events_map *map = NULL;
+ struct perf_cpu cpu = {-1};
char *cpuid = NULL;
size_t i;

if (has_last_result && last_result.pmu == pmu)
return last_result.map;

- cpuid = perf_pmu__getcpuid(pmu);
+ if (pmu)
+ cpu = perf_cpu_map__min(pmu->cpus);
+ cpuid = get_cpuid_allow_env_override(cpu);

/*
* On some platforms which uses cpus map, cpuid can be NULL for
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index d60f1ac1d720..41ff1affdfcd 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -4,10 +4,9 @@
#include "util/expr.h"
#include "util/hashmap.h"
#include "util/header.h"
-#include "util/pmu.h"
-#include "util/pmus.h"
#include "util/smt.h"
#include "tests.h"
+#include <perf/cpumap.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -78,8 +77,8 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u
struct expr_parse_ctx *ctx;
bool is_intel = false;
char strcmp_cpuid_buf[256];
- struct perf_pmu *pmu = perf_pmus__find_core_pmu();
- char *cpuid = perf_pmu__getcpuid(pmu);
+ struct perf_cpu cpu = {-1};
+ char *cpuid = get_cpuid_allow_env_override(cpu);
char *escaped_cpuid1, *escaped_cpuid2;

TEST_ASSERT_VAL("get_cpuid", cpuid);
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 5e3732bc2fa5..f289044a1f7c 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -8,7 +8,6 @@
#include "debug.h"
#include "evlist.h"
#include "expr.h"
-#include "pmu.h"
#include "smt.h"
#include "tool_pmu.h"
#include <util/expr-bison.h>
@@ -16,6 +15,7 @@
#include "util/hashmap.h"
#include "util/header.h"
#include "util/pmu.h"
+#include <perf/cpumap.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>
@@ -456,8 +456,8 @@ double expr__strcmp_cpuid_str(const struct expr_parse_ctx *ctx __maybe_unused,
bool compute_ids __maybe_unused, const char *test_id)
{
double ret;
- struct perf_pmu *pmu = perf_pmus__find_core_pmu();
- char *cpuid = perf_pmu__getcpuid(pmu);
+ struct perf_cpu cpu = {-1};
+ char *cpuid = get_cpuid_allow_env_override(cpu);

if (!cpuid)
return NAN;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 60b42ddc3dac..06ca5762f61f 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -819,11 +819,31 @@ static int write_group_desc(struct feat_fd *ff,
* Each architecture should provide a more precise id string that
* can be use to match the architecture's "mapfile".
*/
-char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char * __weak get_cpuid_str(struct perf_cpu cpu __maybe_unused)
{
return NULL;
}

+char *get_cpuid_allow_env_override(struct perf_cpu cpu)
+{
+ char *cpuid;
+ static bool printed;
+
+ cpuid = getenv("PERF_CPUID");
+ if (cpuid)
+ cpuid = strdup(cpuid);
+ if (!cpuid)
+ cpuid = get_cpuid_str(cpu);
+ if (!cpuid)
+ return NULL;
+
+ if (!printed) {
+ pr_debug("Using CPUID %s\n", cpuid);
+ printed = true;
+ }
+ return cpuid;
+}
+
/* Return zero when the cpuid from the mapfile.csv matches the
* cpuid string generated on this platform.
* Otherwise return non-zero.
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 3bb768455a60..5201af6305f4 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -10,9 +10,14 @@
#include <linux/bitmap.h>
#include <linux/types.h>
#include "env.h"
-#include "pmu.h"
#include <perf/cpumap.h>

+struct evlist;
+union perf_event;
+struct perf_header;
+struct perf_session;
+struct perf_tool;
+
enum {
HEADER_RESERVED = 0, /* always cleared */
HEADER_FIRST_FEATURE = 1,
@@ -92,8 +97,6 @@ struct perf_pipe_file_header {
u64 size;
};

-struct perf_header;
-
int perf_file_header__read(struct perf_file_header *header,
struct perf_header *ph, int fd);

@@ -125,11 +128,6 @@ struct perf_header_feature_ops {
bool synthesize;
};

-struct evlist;
-struct perf_session;
-struct perf_tool;
-union perf_event;
-
extern const char perf_version_string[];

int perf_session__read_header(struct perf_session *session);
@@ -204,6 +202,9 @@ int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
*/
int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu);

-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused);
+char *get_cpuid_str(struct perf_cpu cpu);
+
+char *get_cpuid_allow_env_override(struct perf_cpu cpu);
+
int strcmp_cpuid_str(const char *s1, const char *s2);
#endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 0789758598c0..514cb865f57b 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -818,26 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
return file_available(path);
}

-char *perf_pmu__getcpuid(struct perf_pmu *pmu)
-{
- char *cpuid;
- static bool printed;
-
- cpuid = getenv("PERF_CPUID");
- if (cpuid)
- cpuid = strdup(cpuid);
- if (!cpuid)
- cpuid = get_cpuid_str(pmu);
- if (!cpuid)
- return NULL;
-
- if (!printed) {
- pr_debug("Using CPUID %s\n", cpuid);
- printed = true;
- }
- return cpuid;
-}
-
__weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
{
return perf_pmu__find_metrics_table(NULL);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index b86b3c3685a2..fba3fc608b64 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
const struct pmu_events_table *table);

-char *perf_pmu__getcpuid(struct perf_pmu *pmu);
const struct pmu_metrics_table *pmu_metrics_table__find(void);
bool pmu_uncore_identifier_match(const char *compat, const char *id);