Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __PERF_RECORD_H
0003 #define __PERF_RECORD_H
0004 /*
0005  * The linux/stddef.h isn't need here, but is needed for __always_inline used
0006  * in files included from uapi/linux/perf_event.h such as
0007  * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h,
0008  * detected in at least musl libc, used in Alpine Linux. -acme
0009  */
0010 #include <stdio.h>
0011 #include <linux/stddef.h>
0012 #include <perf/event.h>
0013 #include <linux/types.h>
0014 
0015 #include "perf_regs.h"
0016 
0017 struct dso;
0018 struct machine;
0019 struct perf_event_attr;
0020 
0021 #ifdef __LP64__
0022 /*
0023  * /usr/include/inttypes.h uses just 'lu' for PRIu64, but we end up defining
0024  * __u64 as long long unsigned int, and then -Werror=format= kicks in and
0025  * complains of the mismatched types, so use these two special extra PRI
0026  * macros to overcome that.
0027  */
0028 #define PRI_lu64 "l" PRIu64
0029 #define PRI_lx64 "l" PRIx64
0030 #define PRI_ld64 "l" PRId64
0031 #else
0032 #define PRI_lu64 PRIu64
0033 #define PRI_lx64 PRIx64
0034 #define PRI_ld64 PRId64
0035 #endif
0036 
0037 #define PERF_SAMPLE_MASK                \
0038     (PERF_SAMPLE_IP | PERF_SAMPLE_TID |     \
0039      PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR |      \
0040     PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID |    \
0041      PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD |     \
0042      PERF_SAMPLE_IDENTIFIER)
0043 
0044 /* perf sample has 16 bits size limit */
0045 #define PERF_SAMPLE_MAX_SIZE (1 << 16)
0046 
0047 /* number of register is bound by the number of bits in regs_dump::mask (64) */
0048 #define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64))
0049 
0050 struct regs_dump {
0051     u64 abi;
0052     u64 mask;
0053     u64 *regs;
0054 
0055     /* Cached values/mask filled by first register access. */
0056     u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE];
0057     u64 cache_mask;
0058 };
0059 
0060 struct stack_dump {
0061     u16 offset;
0062     u64 size;
0063     char *data;
0064 };
0065 
0066 struct sample_read_value {
0067     u64 value;
0068     u64 id;   /* only if PERF_FORMAT_ID */
0069     u64 lost; /* only if PERF_FORMAT_LOST */
0070 };
0071 
0072 struct sample_read {
0073     u64 time_enabled;
0074     u64 time_running;
0075     union {
0076         struct {
0077             u64 nr;
0078             struct sample_read_value *values;
0079         } group;
0080         struct sample_read_value one;
0081     };
0082 };
0083 
0084 static inline size_t sample_read_value_size(u64 read_format)
0085 {
0086     /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
0087     if (read_format & PERF_FORMAT_LOST)
0088         return sizeof(struct sample_read_value);
0089     else
0090         return offsetof(struct sample_read_value, lost);
0091 }
0092 
0093 static inline struct sample_read_value *
0094 next_sample_read_value(struct sample_read_value *v, u64 read_format)
0095 {
0096     return (void *)v + sample_read_value_size(read_format);
0097 }
0098 
0099 #define sample_read_group__for_each(v, nr, rf)      \
0100     for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++)
0101 
0102 struct ip_callchain {
0103     u64 nr;
0104     u64 ips[];
0105 };
0106 
0107 struct branch_stack;
0108 
0109 enum {
0110     PERF_IP_FLAG_BRANCH     = 1ULL << 0,
0111     PERF_IP_FLAG_CALL       = 1ULL << 1,
0112     PERF_IP_FLAG_RETURN     = 1ULL << 2,
0113     PERF_IP_FLAG_CONDITIONAL    = 1ULL << 3,
0114     PERF_IP_FLAG_SYSCALLRET     = 1ULL << 4,
0115     PERF_IP_FLAG_ASYNC      = 1ULL << 5,
0116     PERF_IP_FLAG_INTERRUPT      = 1ULL << 6,
0117     PERF_IP_FLAG_TX_ABORT       = 1ULL << 7,
0118     PERF_IP_FLAG_TRACE_BEGIN    = 1ULL << 8,
0119     PERF_IP_FLAG_TRACE_END      = 1ULL << 9,
0120     PERF_IP_FLAG_IN_TX      = 1ULL << 10,
0121     PERF_IP_FLAG_VMENTRY        = 1ULL << 11,
0122     PERF_IP_FLAG_VMEXIT     = 1ULL << 12,
0123     PERF_IP_FLAG_INTR_DISABLE   = 1ULL << 13,
0124     PERF_IP_FLAG_INTR_TOGGLE    = 1ULL << 14,
0125 };
0126 
0127 #define PERF_IP_FLAG_CHARS "bcrosyiABExghDt"
0128 
0129 #define PERF_BRANCH_MASK        (\
0130     PERF_IP_FLAG_BRANCH     |\
0131     PERF_IP_FLAG_CALL       |\
0132     PERF_IP_FLAG_RETURN     |\
0133     PERF_IP_FLAG_CONDITIONAL    |\
0134     PERF_IP_FLAG_SYSCALLRET     |\
0135     PERF_IP_FLAG_ASYNC      |\
0136     PERF_IP_FLAG_INTERRUPT      |\
0137     PERF_IP_FLAG_TX_ABORT       |\
0138     PERF_IP_FLAG_TRACE_BEGIN    |\
0139     PERF_IP_FLAG_TRACE_END      |\
0140     PERF_IP_FLAG_VMENTRY        |\
0141     PERF_IP_FLAG_VMEXIT)
0142 
0143 #define MAX_INSN 16
0144 
0145 struct aux_sample {
0146     u64 size;
0147     void *data;
0148 };
0149 
0150 struct perf_sample {
0151     u64 ip;
0152     u32 pid, tid;
0153     u64 time;
0154     u64 addr;
0155     u64 id;
0156     u64 stream_id;
0157     u64 period;
0158     u64 weight;
0159     u64 transaction;
0160     u64 insn_cnt;
0161     u64 cyc_cnt;
0162     u32 cpu;
0163     u32 raw_size;
0164     u64 data_src;
0165     u64 phys_addr;
0166     u64 data_page_size;
0167     u64 code_page_size;
0168     u64 cgroup;
0169     u32 flags;
0170     u32 machine_pid;
0171     u32 vcpu;
0172     u16 insn_len;
0173     u8  cpumode;
0174     u16 misc;
0175     u16 ins_lat;
0176     u16 p_stage_cyc;
0177     bool no_hw_idx;     /* No hw_idx collected in branch_stack */
0178     char insn[MAX_INSN];
0179     void *raw_data;
0180     struct ip_callchain *callchain;
0181     struct branch_stack *branch_stack;
0182     struct regs_dump  user_regs;
0183     struct regs_dump  intr_regs;
0184     struct stack_dump user_stack;
0185     struct sample_read read;
0186     struct aux_sample aux_sample;
0187 };
0188 
0189 #define PERF_MEM_DATA_SRC_NONE \
0190     (PERF_MEM_S(OP, NA) |\
0191      PERF_MEM_S(LVL, NA) |\
0192      PERF_MEM_S(SNOOP, NA) |\
0193      PERF_MEM_S(LOCK, NA) |\
0194      PERF_MEM_S(TLB, NA))
0195 
0196 /* Attribute type for custom synthesized events */
0197 #define PERF_TYPE_SYNTH     (INT_MAX + 1U)
0198 
0199 /* Attribute config for custom synthesized events */
0200 enum perf_synth_id {
0201     PERF_SYNTH_INTEL_PTWRITE,
0202     PERF_SYNTH_INTEL_MWAIT,
0203     PERF_SYNTH_INTEL_PWRE,
0204     PERF_SYNTH_INTEL_EXSTOP,
0205     PERF_SYNTH_INTEL_PWRX,
0206     PERF_SYNTH_INTEL_CBR,
0207     PERF_SYNTH_INTEL_PSB,
0208     PERF_SYNTH_INTEL_EVT,
0209     PERF_SYNTH_INTEL_IFLAG_CHG,
0210 };
0211 
0212 /*
0213  * Raw data formats for synthesized events. Note that 4 bytes of padding are
0214  * present to match the 'size' member of PERF_SAMPLE_RAW data which is always
0215  * 8-byte aligned. That means we must dereference raw_data with an offset of 4.
0216  * Refer perf_sample__synth_ptr() and perf_synth__raw_data().  It also means the
0217  * structure sizes are 4 bytes bigger than the raw_size, refer
0218  * perf_synth__raw_size().
0219  */
0220 
0221 struct perf_synth_intel_ptwrite {
0222     u32 padding;
0223     union {
0224         struct {
0225             u32 ip      :  1,
0226                 reserved    : 31;
0227         };
0228         u32 flags;
0229     };
0230     u64 payload;
0231 };
0232 
0233 struct perf_synth_intel_mwait {
0234     u32 padding;
0235     u32 reserved;
0236     union {
0237         struct {
0238             u64 hints       :  8,
0239                 reserved1   : 24,
0240                 extensions  :  2,
0241                 reserved2   : 30;
0242         };
0243         u64 payload;
0244     };
0245 };
0246 
0247 struct perf_synth_intel_pwre {
0248     u32 padding;
0249     u32 reserved;
0250     union {
0251         struct {
0252             u64 reserved1   :  7,
0253                 hw      :  1,
0254                 subcstate   :  4,
0255                 cstate      :  4,
0256                 reserved2   : 48;
0257         };
0258         u64 payload;
0259     };
0260 };
0261 
0262 struct perf_synth_intel_exstop {
0263     u32 padding;
0264     union {
0265         struct {
0266             u32 ip      :  1,
0267                 reserved    : 31;
0268         };
0269         u32 flags;
0270     };
0271 };
0272 
0273 struct perf_synth_intel_pwrx {
0274     u32 padding;
0275     u32 reserved;
0276     union {
0277         struct {
0278             u64 deepest_cstate  :  4,
0279                 last_cstate :  4,
0280                 wake_reason :  4,
0281                 reserved1   : 52;
0282         };
0283         u64 payload;
0284     };
0285 };
0286 
0287 struct perf_synth_intel_cbr {
0288     u32 padding;
0289     union {
0290         struct {
0291             u32 cbr     :  8,
0292                 reserved1   :  8,
0293                 max_nonturbo    :  8,
0294                 reserved2   :  8;
0295         };
0296         u32 flags;
0297     };
0298     u32 freq;
0299     u32 reserved3;
0300 };
0301 
0302 struct perf_synth_intel_psb {
0303     u32 padding;
0304     u32 reserved;
0305     u64 offset;
0306 };
0307 
0308 struct perf_synth_intel_evd {
0309     union {
0310         struct {
0311             u8  evd_type;
0312             u8  reserved[7];
0313         };
0314         u64 et;
0315     };
0316     u64 payload;
0317 };
0318 
0319 /* Intel PT Event Trace */
0320 struct perf_synth_intel_evt {
0321     u32 padding;
0322     union {
0323         struct {
0324             u32 type        :  5,
0325                 reserved    :  2,
0326                 ip      :  1,
0327                 vector      :  8,
0328                 evd_cnt     : 16;
0329         };
0330         u32 cfe;
0331     };
0332     struct perf_synth_intel_evd evd[0];
0333 };
0334 
0335 struct perf_synth_intel_iflag_chg {
0336     u32 padding;
0337     union {
0338         struct {
0339             u32 iflag       :  1,
0340                 via_branch  :  1;
0341         };
0342         u32 flags;
0343     };
0344     u64 branch_ip; /* If via_branch */
0345 };
0346 
0347 /*
0348  * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get
0349  * 8-byte alignment.
0350  */
0351 static inline void *perf_sample__synth_ptr(struct perf_sample *sample)
0352 {
0353     return sample->raw_data - 4;
0354 }
0355 
0356 static inline void *perf_synth__raw_data(void *p)
0357 {
0358     return p + 4;
0359 }
0360 
0361 #define perf_synth__raw_size(d) (sizeof(d) - 4)
0362 
0363 #define perf_sample__bad_synth_size(s, d) ((s)->raw_size < sizeof(d) - 4)
0364 
0365 enum {
0366     PERF_STAT_ROUND_TYPE__INTERVAL  = 0,
0367     PERF_STAT_ROUND_TYPE__FINAL = 1,
0368 };
0369 
0370 void perf_event__print_totals(void);
0371 
0372 struct perf_cpu_map;
0373 struct perf_record_stat_config;
0374 struct perf_stat_config;
0375 struct perf_tool;
0376 
0377 void perf_event__read_stat_config(struct perf_stat_config *config,
0378                   struct perf_record_stat_config *event);
0379 
0380 int perf_event__process_comm(struct perf_tool *tool,
0381                  union perf_event *event,
0382                  struct perf_sample *sample,
0383                  struct machine *machine);
0384 int perf_event__process_lost(struct perf_tool *tool,
0385                  union perf_event *event,
0386                  struct perf_sample *sample,
0387                  struct machine *machine);
0388 int perf_event__process_lost_samples(struct perf_tool *tool,
0389                      union perf_event *event,
0390                      struct perf_sample *sample,
0391                      struct machine *machine);
0392 int perf_event__process_aux(struct perf_tool *tool,
0393                 union perf_event *event,
0394                 struct perf_sample *sample,
0395                 struct machine *machine);
0396 int perf_event__process_itrace_start(struct perf_tool *tool,
0397                      union perf_event *event,
0398                      struct perf_sample *sample,
0399                      struct machine *machine);
0400 int perf_event__process_aux_output_hw_id(struct perf_tool *tool,
0401                      union perf_event *event,
0402                      struct perf_sample *sample,
0403                      struct machine *machine);
0404 int perf_event__process_switch(struct perf_tool *tool,
0405                    union perf_event *event,
0406                    struct perf_sample *sample,
0407                    struct machine *machine);
0408 int perf_event__process_namespaces(struct perf_tool *tool,
0409                    union perf_event *event,
0410                    struct perf_sample *sample,
0411                    struct machine *machine);
0412 int perf_event__process_cgroup(struct perf_tool *tool,
0413                    union perf_event *event,
0414                    struct perf_sample *sample,
0415                    struct machine *machine);
0416 int perf_event__process_mmap(struct perf_tool *tool,
0417                  union perf_event *event,
0418                  struct perf_sample *sample,
0419                  struct machine *machine);
0420 int perf_event__process_mmap2(struct perf_tool *tool,
0421                  union perf_event *event,
0422                  struct perf_sample *sample,
0423                  struct machine *machine);
0424 int perf_event__process_fork(struct perf_tool *tool,
0425                  union perf_event *event,
0426                  struct perf_sample *sample,
0427                  struct machine *machine);
0428 int perf_event__process_exit(struct perf_tool *tool,
0429                  union perf_event *event,
0430                  struct perf_sample *sample,
0431                  struct machine *machine);
0432 int perf_event__process_ksymbol(struct perf_tool *tool,
0433                 union perf_event *event,
0434                 struct perf_sample *sample,
0435                 struct machine *machine);
0436 int perf_event__process_bpf(struct perf_tool *tool,
0437                 union perf_event *event,
0438                 struct perf_sample *sample,
0439                 struct machine *machine);
0440 int perf_event__process_text_poke(struct perf_tool *tool,
0441                   union perf_event *event,
0442                   struct perf_sample *sample,
0443                   struct machine *machine);
0444 int perf_event__process(struct perf_tool *tool,
0445             union perf_event *event,
0446             struct perf_sample *sample,
0447             struct machine *machine);
0448 
0449 struct addr_location;
0450 
0451 int machine__resolve(struct machine *machine, struct addr_location *al,
0452              struct perf_sample *sample);
0453 
0454 void addr_location__put(struct addr_location *al);
0455 
0456 struct thread;
0457 
0458 bool is_bts_event(struct perf_event_attr *attr);
0459 bool sample_addr_correlates_sym(struct perf_event_attr *attr);
0460 void thread__resolve(struct thread *thread, struct addr_location *al,
0461              struct perf_sample *sample);
0462 
0463 const char *perf_event__name(unsigned int id);
0464 
0465 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp);
0466 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
0467 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp);
0468 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);
0469 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);
0470 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);
0471 size_t perf_event__fprintf_aux_output_hw_id(union perf_event *event, FILE *fp);
0472 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);
0473 size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp);
0474 size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp);
0475 size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp);
0476 size_t perf_event__fprintf_cgroup(union perf_event *event, FILE *fp);
0477 size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp);
0478 size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp);
0479 size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *machine,FILE *fp);
0480 size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FILE *fp);
0481 
0482 int kallsyms__get_function_start(const char *kallsyms_filename,
0483                  const char *symbol_name, u64 *addr);
0484 
0485 void event_attr_init(struct perf_event_attr *attr);
0486 
0487 int perf_event_paranoid(void);
0488 bool perf_event_paranoid_check(int max_level);
0489 
0490 extern int sysctl_perf_event_max_stack;
0491 extern int sysctl_perf_event_max_contexts_per_stack;
0492 extern unsigned int proc_map_timeout;
0493 
0494 #define PAGE_SIZE_NAME_LEN  32
0495 char *get_page_size_name(u64 size, char *str);
0496 
0497 void arch_perf_parse_sample_weight(struct perf_sample *data, const __u64 *array, u64 type);
0498 void arch_perf_synthesize_sample_weight(const struct perf_sample *data, __u64 *array, u64 type);
0499 const char *arch_perf_header_entry(const char *se_header);
0500 int arch_support_sort_key(const char *sort_key);
0501 
0502 static inline bool perf_event_header__cpumode_is_guest(u8 cpumode)
0503 {
0504     return cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
0505            cpumode == PERF_RECORD_MISC_GUEST_USER;
0506 }
0507 
0508 static inline bool perf_event_header__misc_is_guest(u16 misc)
0509 {
0510     return perf_event_header__cpumode_is_guest(misc & PERF_RECORD_MISC_CPUMODE_MASK);
0511 }
0512 
0513 static inline bool perf_event_header__is_guest(const struct perf_event_header *header)
0514 {
0515     return perf_event_header__misc_is_guest(header->misc);
0516 }
0517 
0518 static inline bool perf_event__is_guest(const union perf_event *event)
0519 {
0520     return perf_event_header__is_guest(&event->header);
0521 }
0522 
0523 #endif /* __PERF_RECORD_H */