1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __PERF_RECORD_H 3 #define __PERF_RECORD_H 4 /* 5 * The linux/stddef.h isn't need here, but is needed for __always_inline used 6 * in files included from uapi/linux/perf_event.h such as 7 * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h, 8 * detected in at least musl libc, used in Alpine Linux. -acme 9 */ 10 #include <stdio.h> 11 #include <linux/stddef.h> 12 #include <perf/event.h> 13 #include <linux/types.h> 14 15 struct dso; 16 struct machine; 17 struct perf_event_attr; 18 19 #ifdef __LP64__ 20 /* 21 * /usr/include/inttypes.h uses just 'lu' for PRIu64, but we end up defining 22 * __u64 as long long unsigned int, and then -Werror=format= kicks in and 23 * complains of the mismatched types, so use these two special extra PRI 24 * macros to overcome that. 25 */ 26 #define PRI_lu64 "l" PRIu64 27 #define PRI_lx64 "l" PRIx64 28 #define PRI_ld64 "l" PRId64 29 #else 30 #define PRI_lu64 PRIu64 31 #define PRI_lx64 PRIx64 32 #define PRI_ld64 PRId64 33 #endif 34 35 #define PERF_SAMPLE_MASK \ 36 (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \ 37 PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR | \ 38 PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | \ 39 PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | \ 40 PERF_SAMPLE_IDENTIFIER) 41 42 /* perf sample has 16 bits size limit */ 43 #define PERF_SAMPLE_MAX_SIZE (1 << 16) 44 45 /* number of register is bound by the number of bits in regs_dump::mask (64) */ 46 #define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64)) 47 48 struct regs_dump { 49 u64 abi; 50 u64 mask; 51 u64 *regs; 52 53 /* Cached values/mask filled by first register access. */ 54 u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE]; 55 u64 cache_mask; 56 }; 57 58 struct stack_dump { 59 u16 offset; 60 u64 size; 61 char *data; 62 }; 63 64 struct sample_read_value { 65 u64 value; 66 u64 id; /* only if PERF_FORMAT_ID */ 67 u64 lost; /* only if PERF_FORMAT_LOST */ 68 }; 69 70 struct sample_read { 71 u64 time_enabled; 72 u64 time_running; 73 union { 74 struct { 75 u64 nr; 76 struct sample_read_value *values; 77 } group; 78 struct sample_read_value one; 79 }; 80 }; 81 82 static inline size_t sample_read_value_size(u64 read_format) 83 { 84 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ 85 if (read_format & PERF_FORMAT_LOST) 86 return sizeof(struct sample_read_value); 87 else 88 return offsetof(struct sample_read_value, lost); 89 } 90 91 static inline struct sample_read_value * 92 next_sample_read_value(struct sample_read_value *v, u64 read_format) 93 { 94 return (void *)v + sample_read_value_size(read_format); 95 } 96 97 #define sample_read_group__for_each(v, nr, rf) \ 98 for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++) 99 100 struct ip_callchain { 101 u64 nr; 102 u64 ips[]; 103 }; 104 105 struct branch_stack; 106 107 enum { 108 PERF_IP_FLAG_BRANCH = 1ULL << 0, 109 PERF_IP_FLAG_CALL = 1ULL << 1, 110 PERF_IP_FLAG_RETURN = 1ULL << 2, 111 PERF_IP_FLAG_CONDITIONAL = 1ULL << 3, 112 PERF_IP_FLAG_SYSCALLRET = 1ULL << 4, 113 PERF_IP_FLAG_ASYNC = 1ULL << 5, 114 PERF_IP_FLAG_INTERRUPT = 1ULL << 6, 115 PERF_IP_FLAG_TX_ABORT = 1ULL << 7, 116 PERF_IP_FLAG_TRACE_BEGIN = 1ULL << 8, 117 PERF_IP_FLAG_TRACE_END = 1ULL << 9, 118 PERF_IP_FLAG_IN_TX = 1ULL << 10, 119 PERF_IP_FLAG_VMENTRY = 1ULL << 11, 120 PERF_IP_FLAG_VMEXIT = 1ULL << 12, 121 PERF_IP_FLAG_INTR_DISABLE = 1ULL << 13, 122 PERF_IP_FLAG_INTR_TOGGLE = 1ULL << 14, 123 }; 124 125 #define PERF_IP_FLAG_CHARS "bcrosyiABExghDt" 126 127 #define PERF_BRANCH_MASK (\ 128 PERF_IP_FLAG_BRANCH |\ 129 PERF_IP_FLAG_CALL |\ 130 PERF_IP_FLAG_RETURN |\ 131 PERF_IP_FLAG_CONDITIONAL |\ 132 PERF_IP_FLAG_SYSCALLRET |\ 133 PERF_IP_FLAG_ASYNC |\ 134 PERF_IP_FLAG_INTERRUPT |\ 135 PERF_IP_FLAG_TX_ABORT |\ 136 PERF_IP_FLAG_TRACE_BEGIN |\ 137 PERF_IP_FLAG_TRACE_END |\ 138 PERF_IP_FLAG_VMENTRY |\ 139 PERF_IP_FLAG_VMEXIT) 140 141 #define MAX_INSN 16 142 143 struct aux_sample { 144 u64 size; 145 void *data; 146 }; 147 148 struct perf_sample { 149 u64 ip; 150 u32 pid, tid; 151 u64 time; 152 u64 addr; 153 u64 id; 154 u64 stream_id; 155 u64 period; 156 u64 weight; 157 u64 transaction; 158 u64 insn_cnt; 159 u64 cyc_cnt; 160 u32 cpu; 161 u32 raw_size; 162 u64 data_src; 163 u64 phys_addr; 164 u64 data_page_size; 165 u64 code_page_size; 166 u64 cgroup; 167 u32 flags; 168 u32 machine_pid; 169 u32 vcpu; 170 u16 insn_len; 171 u8 cpumode; 172 u16 misc; 173 u16 ins_lat; 174 u16 p_stage_cyc; 175 bool no_hw_idx; /* No hw_idx collected in branch_stack */ 176 char insn[MAX_INSN]; 177 void *raw_data; 178 struct ip_callchain *callchain; 179 struct branch_stack *branch_stack; 180 struct regs_dump user_regs; 181 struct regs_dump intr_regs; 182 struct stack_dump user_stack; 183 struct sample_read read; 184 struct aux_sample aux_sample; 185 }; 186 187 #define PERF_MEM_DATA_SRC_NONE \ 188 (PERF_MEM_S(OP, NA) |\ 189 PERF_MEM_S(LVL, NA) |\ 190 PERF_MEM_S(SNOOP, NA) |\ 191 PERF_MEM_S(LOCK, NA) |\ 192 PERF_MEM_S(TLB, NA)) 193 194 /* Attribute type for custom synthesized events */ 195 #define PERF_TYPE_SYNTH (INT_MAX + 1U) 196 197 /* Attribute config for custom synthesized events */ 198 enum perf_synth_id { 199 PERF_SYNTH_INTEL_PTWRITE, 200 PERF_SYNTH_INTEL_MWAIT, 201 PERF_SYNTH_INTEL_PWRE, 202 PERF_SYNTH_INTEL_EXSTOP, 203 PERF_SYNTH_INTEL_PWRX, 204 PERF_SYNTH_INTEL_CBR, 205 PERF_SYNTH_INTEL_PSB, 206 PERF_SYNTH_INTEL_EVT, 207 PERF_SYNTH_INTEL_IFLAG_CHG, 208 }; 209 210 /* 211 * Raw data formats for synthesized events. Note that 4 bytes of padding are 212 * present to match the 'size' member of PERF_SAMPLE_RAW data which is always 213 * 8-byte aligned. That means we must dereference raw_data with an offset of 4. 214 * Refer perf_sample__synth_ptr() and perf_synth__raw_data(). It also means the 215 * structure sizes are 4 bytes bigger than the raw_size, refer 216 * perf_synth__raw_size(). 217 */ 218 219 struct perf_synth_intel_ptwrite { 220 u32 padding; 221 union { 222 struct { 223 u32 ip : 1, 224 reserved : 31; 225 }; 226 u32 flags; 227 }; 228 u64 payload; 229 }; 230 231 struct perf_synth_intel_mwait { 232 u32 padding; 233 u32 reserved; 234 union { 235 struct { 236 u64 hints : 8, 237 reserved1 : 24, 238 extensions : 2, 239 reserved2 : 30; 240 }; 241 u64 payload; 242 }; 243 }; 244 245 struct perf_synth_intel_pwre { 246 u32 padding; 247 u32 reserved; 248 union { 249 struct { 250 u64 reserved1 : 7, 251 hw : 1, 252 subcstate : 4, 253 cstate : 4, 254 reserved2 : 48; 255 }; 256 u64 payload; 257 }; 258 }; 259 260 struct perf_synth_intel_exstop { 261 u32 padding; 262 union { 263 struct { 264 u32 ip : 1, 265 reserved : 31; 266 }; 267 u32 flags; 268 }; 269 }; 270 271 struct perf_synth_intel_pwrx { 272 u32 padding; 273 u32 reserved; 274 union { 275 struct { 276 u64 deepest_cstate : 4, 277 last_cstate : 4, 278 wake_reason : 4, 279 reserved1 : 52; 280 }; 281 u64 payload; 282 }; 283 }; 284 285 struct perf_synth_intel_cbr { 286 u32 padding; 287 union { 288 struct { 289 u32 cbr : 8, 290 reserved1 : 8, 291 max_nonturbo : 8, 292 reserved2 : 8; 293 }; 294 u32 flags; 295 }; 296 u32 freq; 297 u32 reserved3; 298 }; 299 300 struct perf_synth_intel_psb { 301 u32 padding; 302 u32 reserved; 303 u64 offset; 304 }; 305 306 struct perf_synth_intel_evd { 307 union { 308 struct { 309 u8 evd_type; 310 u8 reserved[7]; 311 }; 312 u64 et; 313 }; 314 u64 payload; 315 }; 316 317 /* Intel PT Event Trace */ 318 struct perf_synth_intel_evt { 319 u32 padding; 320 union { 321 struct { 322 u32 type : 5, 323 reserved : 2, 324 ip : 1, 325 vector : 8, 326 evd_cnt : 16; 327 }; 328 u32 cfe; 329 }; 330 struct perf_synth_intel_evd evd[0]; 331 }; 332 333 struct perf_synth_intel_iflag_chg { 334 u32 padding; 335 union { 336 struct { 337 u32 iflag : 1, 338 via_branch : 1; 339 }; 340 u32 flags; 341 }; 342 u64 branch_ip; /* If via_branch */ 343 }; 344 345 /* 346 * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get 347 * 8-byte alignment. 348 */ 349 static inline void *perf_sample__synth_ptr(struct perf_sample *sample) 350 { 351 return sample->raw_data - 4; 352 } 353 354 static inline void *perf_synth__raw_data(void *p) 355 { 356 return p + 4; 357 } 358 359 #define perf_synth__raw_size(d) (sizeof(d) - 4) 360 361 #define perf_sample__bad_synth_size(s, d) ((s)->raw_size < sizeof(d) - 4) 362 363 enum { 364 PERF_STAT_ROUND_TYPE__INTERVAL = 0, 365 PERF_STAT_ROUND_TYPE__FINAL = 1, 366 }; 367 368 void perf_event__print_totals(void); 369 370 struct perf_cpu_map; 371 struct perf_record_stat_config; 372 struct perf_stat_config; 373 struct perf_tool; 374 375 void perf_event__read_stat_config(struct perf_stat_config *config, 376 struct perf_record_stat_config *event); 377 378 int perf_event__process_comm(struct perf_tool *tool, 379 union perf_event *event, 380 struct perf_sample *sample, 381 struct machine *machine); 382 int perf_event__process_lost(struct perf_tool *tool, 383 union perf_event *event, 384 struct perf_sample *sample, 385 struct machine *machine); 386 int perf_event__process_lost_samples(struct perf_tool *tool, 387 union perf_event *event, 388 struct perf_sample *sample, 389 struct machine *machine); 390 int perf_event__process_aux(struct perf_tool *tool, 391 union perf_event *event, 392 struct perf_sample *sample, 393 struct machine *machine); 394 int perf_event__process_itrace_start(struct perf_tool *tool, 395 union perf_event *event, 396 struct perf_sample *sample, 397 struct machine *machine); 398 int perf_event__process_aux_output_hw_id(struct perf_tool *tool, 399 union perf_event *event, 400 struct perf_sample *sample, 401 struct machine *machine); 402 int perf_event__process_switch(struct perf_tool *tool, 403 union perf_event *event, 404 struct perf_sample *sample, 405 struct machine *machine); 406 int perf_event__process_namespaces(struct perf_tool *tool, 407 union perf_event *event, 408 struct perf_sample *sample, 409 struct machine *machine); 410 int perf_event__process_cgroup(struct perf_tool *tool, 411 union perf_event *event, 412 struct perf_sample *sample, 413 struct machine *machine); 414 int perf_event__process_mmap(struct perf_tool *tool, 415 union perf_event *event, 416 struct perf_sample *sample, 417 struct machine *machine); 418 int perf_event__process_mmap2(struct perf_tool *tool, 419 union perf_event *event, 420 struct perf_sample *sample, 421 struct machine *machine); 422 int perf_event__process_fork(struct perf_tool *tool, 423 union perf_event *event, 424 struct perf_sample *sample, 425 struct machine *machine); 426 int perf_event__process_exit(struct perf_tool *tool, 427 union perf_event *event, 428 struct perf_sample *sample, 429 struct machine *machine); 430 int perf_event__process_ksymbol(struct perf_tool *tool, 431 union perf_event *event, 432 struct perf_sample *sample, 433 struct machine *machine); 434 int perf_event__process_bpf(struct perf_tool *tool, 435 union perf_event *event, 436 struct perf_sample *sample, 437 struct machine *machine); 438 int perf_event__process_text_poke(struct perf_tool *tool, 439 union perf_event *event, 440 struct perf_sample *sample, 441 struct machine *machine); 442 int perf_event__process(struct perf_tool *tool, 443 union perf_event *event, 444 struct perf_sample *sample, 445 struct machine *machine); 446 447 struct addr_location; 448 449 int machine__resolve(struct machine *machine, struct addr_location *al, 450 struct perf_sample *sample); 451 452 void addr_location__put(struct addr_location *al); 453 454 struct thread; 455 456 bool is_bts_event(struct perf_event_attr *attr); 457 bool sample_addr_correlates_sym(struct perf_event_attr *attr); 458 void thread__resolve(struct thread *thread, struct addr_location *al, 459 struct perf_sample *sample); 460 461 const char *perf_event__name(unsigned int id); 462 463 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); 464 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); 465 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); 466 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp); 467 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp); 468 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp); 469 size_t perf_event__fprintf_aux_output_hw_id(union perf_event *event, FILE *fp); 470 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp); 471 size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp); 472 size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp); 473 size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp); 474 size_t perf_event__fprintf_cgroup(union perf_event *event, FILE *fp); 475 size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp); 476 size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp); 477 size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *machine,FILE *fp); 478 size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FILE *fp); 479 480 int kallsyms__get_function_start(const char *kallsyms_filename, 481 const char *symbol_name, u64 *addr); 482 483 void event_attr_init(struct perf_event_attr *attr); 484 485 int perf_event_paranoid(void); 486 bool perf_event_paranoid_check(int max_level); 487 488 extern int sysctl_perf_event_max_stack; 489 extern int sysctl_perf_event_max_contexts_per_stack; 490 extern unsigned int proc_map_timeout; 491 492 #define PAGE_SIZE_NAME_LEN 32 493 char *get_page_size_name(u64 size, char *str); 494 495 void arch_perf_parse_sample_weight(struct perf_sample *data, const __u64 *array, u64 type); 496 void arch_perf_synthesize_sample_weight(const struct perf_sample *data, __u64 *array, u64 type); 497 const char *arch_perf_header_entry(const char *se_header); 498 int arch_support_sort_key(const char *sort_key); 499 500 static inline bool perf_event_header__cpumode_is_guest(u8 cpumode) 501 { 502 return cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 503 cpumode == PERF_RECORD_MISC_GUEST_USER; 504 } 505 506 static inline bool perf_event_header__misc_is_guest(u16 misc) 507 { 508 return perf_event_header__cpumode_is_guest(misc & PERF_RECORD_MISC_CPUMODE_MASK); 509 } 510 511 static inline bool perf_event_header__is_guest(const struct perf_event_header *header) 512 { 513 return perf_event_header__misc_is_guest(header->misc); 514 } 515 516 static inline bool perf_event__is_guest(const union perf_event *event) 517 { 518 return perf_event_header__is_guest(&event->header); 519 } 520 521 #endif /* __PERF_RECORD_H */ 522