perf env: Add perf_env__cpuid, perf_env__{nr_}pmu_mappings
authorKim Phillips <kim.phillips@amd.com>
Tue, 17 Aug 2021 22:15:07 +0000 (17:15 -0500)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 10 Sep 2021 14:45:19 +0000 (11:45 -0300)
To be used by IBS raw data display: It needs the recorder's cpuid in
order to determine which errata workarounds to apply to the data, and
the pmu_mappings are needed in order to figure out which PMU sample
type is IBS Fetch vs. IBS Op.

When not available from perf.data, we assume local operation, and
retrieve cpuid and pmu mappings directly from the running system.

Signed-off-by: Kim Phillips <kim.phillips@amd.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Joao Martins <joao.m.martins@oracle.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: https //lore.kernel.org/r/20210817221509.88391-2-kim.phillips@amd.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/env.c
tools/perf/util/env.h

index 8f7ff00..cf773f0 100644 (file)
@@ -10,6 +10,7 @@
 #include <sys/utsname.h>
 #include <stdlib.h>
 #include <string.h>
+#include "strbuf.h"
 
 struct perf_env perf_env;
 
@@ -306,6 +307,45 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
        return 0;
 }
 
+int perf_env__read_pmu_mappings(struct perf_env *env)
+{
+       struct perf_pmu *pmu = NULL;
+       u32 pmu_num = 0;
+       struct strbuf sb;
+
+       while ((pmu = perf_pmu__scan(pmu))) {
+               if (!pmu->name)
+                       continue;
+               pmu_num++;
+       }
+       if (!pmu_num) {
+               pr_debug("pmu mappings not available\n");
+               return -ENOENT;
+       }
+       env->nr_pmu_mappings = pmu_num;
+
+       if (strbuf_init(&sb, 128 * pmu_num) < 0)
+               return -ENOMEM;
+
+       while ((pmu = perf_pmu__scan(pmu))) {
+               if (!pmu->name)
+                       continue;
+               if (strbuf_addf(&sb, "%u:%s", pmu->type, pmu->name) < 0)
+                       goto error;
+               /* include a NULL character at the end */
+               if (strbuf_add(&sb, "", 1) < 0)
+                       goto error;
+       }
+
+       env->pmu_mappings = strbuf_detach(&sb, NULL);
+
+       return 0;
+
+error:
+       strbuf_release(&sb);
+       return -1;
+}
+
 int perf_env__read_cpuid(struct perf_env *env)
 {
        char cpuid[128];
@@ -404,6 +444,44 @@ const char *perf_env__arch(struct perf_env *env)
        return normalize_arch(arch_name);
 }
 
+const char *perf_env__cpuid(struct perf_env *env)
+{
+       int status;
+
+       if (!env || !env->cpuid) { /* Assume local operation */
+               status = perf_env__read_cpuid(env);
+               if (status)
+                       return NULL;
+       }
+
+       return env->cpuid;
+}
+
+int perf_env__nr_pmu_mappings(struct perf_env *env)
+{
+       int status;
+
+       if (!env || !env->nr_pmu_mappings) { /* Assume local operation */
+               status = perf_env__read_pmu_mappings(env);
+               if (status)
+                       return 0;
+       }
+
+       return env->nr_pmu_mappings;
+}
+
+const char *perf_env__pmu_mappings(struct perf_env *env)
+{
+       int status;
+
+       if (!env || !env->pmu_mappings) { /* Assume local operation */
+               status = perf_env__read_pmu_mappings(env);
+               if (status)
+                       return NULL;
+       }
+
+       return env->pmu_mappings;
+}
 
 int perf_env__numa_node(struct perf_env *env, int cpu)
 {
index 1f51758..1383876 100644 (file)
@@ -149,11 +149,16 @@ int perf_env__kernel_is_64_bit(struct perf_env *env);
 int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);
 
 int perf_env__read_cpuid(struct perf_env *env);
+int perf_env__read_pmu_mappings(struct perf_env *env);
+int perf_env__nr_pmu_mappings(struct perf_env *env);
+const char *perf_env__pmu_mappings(struct perf_env *env);
+
 int perf_env__read_cpu_topology_map(struct perf_env *env);
 
 void cpu_cache_level__free(struct cpu_cache_level *cache);
 
 const char *perf_env__arch(struct perf_env *env);
+const char *perf_env__cpuid(struct perf_env *env);
 const char *perf_env__raw_arch(struct perf_env *env);
 int perf_env__nr_cpus_avail(struct perf_env *env);