diff options
Diffstat (limited to 'tools/perf/util/header.c')
| -rw-r--r-- | tools/perf/util/header.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 69374deeb4a8..63aad3109e34 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -20,6 +20,7 @@ #include "symbol.h" #include "debug.h" #include "cpumap.h" +#include "pmu.h" static bool no_buildid_cache = false; @@ -1004,6 +1005,45 @@ done: } /* + * File format: + * + * struct pmu_mappings { + * u32 pmu_num; + * struct pmu_map { + * u32 type; + * char name[]; + * }[pmu_num]; + * }; + */ + +static int write_pmu_mappings(int fd, struct perf_header *h __used, + struct perf_evlist *evlist __used) +{ + struct perf_pmu *pmu = NULL; + off_t offset = lseek(fd, 0, SEEK_CUR); + __u32 pmu_num = 0; + + /* write real pmu_num later */ + do_write(fd, &pmu_num, sizeof(pmu_num)); + + while ((pmu = perf_pmu__scan(pmu))) { + if (!pmu->name) + continue; + pmu_num++; + do_write(fd, &pmu->type, sizeof(pmu->type)); + do_write_string(fd, pmu->name); + } + + if (pwrite(fd, &pmu_num, sizeof(pmu_num), offset) != sizeof(pmu_num)) { + /* discard all */ + lseek(fd, offset, SEEK_SET); + return -1; + } + + return 0; +} + +/* * default get_cpuid(): nothing gets recorded * actual implementation must be in arch/$(ARCH)/util/header.c */ @@ -1389,6 +1429,43 @@ static void print_branch_stack(struct perf_header *ph __used, int fd __used, fprintf(fp, "# contains samples with branch stack\n"); } +static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp) +{ + const char *delimiter = "# pmu mappings: "; + char *name; + int ret; + u32 pmu_num; + u32 type; + + ret = read(fd, &pmu_num, sizeof(pmu_num)); + if (ret != sizeof(pmu_num)) + goto error; + + if (!pmu_num) { + fprintf(fp, "# pmu mappings: not available\n"); + return; + } + + while (pmu_num) { + if (read(fd, &type, sizeof(type)) != sizeof(type)) + break; + name = do_read_string(fd, ph); + if (!name) + break; + pmu_num--; + fprintf(fp, "%s%s = %" PRIu32, delimiter, name, type); + free(name); + delimiter = ", "; + } + + fprintf(fp, "\n"); + + if (!pmu_num) + return; +error: + fprintf(fp, "# pmu mappings: unable to read\n"); +} + static int __event_process_build_id(struct build_id_event *bev, char *filename, struct perf_session *session) @@ -1644,6 +1721,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology), FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology), FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), + FEAT_OPA(HEADER_PMU_MAPPINGS, pmu_mappings), }; struct header_print_data { |
