summaryrefslogtreecommitdiff
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c78
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 {