Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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