409 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef __PERF_RECORD_H3#define __PERF_RECORD_H4/*5 * The linux/stddef.h isn't need here, but is needed for __always_inline used6 * in files included from uapi/linux/perf_event.h such as7 * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h,8 * detected in at least musl libc, used in Alpine Linux. -acme9 */10#include <stdio.h>11#include <linux/stddef.h>12#include <perf/event.h>13#include <linux/types.h>14 15struct dso;16struct machine;17struct perf_event_attr;18struct perf_sample;19 20#ifdef __LP64__21/*22 * /usr/include/inttypes.h uses just 'lu' for PRIu64, but we end up defining23 * __u64 as long long unsigned int, and then -Werror=format= kicks in and24 * complains of the mismatched types, so use these two special extra PRI25 * macros to overcome that.26 */27#define PRI_lu64 "l" PRIu6428#define PRI_lx64 "l" PRIx6429#define PRI_ld64 "l" PRId6430#else31#define PRI_lu64 PRIu6432#define PRI_lx64 PRIx6433#define PRI_ld64 PRId6434#endif35 36#define PERF_SAMPLE_MASK \37 (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \38 PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR | \39 PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | \40 PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | \41 PERF_SAMPLE_IDENTIFIER)42 43/* perf sample has 16 bits size limit */44#define PERF_SAMPLE_MAX_SIZE (1 << 16)45 46struct ip_callchain {47 u64 nr;48 u64 ips[];49};50 51struct branch_stack;52 53enum {54 PERF_IP_FLAG_BRANCH = 1ULL << 0,55 PERF_IP_FLAG_CALL = 1ULL << 1,56 PERF_IP_FLAG_RETURN = 1ULL << 2,57 PERF_IP_FLAG_CONDITIONAL = 1ULL << 3,58 PERF_IP_FLAG_SYSCALLRET = 1ULL << 4,59 PERF_IP_FLAG_ASYNC = 1ULL << 5,60 PERF_IP_FLAG_INTERRUPT = 1ULL << 6,61 PERF_IP_FLAG_TX_ABORT = 1ULL << 7,62 PERF_IP_FLAG_TRACE_BEGIN = 1ULL << 8,63 PERF_IP_FLAG_TRACE_END = 1ULL << 9,64 PERF_IP_FLAG_IN_TX = 1ULL << 10,65 PERF_IP_FLAG_VMENTRY = 1ULL << 11,66 PERF_IP_FLAG_VMEXIT = 1ULL << 12,67 PERF_IP_FLAG_INTR_DISABLE = 1ULL << 13,68 PERF_IP_FLAG_INTR_TOGGLE = 1ULL << 14,69};70 71#define PERF_IP_FLAG_CHARS "bcrosyiABExghDt"72 73#define PERF_BRANCH_MASK (\74 PERF_IP_FLAG_BRANCH |\75 PERF_IP_FLAG_CALL |\76 PERF_IP_FLAG_RETURN |\77 PERF_IP_FLAG_CONDITIONAL |\78 PERF_IP_FLAG_SYSCALLRET |\79 PERF_IP_FLAG_ASYNC |\80 PERF_IP_FLAG_INTERRUPT |\81 PERF_IP_FLAG_TX_ABORT |\82 PERF_IP_FLAG_TRACE_BEGIN |\83 PERF_IP_FLAG_TRACE_END |\84 PERF_IP_FLAG_VMENTRY |\85 PERF_IP_FLAG_VMEXIT)86 87#define PERF_MEM_DATA_SRC_NONE \88 (PERF_MEM_S(OP, NA) |\89 PERF_MEM_S(LVL, NA) |\90 PERF_MEM_S(SNOOP, NA) |\91 PERF_MEM_S(LOCK, NA) |\92 PERF_MEM_S(TLB, NA) |\93 PERF_MEM_S(LVLNUM, NA))94 95/* Attribute type for custom synthesized events */96#define PERF_TYPE_SYNTH (INT_MAX + 1U)97 98/* Attribute config for custom synthesized events */99enum perf_synth_id {100 PERF_SYNTH_INTEL_PTWRITE,101 PERF_SYNTH_INTEL_MWAIT,102 PERF_SYNTH_INTEL_PWRE,103 PERF_SYNTH_INTEL_EXSTOP,104 PERF_SYNTH_INTEL_PWRX,105 PERF_SYNTH_INTEL_CBR,106 PERF_SYNTH_INTEL_PSB,107 PERF_SYNTH_INTEL_EVT,108 PERF_SYNTH_INTEL_IFLAG_CHG,109};110 111/*112 * Raw data formats for synthesized events. Note that 4 bytes of padding are113 * present to match the 'size' member of PERF_SAMPLE_RAW data which is always114 * 8-byte aligned. That means we must dereference raw_data with an offset of 4.115 * Refer perf_sample__synth_ptr() and perf_synth__raw_data(). It also means the116 * structure sizes are 4 bytes bigger than the raw_size, refer117 * perf_synth__raw_size().118 */119 120struct perf_synth_intel_ptwrite {121 u32 padding;122 union {123 struct {124 u32 ip : 1,125 reserved : 31;126 };127 u32 flags;128 };129 u64 payload;130};131 132struct perf_synth_intel_mwait {133 u32 padding;134 u32 reserved;135 union {136 struct {137 u64 hints : 8,138 reserved1 : 24,139 extensions : 2,140 reserved2 : 30;141 };142 u64 payload;143 };144};145 146struct perf_synth_intel_pwre {147 u32 padding;148 u32 reserved;149 union {150 struct {151 u64 reserved1 : 7,152 hw : 1,153 subcstate : 4,154 cstate : 4,155 reserved2 : 48;156 };157 u64 payload;158 };159};160 161struct perf_synth_intel_exstop {162 u32 padding;163 union {164 struct {165 u32 ip : 1,166 reserved : 31;167 };168 u32 flags;169 };170};171 172struct perf_synth_intel_pwrx {173 u32 padding;174 u32 reserved;175 union {176 struct {177 u64 deepest_cstate : 4,178 last_cstate : 4,179 wake_reason : 4,180 reserved1 : 52;181 };182 u64 payload;183 };184};185 186struct perf_synth_intel_cbr {187 u32 padding;188 union {189 struct {190 u32 cbr : 8,191 reserved1 : 8,192 max_nonturbo : 8,193 reserved2 : 8;194 };195 u32 flags;196 };197 u32 freq;198 u32 reserved3;199};200 201struct perf_synth_intel_psb {202 u32 padding;203 u32 reserved;204 u64 offset;205};206 207struct perf_synth_intel_evd {208 union {209 struct {210 u8 evd_type;211 u8 reserved[7];212 };213 u64 et;214 };215 u64 payload;216};217 218/* Intel PT Event Trace */219struct perf_synth_intel_evt {220 u32 padding;221 union {222 struct {223 u32 type : 5,224 reserved : 2,225 ip : 1,226 vector : 8,227 evd_cnt : 16;228 };229 u32 cfe;230 };231 struct perf_synth_intel_evd evd[0];232};233 234struct perf_synth_intel_iflag_chg {235 u32 padding;236 union {237 struct {238 u32 iflag : 1,239 via_branch : 1;240 };241 u32 flags;242 };243 u64 branch_ip; /* If via_branch */244};245 246static inline void *perf_synth__raw_data(void *p)247{248 return p + 4;249}250 251#define perf_synth__raw_size(d) (sizeof(d) - 4)252 253#define perf_sample__bad_synth_size(s, d) ((s)->raw_size < sizeof(d) - 4)254 255enum {256 PERF_STAT_ROUND_TYPE__INTERVAL = 0,257 PERF_STAT_ROUND_TYPE__FINAL = 1,258};259 260void perf_event__print_totals(void);261 262struct perf_cpu_map;263struct perf_record_stat_config;264struct perf_stat_config;265struct perf_tool;266 267void perf_event__read_stat_config(struct perf_stat_config *config,268 struct perf_record_stat_config *event);269 270int perf_event__process_comm(const struct perf_tool *tool,271 union perf_event *event,272 struct perf_sample *sample,273 struct machine *machine);274int perf_event__process_lost(const struct perf_tool *tool,275 union perf_event *event,276 struct perf_sample *sample,277 struct machine *machine);278int perf_event__process_lost_samples(const struct perf_tool *tool,279 union perf_event *event,280 struct perf_sample *sample,281 struct machine *machine);282int perf_event__process_aux(const struct perf_tool *tool,283 union perf_event *event,284 struct perf_sample *sample,285 struct machine *machine);286int perf_event__process_itrace_start(const struct perf_tool *tool,287 union perf_event *event,288 struct perf_sample *sample,289 struct machine *machine);290int perf_event__process_aux_output_hw_id(const struct perf_tool *tool,291 union perf_event *event,292 struct perf_sample *sample,293 struct machine *machine);294int perf_event__process_switch(const struct perf_tool *tool,295 union perf_event *event,296 struct perf_sample *sample,297 struct machine *machine);298int perf_event__process_namespaces(const struct perf_tool *tool,299 union perf_event *event,300 struct perf_sample *sample,301 struct machine *machine);302int perf_event__process_cgroup(const struct perf_tool *tool,303 union perf_event *event,304 struct perf_sample *sample,305 struct machine *machine);306int perf_event__process_mmap(const struct perf_tool *tool,307 union perf_event *event,308 struct perf_sample *sample,309 struct machine *machine);310int perf_event__process_mmap2(const struct perf_tool *tool,311 union perf_event *event,312 struct perf_sample *sample,313 struct machine *machine);314int perf_event__process_fork(const struct perf_tool *tool,315 union perf_event *event,316 struct perf_sample *sample,317 struct machine *machine);318int perf_event__process_exit(const struct perf_tool *tool,319 union perf_event *event,320 struct perf_sample *sample,321 struct machine *machine);322int perf_event__exit_del_thread(const struct perf_tool *tool,323 union perf_event *event,324 struct perf_sample *sample,325 struct machine *machine);326int perf_event__process_ksymbol(const struct perf_tool *tool,327 union perf_event *event,328 struct perf_sample *sample,329 struct machine *machine);330int perf_event__process_bpf(const struct perf_tool *tool,331 union perf_event *event,332 struct perf_sample *sample,333 struct machine *machine);334int perf_event__process_text_poke(const struct perf_tool *tool,335 union perf_event *event,336 struct perf_sample *sample,337 struct machine *machine);338int perf_event__process(const struct perf_tool *tool,339 union perf_event *event,340 struct perf_sample *sample,341 struct machine *machine);342 343bool is_bts_event(struct perf_event_attr *attr);344bool sample_addr_correlates_sym(struct perf_event_attr *attr);345 346const char *perf_event__name(unsigned int id);347 348size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp);349size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);350size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp);351size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);352size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);353size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);354size_t perf_event__fprintf_aux_output_hw_id(union perf_event *event, FILE *fp);355size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);356size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp);357size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp);358size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp);359size_t perf_event__fprintf_cgroup(union perf_event *event, FILE *fp);360size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp);361size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp);362size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *machine,FILE *fp);363size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FILE *fp);364 365int kallsyms__get_function_start(const char *kallsyms_filename,366 const char *symbol_name, u64 *addr);367int kallsyms__get_symbol_start(const char *kallsyms_filename,368 const char *symbol_name, u64 *addr);369 370void event_attr_init(struct perf_event_attr *attr);371 372int perf_event_paranoid(void);373bool perf_event_paranoid_check(int max_level);374 375extern int sysctl_perf_event_max_stack;376extern int sysctl_perf_event_max_contexts_per_stack;377extern unsigned int proc_map_timeout;378 379#define PAGE_SIZE_NAME_LEN 32380char *get_page_size_name(u64 size, char *str);381 382void arch_perf_parse_sample_weight(struct perf_sample *data, const __u64 *array, u64 type);383void arch_perf_synthesize_sample_weight(const struct perf_sample *data, __u64 *array, u64 type);384const char *arch_perf_header_entry(const char *se_header);385int arch_support_sort_key(const char *sort_key);386 387static inline bool perf_event_header__cpumode_is_guest(u8 cpumode)388{389 return cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||390 cpumode == PERF_RECORD_MISC_GUEST_USER;391}392 393static inline bool perf_event_header__misc_is_guest(u16 misc)394{395 return perf_event_header__cpumode_is_guest(misc & PERF_RECORD_MISC_CPUMODE_MASK);396}397 398static inline bool perf_event_header__is_guest(const struct perf_event_header *header)399{400 return perf_event_header__misc_is_guest(header->misc);401}402 403static inline bool perf_event__is_guest(const union perf_event *event)404{405 return perf_event_header__is_guest(&event->header);406}407 408#endif /* __PERF_RECORD_H */409