aboutsummaryrefslogtreecommitdiff
path: root/pevent/include/pevent.h
diff options
context:
space:
mode:
Diffstat (limited to 'pevent/include/pevent.h')
-rw-r--r--pevent/include/pevent.h268
1 files changed, 268 insertions, 0 deletions
diff --git a/pevent/include/pevent.h b/pevent/include/pevent.h
new file mode 100644
index 000000000000..d41f078b812d
--- /dev/null
+++ b/pevent/include/pevent.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2014-2019, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PEVENT_H
+#define PEVENT_H
+
+#include <linux/perf_event.h>
+
+#include "intel-pt.h"
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+
+/* A perf event configuration. */
+struct pev_config {
+ /* The size of the config structure in bytes. */
+ size_t size;
+
+ /* The respective field in struct perf_event_attr.
+ *
+ * We require sample_id_all in struct perf_event_attr to be set.
+ */
+ uint64_t sample_type;
+
+ /* The respective fields in struct perf_event_mmap_page. */
+ uint16_t time_shift;
+ uint32_t time_mult;
+ uint64_t time_zero;
+};
+
+static inline void pev_config_init(struct pev_config *config)
+{
+ memset(config, 0, sizeof(*config));
+ config->size = sizeof(*config);
+}
+
+
+/* The MMAP perf event record. */
+struct pev_record_mmap {
+ uint32_t pid, tid;
+ uint64_t addr;
+ uint64_t len;
+ uint64_t pgoff;
+ char filename[];
+};
+
+/* The LOST perf event record. */
+struct pev_record_lost {
+ uint64_t id;
+ uint64_t lost;
+};
+
+/* The COMM perf event record. */
+struct pev_record_comm {
+ uint32_t pid, tid;
+ char comm[];
+};
+
+/* The EXIT perf event record. */
+struct pev_record_exit {
+ uint32_t pid, ppid;
+ uint32_t tid, ptid;
+ uint64_t time;
+};
+
+/* The THROTTLE and UNTHROTTLE perf event records. */
+struct pev_record_throttle {
+ uint64_t time;
+ uint64_t id;
+ uint64_t stream_id;
+};
+
+/* The FORK perf event record. */
+struct pev_record_fork {
+ uint32_t pid, ppid;
+ uint32_t tid, ptid;
+ uint64_t time;
+};
+
+/* The MMAP2 perf event record. */
+struct pev_record_mmap2 {
+ uint32_t pid, tid;
+ uint64_t addr;
+ uint64_t len;
+ uint64_t pgoff;
+ uint32_t maj, min;
+ uint64_t ino;
+ uint64_t ino_generation;
+ uint32_t prot, flags;
+ char filename[];
+};
+
+/* The AUX perf event record. */
+struct pev_record_aux {
+ uint64_t aux_offset;
+ uint64_t aux_size;
+ uint64_t flags;
+};
+
+/* The ITRACE_START perf event record. */
+struct pev_record_itrace_start {
+ uint32_t pid, tid;
+};
+
+/* The LOST_SAMPLES perf event record. */
+struct pev_record_lost_samples {
+ uint64_t lost;
+};
+
+/* The SWITCH_CPU_WIDE perf event record. */
+struct pev_record_switch_cpu_wide {
+ uint32_t next_prev_pid;
+ uint32_t next_prev_tid;
+};
+
+/* A perf event record. */
+struct pev_event {
+ /* The record type (enum perf_event_type). */
+ uint32_t type;
+
+ /* The misc field of the perf event header. */
+ uint16_t misc;
+
+ /* The perf event record. */
+ union {
+ /* @type = PERF_RECORD_MMAP. */
+ const struct pev_record_mmap *mmap;
+
+ /* @type = PERF_RECORD_LOST. */
+ const struct pev_record_lost *lost;
+
+ /* @type = PERF_RECORD_COMM. */
+ const struct pev_record_comm *comm;
+
+ /* @type = PERF_RECORD_EXIT. */
+ const struct pev_record_exit *exit;
+
+ /* @type = PERF_RECORD_(UN)THROTTLE. */
+ const struct pev_record_throttle *throttle;
+
+ /* @type = PERF_RECORD_FORK. */
+ const struct pev_record_fork *fork;
+
+ /* @type = PERF_RECORD_MMAP2. */
+ const struct pev_record_mmap2 *mmap2;
+
+ /* @type = PERF_RECORD_AUX. */
+ const struct pev_record_aux *aux;
+
+ /* @type = PERF_RECORD_ITRACE_START. */
+ const struct pev_record_itrace_start *itrace_start;
+
+ /* @type = PERF_RECORD_LOST_SAMPLES. */
+ const struct pev_record_lost_samples *lost_samples;
+
+ /* @type = PERF_RECORD_SWITCH_CPU_WIDE. */
+ const struct pev_record_switch_cpu_wide *switch_cpu_wide;
+ } record;
+
+ /* The additional samples. */
+ struct {
+ /* The sampled pid and tid. */
+ const uint32_t *pid;
+ const uint32_t *tid;
+
+ /* The sampled time in perf_event format. */
+ const uint64_t *time;
+
+ /* The sampled time in TSC format - if @time is not NULL. */
+ uint64_t tsc;
+
+ /* The sampled id. */
+ const uint64_t *id;
+
+ /* The sampled stream id. */
+ const uint64_t *stream_id;
+
+ /* The sampled cpu. */
+ const uint32_t *cpu;
+
+ /* The sample identifier. */
+ const uint64_t *identifier;
+ } sample;
+};
+
+static inline void pev_event_init(struct pev_event *event)
+{
+ memset(event, 0, sizeof(*event));
+}
+
+/* Convert perf_event time to TSC.
+ *
+ * Converts @time in perf_event format to @tsc.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ * Returns -pte_bad_config if @config->size is too small.
+ * Returns -pte_bad_config if @config->time_mult is zero.
+ * Returns -pte_internal if @tsc or @config is NULL.
+ */
+extern int pev_time_to_tsc(uint64_t *tsc, uint64_t time,
+ const struct pev_config *config);
+
+/* Convert TSC to perf_event time.
+ *
+ * Converts @tsc into @time in perf_event format.
+ *
+ * Returns zero on success, a negative error code otherwise.
+ * Returns -pte_bad_config if @config->size is too small.
+ * Returns -pte_bad_config if @config->time_mult is zero.
+ * Returns -pte_internal if @time or @config is NULL.
+ */
+extern int pev_time_from_tsc(uint64_t *time, uint64_t tsc,
+ const struct pev_config *config);
+
+/* Read a perf_event record.
+ *
+ * Reads one perf_event record from [@begin; @end[ into @event.
+ *
+ * Returns the number of bytes read on success, a negative error code otherwise.
+ * Returns -pte_bad_config if @config->size is too small.
+ * Returns -pte_eos if the event does not fit into [@begin; @end[.
+ * Returns -pte_internal if @event, @config, @begin, or @end is NULL.
+ */
+extern int pev_read(struct pev_event *event, const uint8_t *begin,
+ const uint8_t *end, const struct pev_config *config);
+
+/* Write a perf_event record.
+ *
+ * Writes @event into [@begin; @end[.
+ *
+ * Returns the number of bytes written on success, a negative error code
+ * otherwise.
+ * Returns -pte_bad_config if @config->size is too small.
+ * Returns -pte_bad_opc if the event type is not known.
+ * Returns -pte_eos if the event does not fit into [@begin; @end[.
+ * Returns -pte_internal if @begin, @end, @event, or @config is NULL.
+ */
+extern int pev_write(const struct pev_event *event, uint8_t *begin,
+ uint8_t *end, const struct pev_config *config);
+
+#endif /* PEVENT_H */