blob: 68e0f32e44995ce97e4f5bd2e52c1f7e6f44a9e4 [file] [log] [blame]
/* Copyright (C) 2009-2016, the Linux Perf authors
* Copyright (c) 2015 Google Inc
* Davide Libenzi <dlibenzi@google.com>
* See LICENSE for details.
*
* Parts of this file come, either directly, or as baseline, from the Linux
* kernel source file:
*
* tools/perf/util/header.h
*
* Such file is ruled by the general Linux kernel copyright.
*/
#pragma once
#define BITS_PER_LONG (8 * sizeof(long))
#define BITS_TO_LONGS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
#define DECLARE_BITMAP(name, bits) \
unsigned long name[BITS_TO_LONGS(bits)]
enum {
HEADER_RESERVED = 0, /* Always cleared */
HEADER_FIRST_FEATURE = 1,
HEADER_TRACING_DATA = 1,
HEADER_BUILD_ID,
HEADER_HOSTNAME,
HEADER_OSRELEASE,
HEADER_VERSION,
HEADER_ARCH,
HEADER_NRCPUS,
HEADER_CPUDESC,
HEADER_CPUID,
HEADER_TOTAL_MEM,
HEADER_CMDLINE,
HEADER_EVENT_DESC,
HEADER_CPU_TOPOLOGY,
HEADER_NUMA_TOPOLOGY,
HEADER_BRANCH_STACK,
HEADER_PMU_MAPPINGS,
HEADER_GROUP_DESC,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
/*
* Bits that can be set in attr.sample_type to request information
* in the overflow packets.
*/
enum perf_event_sample_format {
PERF_SAMPLE_IP = 1U << 0,
PERF_SAMPLE_TID = 1U << 1,
PERF_SAMPLE_TIME = 1U << 2,
PERF_SAMPLE_ADDR = 1U << 3,
PERF_SAMPLE_READ = 1U << 4,
PERF_SAMPLE_CALLCHAIN = 1U << 5,
PERF_SAMPLE_ID = 1U << 6,
PERF_SAMPLE_CPU = 1U << 7,
PERF_SAMPLE_PERIOD = 1U << 8,
PERF_SAMPLE_STREAM_ID = 1U << 9,
PERF_SAMPLE_RAW = 1U << 10,
PERF_SAMPLE_BRANCH_STACK = 1U << 11,
PERF_SAMPLE_REGS_USER = 1U << 12,
PERF_SAMPLE_STACK_USER = 1U << 13,
PERF_SAMPLE_WEIGHT = 1U << 14,
PERF_SAMPLE_DATA_SRC = 1U << 15,
PERF_SAMPLE_IDENTIFIER = 1U << 16,
PERF_SAMPLE_TRANSACTION = 1U << 17,
PERF_SAMPLE_REGS_INTR = 1U << 18,
PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */
};
enum perf_event_type {
/*
* If perf_event_attr.sample_id_all is set then all event types will
* have the sample_type selected fields related to where/when
* (identity) an event took place (TID, TIME, ID, STREAM_ID, CPU,
* IDENTIFIER) described in PERF_RECORD_SAMPLE below, it will be stashed
* just after the perf_event_header and the fields already present for
* the existing fields, i.e. at the end of the payload. That way a newer
* perf.data file will be supported by older perf tools, with these new
* optional fields being ignored.
*
* struct sample_id {
* { u32 pid, tid; } && PERF_SAMPLE_TID
* { u64 time; } && PERF_SAMPLE_TIME
* { u64 id; } && PERF_SAMPLE_ID
* { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
* { u32 cpu, res; } && PERF_SAMPLE_CPU
* { u64 id; } && PERF_SAMPLE_IDENTIFIER
* } && perf_event_attr::sample_id_all
*
* Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID. The
* advantage of PERF_SAMPLE_IDENTIFIER is that its position is fixed
* relative to header.size.
*/
/*
* The MMAP events record the PROT_EXEC mappings so that we can
* correlate userspace IPs to code. They have the following structure:
*
* struct {
* struct perf_event_header header;
*
* u32 pid, tid;
* u64 addr;
* u64 len;
* u64 pgoff;
* char filename[];
* };
*/
PERF_RECORD_MMAP = 1,
/*
* struct {
* struct perf_event_header header;
* u64 id;
* u64 lost;
* struct sample_id sample_id;
* };
*/
PERF_RECORD_LOST = 2,
/*
* struct {
* struct perf_event_header header;
*
* u32 pid, tid;
* char comm[];
* struct sample_id sample_id;
* };
*/
PERF_RECORD_COMM = 3,
/*
* struct {
* struct perf_event_header header;
* u32 pid, ppid;
* u32 tid, ptid;
* u64 time;
* struct sample_id sample_id;
* };
*/
PERF_RECORD_EXIT = 4,
/*
* struct {
* struct perf_event_header header;
* u64 time;
* u64 id;
* u64 stream_id;
* struct sample_id sample_id;
* };
*/
PERF_RECORD_THROTTLE = 5,
PERF_RECORD_UNTHROTTLE = 6,
/*
* struct {
* struct perf_event_header header;
* u32 pid, ppid;
* u32 tid, ptid;
* u64 time;
* struct sample_id sample_id;
* };
*/
PERF_RECORD_FORK = 7,
/*
* struct {
* struct perf_event_header header;
* u32 pid, tid;
*
* struct read_format values;
* struct sample_id sample_id;
* };
*/
PERF_RECORD_READ = 8,
/*
* struct {
* struct perf_event_header header;
*
* #
* # Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID.
* # The advantage of PERF_SAMPLE_IDENTIFIER is that its position
* # is fixed relative to header.
* #
*
* { u64 id; } && PERF_SAMPLE_IDENTIFIER
* { u64 ip; } && PERF_SAMPLE_IP
* { u32 pid, tid; } && PERF_SAMPLE_TID
* { u64 time; } && PERF_SAMPLE_TIME
* { u64 addr; } && PERF_SAMPLE_ADDR
* { u64 id; } && PERF_SAMPLE_ID
* { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
* { u32 cpu, res; } && PERF_SAMPLE_CPU
* { u64 period; } && PERF_SAMPLE_PERIOD
*
* { struct read_format values; } && PERF_SAMPLE_READ
*
* { u64 nr,
* u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
*
* #
* # The RAW record below is opaque data wrt the ABI
* #
* # That is, the ABI doesn't make any promises wrt to
* # the stability of its content, it may vary depending
* # on event, hardware, kernel version and phase of
* # the moon.
* #
* # In other words, PERF_SAMPLE_RAW contents are not an ABI.
* #
*
* { u32 size;
* char data[size];}&& PERF_SAMPLE_RAW
*
* { u64 nr;
* { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
*
* { u64 abi; # enum perf_sample_regs_abi
* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
*
* { u64 size;
* char data[size];
* u64 dyn_size; } && PERF_SAMPLE_STACK_USER
*
* { u64 weight; } && PERF_SAMPLE_WEIGHT
* { u64 data_src; } && PERF_SAMPLE_DATA_SRC
* { u64 transaction; } && PERF_SAMPLE_TRANSACTION
* { u64 abi; # enum perf_sample_regs_abi
* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
* };
*/
PERF_RECORD_SAMPLE = 9,
/*
* The MMAP2 records are an augmented version of MMAP, they add
* maj, min, ino numbers to be used to uniquely identify each mapping
*
* struct {
* struct perf_event_header header;
*
* u32 pid, tid;
* u64 addr;
* u64 len;
* u64 pgoff;
* u32 maj;
* u32 min;
* u64 ino;
* u64 ino_generation;
* char filename[];
* struct sample_id sample_id;
* };
*/
PERF_RECORD_MMAP2 = 10,
PERF_RECORD_MAX, /* non-ABI */
};
#define PERF_MAX_STACK_DEPTH 127
enum perf_callchain_context {
PERF_CONTEXT_HV = (__uint64_t) -32,
PERF_CONTEXT_KERNEL = (__uint64_t) -128,
PERF_CONTEXT_USER = (__uint64_t) -512,
PERF_CONTEXT_GUEST = (__uint64_t) -2048,
PERF_CONTEXT_GUEST_KERNEL = (__uint64_t) -2176,
PERF_CONTEXT_GUEST_USER = (__uint64_t) -2560,
PERF_CONTEXT_MAX = (__uint64_t) -4095,
};
/*
* attr.type
*/
enum perf_type_id {
PERF_TYPE_HARDWARE = 0,
PERF_TYPE_SOFTWARE = 1,
PERF_TYPE_TRACEPOINT = 2,
PERF_TYPE_HW_CACHE = 3,
PERF_TYPE_RAW = 4,
PERF_TYPE_BREAKPOINT = 5,
PERF_TYPE_INTEL_CQM = 6,
PERF_TYPE_MAX, /* non-ABI */
};
/*
* Generalized performance event event_id types, used by the
* attr.event_id parameter of the sys_perf_event_open()
* syscall:
*/
enum perf_hw_id {
/*
* Common hardware events, generalized by the kernel:
*/
PERF_COUNT_HW_CPU_CYCLES = 0,
PERF_COUNT_HW_INSTRUCTIONS = 1,
PERF_COUNT_HW_CACHE_REFERENCES = 2,
PERF_COUNT_HW_CACHE_MISSES = 3,
PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
PERF_COUNT_HW_BRANCH_MISSES = 5,
PERF_COUNT_HW_BUS_CYCLES = 6,
PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
PERF_COUNT_HW_REF_CPU_CYCLES = 9,
PERF_COUNT_HW_MAX, /* non-ABI */
};
/* We can output a bunch of different versions of perf_event_attr. The oldest
* Linux perf I've run across expects version 3 and can't handle anything
* larger. Since we're not using anything from versions 1 or higher, we can sit
* at version 0 for now. */
#define PERF_ATTR_VER0
#ifdef PERF_ATTR_VER1
#define __PERF_ATTR_VER1 1
#endif
#ifdef PERF_ATTR_VER2
#define __PERF_ATTR_VER1 1
#define __PERF_ATTR_VER2 1
#endif
#ifdef PERF_ATTR_VER3
#define __PERF_ATTR_VER1 1
#define __PERF_ATTR_VER2 1
#define __PERF_ATTR_VER3 1
#endif
#ifdef PERF_ATTR_VER4
#define __PERF_ATTR_VER1 1
#define __PERF_ATTR_VER2 1
#define __PERF_ATTR_VER3 1
#define __PERF_ATTR_VER4 1
#endif
/*
* Hardware event_id to monitor via a performance monitoring event:
*/
struct perf_event_attr {
/*
* Major type: hardware/software/tracepoint/etc.
*/
uint32_t type;
/*
* Size of the attr structure, for fwd/bwd compat.
*/
uint32_t size;
/*
* Type specific configuration information.
*/
uint64_t config;
union {
uint64_t sample_period;
uint64_t sample_freq;
};
uint64_t sample_type;
uint64_t read_format;
uint64_t disabled : 1, /* off by default */
inherit : 1, /* children inherit it */
pinned : 1, /* must always be on PMU */
exclusive : 1, /* only group on PMU */
exclude_user : 1, /* don't count user */
exclude_kernel : 1, /* ditto kernel */
exclude_hv : 1, /* ditto hypervisor */
exclude_idle : 1, /* don't count when idle */
mmap : 1, /* include mmap data */
comm : 1, /* include comm data */
freq : 1, /* use freq, not period */
inherit_stat : 1, /* per task counts */
enable_on_exec : 1, /* next exec enables */
task : 1, /* trace fork/exit */
watermark : 1, /* wakeup_watermark */
/*
* precise_ip:
*
* 0 - SAMPLE_IP can have arbitrary skid
* 1 - SAMPLE_IP must have constant skid
* 2 - SAMPLE_IP requested to have 0 skid
* 3 - SAMPLE_IP must have 0 skid
*
* See also PERF_RECORD_MISC_EXACT_IP
*/
precise_ip : 2, /* skid constraint */
mmap_data : 1, /* non-exec mmap data */
sample_id_all : 1, /* sample_type all events */
exclude_host : 1, /* don't count in host */
exclude_guest : 1, /* don't count in guest */
exclude_callchain_kernel : 1, /* exclude kernel callchains */
exclude_callchain_user : 1, /* exclude user callchains */
mmap2 : 1, /* include mmap with inode data */
__reserved_1 : 40;
union {
uint32_t wakeup_events; /* wakeup every n events */
uint32_t wakeup_watermark; /* bytes before wakeup */
};
uint32_t bp_type;
union {
uint64_t bp_addr;
uint64_t config1; /* extension of config */
};
#ifdef __PERF_ATTR_VER1
union {
uint64_t bp_len;
uint64_t config2; /* extension of config1 */
};
# ifdef __PERF_ATTR_VER2
uint64_t branch_sample_type; /* enum perf_branch_sample_type */
# ifdef __PERF_ATTR_VER3
/*
* Defines set of user regs to dump on samples.
* See asm/perf_regs.h for details.
*/
uint64_t sample_regs_user;
/*
* Defines size of the user stack to dump on samples.
*/
uint32_t sample_stack_user;
# ifdef __PERF_ATTR_VER4
/* Align to u64. */
uint32_t __reserved_2;
/*
* Defines set of regs to dump for each sample
* state captured on:
* - precise = 0: PMU interrupt
* - precise > 0: sampled instruction
*
* See asm/perf_regs.h for details.
*/
uint64_t sample_regs_intr;
# endif /* __PERF_ATTR_VER4 */
# endif /* __PERF_ATTR_VER3 */
# endif /* __PERF_ATTR_VER2 */
#endif /* __PERF_ATTR_VER1 */
} __attribute__((packed));
#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
#define PERF_RECORD_MISC_KERNEL (1 << 0)
#define PERF_RECORD_MISC_USER (2 << 0)
#define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
#define PERF_RECORD_MISC_GUEST_USER (5 << 0)
#define PERF_RECORD_MISC_MMAP_DATA (1 << 13)
/*
* Indicates that the content of PERF_SAMPLE_IP points to
* the actual instruction that triggered the event. See also
* perf_event_attr::precise_ip.
*/
#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
/*
* Reserve the last bit to indicate some extended misc field
*/
#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
struct perf_event_header {
uint32_t type;
uint16_t misc;
uint16_t size;
} __attribute__((packed));
struct perf_file_section {
uint64_t offset; /* Offset from start of file */
uint64_t size; /* Size of the section */
} __attribute__((packed));
#define PERF_STRING_ALIGN 64
struct perf_header_string {
uint32_t len;
char string[0]; /* Zero terminated */
};
struct perf_header_string_list {
uint32_t nr;
struct perf_header_string strings[0]; /* Variable length records */
};
struct nr_cpus {
uint32_t nr_cpus_online;
uint32_t nr_cpus_available;
};
struct build_id_event {
struct perf_event_header header;
pid_t pid;
uint8_t build_id[24]; /* BUILD_ID_SIZE aligned u64 */
char filename[];
};
#define MAX_EVENT_NAME 64
struct perf_trace_event_type {
uint64_t event_id;
char name[MAX_EVENT_NAME];
};
struct perf_file_attr {
struct perf_event_attr attr;
struct perf_file_section ids;
};
/* "PERFILE2"
*/
static const uint64_t PERF_MAGIC2 = 0x32454c4946524550ULL;
struct perf_pipe_file_header {
uint64_t magic; /* PERFILE2 */
uint64_t size;
};
struct perf_header {
uint64_t magic; /* PERFILE2 */
uint64_t size; /* Size of the header */
uint64_t attr_size; /* size of an attribute in attrs */
struct perf_file_section attrs;
struct perf_file_section data;
struct perf_file_section event_types;
DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
} __attribute__((packed));
/* For type PERF_RECORD_MMAP
*/
struct perf_record_mmap {
struct perf_event_header header;
uint32_t pid;
uint32_t tid;
uint64_t addr;
uint64_t len;
uint64_t pgoff;
char filename[0];
} __attribute__((packed));
/* For type PERF_RECORD_COMM
*/
struct perf_record_comm {
struct perf_event_header header;
uint32_t pid;
uint32_t tid;
char comm[0];
} __attribute__((packed));
/* For type PERF_RECORD_SAMPLE
*
* Configured with: PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
* PERF_SAMPLE_ADDR | PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_CPU |
* PERF_SAMPLE_CALLCHAIN. */
struct perf_record_sample {
struct perf_event_header header;
uint64_t identifier;
uint64_t ip;
uint32_t pid, tid;
uint64_t time;
uint64_t addr;
uint32_t cpu, res;
uint64_t nr;
uint64_t ips[0];
} __attribute__((packed));