perf_event_open(2) System Calls Manual perf_event_open(2) perf_event_open - (libc -lc) #include /* PERF_* */ #include /* HW_* */ #include /* SYS_* */ #include int syscall(SYS_perf_event_open, struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags); : glibc perf_event_open() syscall(2). perf_event_open() (read(2) mmap(2) prctl(2) fcntl(2) ). perf_event_open() . . : ioctl(2) prctl(2). . : . . read(2). mmap(2). pid cpu : pid == 0 cpu == -1 / . pid == 0 cpu >= 0 / . pid > 0 cpu == -1 / . pid > 0 cpu >= 0 / . pid == -1 cpu >= 0 / . CAP_PERFMON ( 5.8) CAP_SYS_ADMIN 1 /proc/sys/kernel/perf_event_paranoid. pid == -1 cpu == -1 . pid CAP_PERFMON ( 5.9) ptrace PTRACE_MODE_READ_REALCREDS ptrace(2). group_fd . . group_fd = -1. perf_event_open() group_fd . ( group_fd = -1 .) : . -- ( ) -- . flags OR : PERF_FLAG_FD_CLOEXEC ( 3.14) (close-on-exec) execve(2). fcntl(2) perf_event_open() fcntl(2) fork(2) execve(2). PERF_FLAG_FD_NO_GROUP group_fd PERF_FLAG_FD_OUTPUT. PERF_FLAG_FD_OUTPUT ( 2.6.35) mmap group_fd. PERF_FLAG_PID_CGROUP ( 2.6.39) . ( ). (cgroup). cgroup cgroupfs. cgroup test /dev/cgroup/test ( cgroupfs /dev/cgroup) pid. cgroup . perf_event_attr . struct perf_event_attr { __u32 type; /* */ __u32 size; /* */ __u64 config; /* */ union { __u64 sample_period; /* */ __u64 sample_freq; /* */ }; __u64 sample_type; /* */ __u64 read_format; /* */ __u64 disabled : 1, /* */ inherit : 1, /* */ pinned : 1, /* (PMU) */ exclusive : 1, /* PMU */ exclude_user : 1, /* */ exclude_kernel : 1, /* */ exclude_hv : 1, /* */ exclude_idle : 1, /* */ mmap : 1, /* mmap */ comm : 1, /* comm */ freq : 1, /* */ inherit_stat : 1, /* */ enable_on_exec : 1, /* */ task : 1, /* / */ watermark : 1, /* */ precise_ip : 2, /* */ mmap_data : 1, /* mmap */ sample_id_all : 1, /* */ exclude_host : 1, /* */ exclude_guest : 1, /* */ exclude_callchain_kernel : 1, /* */ exclude_callchain_user : 1, /* */ mmap2 : 1, /* mmap inode */ comm_exec : 1, /* comm */ use_clockid : 1, /* clockid */ context_switch : 1, /* */ write_backward : 1, /* */ namespaces : 1, /* */ ksymbol : 1, /* ksymbol */ bpf_event : 1, /* bpf */ aux_output : 1, /* AUX */ cgroup : 1, /* cgroup */ text_poke : 1, /* */ build_id : 1, /* mmap2 */ inherit_thread : 1, /* CLONE_THREAD */ remove_on_exec : 1, /* */ sigtrap : 1, /* SIGTRAP */ __reserved_1 : 26; union { __u32 wakeup_events; /* n */ __u32 wakeup_watermark; /* */ }; __u32 bp_type; /* */ union { __u64 bp_addr; /* */ __u64 kprobe_func; /* perf_kprobe */ __u64 uprobe_path; /* perf_uprobe */ __u64 config1; /* config */ }; union { __u64 bp_len; /* */ __u64 kprobe_addr; /* kprobe_func == NULL */ __u64 probe_offset; /* perf_[k,u]probe */ __u64 config2; /* config1 */ }; __u64 branch_sample_type; /* */ __u64 sample_regs_user; /* */ __u32 sample_stack_user; /* */ __s32 clockid; /* */ __u64 sample_regs_intr; /* */ __u32 aux_watermark; /* aux */ __u16 sample_max_stack; /* */ __u16 __reserved_2; /* u64 */ __u32 aux_sample_size; /* aux */ __u32 __reserved_3; /* u64 */ __u64 sig_data; /* sigtrap */ }; perf_event_attr : type . : PERF_TYPE_HARDWARE "" . config . PERF_TYPE_SOFTWARE ( ). PERF_TYPE_TRACEPOINT . PERF_TYPE_HW_CACHE . config. PERF_TYPE_RAW "" config. PERF_TYPE_BREAKPOINT ( 2.6.33) . / . (PMU) 2.6.38 perf_event_open() PMU . type PMU . sysfs: PMU /sys/bus/event_source/devices. type type. /sys/bus/event_source/devices/cpu/type PMU 4. kprobe uprobe ( 4.17) PMU kprobe/uprobe perf_event_open. kprobe/uprobe . kprobe_func uprobe_path kprobe_addr probe_offset . size perf_event_attr . sizeof(struct perf_event_attr) . PERF_ATTR_SIZE_VER0 64 . PERF_ATTR_SIZE_VER1 72 2.6.33. PERF_ATTR_SIZE_VER2 80 3.4. PERF_ATTR_SIZE_VER3 96 sample_regs_user sample_stack_user 3.7. PERF_ATTR_SIZE_VER4 104 sample_regs_intr 3.19. PERF_ATTR_SIZE_VER5 112 aux_watermark 4.1. config type. config1 config2 64 . . config type . config type. type PERF_TYPE_HARDWARE . . config : PERF_COUNT_HW_CPU_CYCLES . . PERF_COUNT_HW_INSTRUCTIONS . . PERF_COUNT_HW_CACHE_REFERENCES . . . PERF_COUNT_HW_CACHE_MISSES . PERF_COUNT_HW_CACHE_REFERENCES . PERF_COUNT_HW_BRANCH_INSTRUCTIONS . 2.6.35 AMD. PERF_COUNT_HW_BRANCH_MISSES . PERF_COUNT_HW_BUS_CYCLES . PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ( 3.0) . PERF_COUNT_HW_STALLED_CYCLES_BACKEND ( 3.0) . PERF_COUNT_HW_REF_CPU_CYCLES ( 3.3) . type PERF_TYPE_SOFTWARE . config : PERF_COUNT_SW_CPU_CLOCK . PERF_COUNT_SW_TASK_CLOCK . PERF_COUNT_SW_PAGE_FAULTS . PERF_COUNT_SW_CONTEXT_SWITCHES . 2.6.34 . PERF_COUNT_SW_CPU_MIGRATIONS . PERF_COUNT_SW_PAGE_FAULTS_MIN . / . PERF_COUNT_SW_PAGE_FAULTS_MAJ . / . PERF_COUNT_SW_ALIGNMENT_FAULTS ( 2.6.33) . . ( x86). PERF_COUNT_SW_EMULATION_FAULTS ( 2.6.33) . . . PERF_COUNT_SW_DUMMY ( 3.12) . mmap comm . . PERF_COUNT_SW_BPF_OUTPUT ( 4.4) BPF. BPF bpf_perf_event_output. PERF_COUNT_SW_CGROUP_SWITCHES ( 5.13) (cgroup) . . type PERF_TYPE_TRACEPOINT . config debugfs tracing/events/*/*/id ftrace . type PERF_TYPE_HW_CACHE . config : config = (perf_hw_cache_id) | (perf_hw_cache_op_id << 8) | (perf_hw_cache_op_result_id << 16); perf_hw_cache_id : PERF_COUNT_HW_CACHE_L1D 1 PERF_COUNT_HW_CACHE_L1I 1 PERF_COUNT_HW_CACHE_LL PERF_COUNT_HW_CACHE_DTLB (Data TLB) PERF_COUNT_HW_CACHE_ITLB (Instruction TLB) PERF_COUNT_HW_CACHE_BPU PERF_COUNT_HW_CACHE_NODE ( 3.1) perf_hw_cache_op_id : PERF_COUNT_HW_CACHE_OP_READ PERF_COUNT_HW_CACHE_OP_WRITE PERF_COUNT_HW_CACHE_OP_PREFETCH perf_hw_cache_op_result_id : PERF_COUNT_HW_CACHE_RESULT_ACCESS PERF_COUNT_HW_CACHE_RESULT_MISS type PERF_TYPE_RAW config "" . "". ( Intel 3B BIOS AMD). libpfm4 perf_event_open() . type PERF_TYPE_BREAKPOINT config . . type kprobe uprobe retprobe ( 0 config /sys/bus/event_source/devices/[k,u]probe/format/retprobe) kretprobe/uretprobe. kprobe_func uprobe_path kprobe_addr probe_offset . kprobe_func uprobe_path kprobe_addr probe_offset kprobe/uprobe PMU kprobe uprobe. kprobe: kprobe_func probe_offset kprobe_addr kprobe_func NULL. uprobe: uprobe_path probe_offset. sample_period sample_freq " " N N sample_period. sample_period 0. mmap . sample_type . sample_freq . freq. . . sample_type . mmap(2). MMAP enum perf_event_sample_format. PERF_SAMPLE_IP . PERF_SAMPLE_TID . PERF_SAMPLE_TIME . PERF_SAMPLE_ADDR . PERF_SAMPLE_READ . PERF_SAMPLE_CALLCHAIN ( ). PERF_SAMPLE_ID . PERF_SAMPLE_CPU . PERF_SAMPLE_PERIOD . PERF_SAMPLE_STREAM_ID . PERF_SAMPLE_ID . PERF_FORMAT_ID. PERF_SAMPLE_RAW . . PERF_SAMPLE_BRANCH_STACK ( 3.4) ( Intel Last Branch Record). . branch_sample_type . PERF_SAMPLE_REGS_USER ( 3.7) ( ). PERF_SAMPLE_STACK_USER ( 3.7) . PERF_SAMPLE_WEIGHT ( 3.10) . . PERF_SAMPLE_DATA_SRC ( 3.10) : . . PERF_SAMPLE_IDENTIFIER ( 3.12) SAMPLE_ID ( ) ( ). sample_type . SAMPLE_ID ( ). PERF_SAMPLE_IDENTIFIER SAMPLE_ID SAMPLE_ID . PERF_SAMPLE_TRANSACTION ( 3.13) ( Intel TSX). precise_ip 0 . perf_event ( ). PERF_SAMPLE_REGS_INTR ( 3.19) sample_regs_intr. PERF_SAMPLE_REGS_USER . ( PEBS Intel x86) precise_ip . PERF_SAMPLE_PHYS_ADDR ( 4.13) PERF_SAMPLE_ADDR. PERF_SAMPLE_CGROUP ( 5.7) cgroup (perf_event) . id PERF_RECORD_CGROUP. PERF_SAMPLE_DATA_PAGE_SIZE ( 5.11) PERF_SAMPLE_ADDR. PERF_SAMPLE_CODE_PAGE_SIZE ( 5.11) ip PERF_SAMPLE_IP. PERF_SAMPLE_WEIGHT_STRUCT ( 5.12) PERF_SAMPLE_WEIGHT (struct). PERF_SAMPLE_WEIGHT . . union perf_sample_weight { u64 full; /* PERF_SAMPLE_WEIGHT */ struct { /* PERF_SAMPLE_WEIGHT_STRUCT */ u32 var1_dw; u16 var2_w; u16 var3_w; }; }; read_format read(2) perf_event_open(). PERF_FORMAT_TOTAL_TIME_ENABLED time_enabled 64 . (PMU) . PERF_FORMAT_TOTAL_TIME_RUNNING time_running 64 . (PMU) . PERF_FORMAT_ID 64 . PERF_FORMAT_GROUP . PERF_FORMAT_LOST ( 6.0) 64 . sample_period sample_freq. disabled disabled . ioctl(2) prctl(2) enable_on_exec. disabled 1 disabled 0. disabled 0 . inherit inherit . ( ). (Inherit) read_format PERF_FORMAT_GROUP. cpu == -1 mmap . pinned pinned . . ( ) '' ( read(2) 0) . exclusive exclusive . (PMU) . exclusive . ( NMI ). exclude_user . exclude_kernel . exclude_hv (hypervisor). (PMUs) ( POWER). . exclude_idle . . mmap mmap PERF_RECORD_MMAP mmap(2) PROT_EXEC . ( ) . comm comm execve(2) prctl(PR_SET_NAME) /proc/self/comm. comm_exec ( 3.16) PERF_RECORD_MISC_COMM_EXEC execve(2) . freq sample_frequency sample_period . inherit_stat . inherit . enable_on_exec execve(2). task / . watermark wakeup_watermark. wakeup_events. precise_ip ( 2.6.35) (skid). . . : 0 SAMPLE_IP . 1 SAMPLE_IP . 2 SAMPLE_IP 0. 3 SAMPLE_IP 0. PERF_RECORD_MISC_EXACT_IP. mmap_data ( 2.6.36) mmap. PERF_RECORD_MMAP mmap(2) PROT_EXEC ( SysV ). sample_id_all ( 2.6.38) TID TIME ID STREAM_ID CPU PERF_RECORD_SAMPLE sample_type . PERF_SAMPLE_IDENTIFIER ID . id . : struct sample_id { { u32 pid, tid; } /* if PERF_SAMPLE_TID set */ { u64 time; } /* if PERF_SAMPLE_TIME set */ { u64 id; } /* if PERF_SAMPLE_ID set */ { u64 stream_id;} /* if PERF_SAMPLE_STREAM_ID set */ { u32 cpu, res; } /* if PERF_SAMPLE_CPU set */ { u64 id; } /* if PERF_SAMPLE_IDENTIFIER set */ }; exclude_host ( 3.2) ( KVM_RUN ioctl(2)) . . x86 . exclude_guest ( 3.2) ( KVM_RUN ioctl(2)) . . x86 . exclude_callchain_kernel ( 3.7) . exclude_callchain_user ( 3.7) . mmap2 ( 3.16) mmap . mmap . comm_exec ( 3.16) . comm PERF_RECORD_MISC_COMM_EXEC misc comm execve(2). . use_clockid ( 4.1) clockid. (perf) . context_switch ( 4.3) PERF_RECORD_SWITCH . PERF_RECORD_SWITCH_CPU_WIDE CPU-wide. (tracepoint) . perf_event_paranoid . write_backward ( 4.6) (ring buffer) . . namespaces ( 4.11) PERF_RECORD_NAMESPACES . (inode). ksymbol ( 5.0) PERF_RECORD_KSYMBOL . eBPF. bpf_event ( 5.0) PERF_RECORD_BPF_EVENT eBPF . aux_output ( 5.4) ( AUX) AUX . cgroup ( 5.7) PERF_RECORD_CGROUP () (cgroup) . text_poke ( 5.8) PERF_RECORD_TEXT_POKE ( ). build_id ( 5.12) PERF_RECORD_MMAP2 (build-id) (inode). inherit_thread ( 5.13) . ( CLONE_THREAD) . remove_on_exec ( 5.13) execve(2). sigtrap ( 5.13) SIGTRAP . wakeup_events wakeup_watermark (union) (wakeup_events) (wakeup_watermark) . watermark. wakeup_events PERF_RECORD_SAMPLE . PERF_RECORD watermark wakeup_watermark 1. 3.0 wakeup_events 0 0 1. bp_type ( 2.6.33) . : HW_BREAKPOINT_EMPTY . HW_BREAKPOINT_R . HW_BREAKPOINT_W . HW_BREAKPOINT_RW . HW_BREAKPOINT_X . (OR) HW_BREAKPOINT_R HW_BREAKPOINT_W HW_BREAKPOINT_X . bp_addr ( 2.6.33) . . config1 ( 2.6.39) config1 config . OFFCORE_EVENTS Nehalem/Westmere/SandyBridge 3.3 . bp_len ( 2.6.33) bp_len type PERF_TYPE_BREAKPOINT. HW_BREAKPOINT_LEN_1 HW_BREAKPOINT_LEN_2 HW_BREAKPOINT_LEN_4 HW_BREAKPOINT_LEN_8. sizeof(long). config2 ( 2.6.39) config2 config1. branch_sample_type ( 3.4) PERF_SAMPLE_BRANCH_STACK . . . . PERF_SAMPLE_BRANCH_USER . PERF_SAMPLE_BRANCH_KERNEL . PERF_SAMPLE_BRANCH_HV (hypervisor). PERF_SAMPLE_BRANCH_PLM_ALL OR . . PERF_SAMPLE_BRANCH_ANY . PERF_SAMPLE_BRANCH_ANY_CALL ( ). PERF_SAMPLE_BRANCH_IND_CALL . PERF_SAMPLE_BRANCH_CALL ( 4.4) . PERF_SAMPLE_BRANCH_ANY_RETURN . PERF_SAMPLE_BRANCH_IND_JUMP ( 4.2) . PERF_SAMPLE_BRANCH_COND ( 3.16) . PERF_SAMPLE_BRANCH_ABORT_TX ( 3.11) . PERF_SAMPLE_BRANCH_IN_TX ( 3.11) . PERF_SAMPLE_BRANCH_NO_TX ( 3.11) . PERF_SAMPLE_BRANCH_CALL_STACK ( 4.1) . Intel x86 Haswell . sample_regs_user ( 3.7) . arch/ARCH/include/uapi/asm/perf_regs.h. sample_stack_user ( 3.7) PERF_SAMPLE_STACK_USER. clockid ( 4.1) use_clockid . linux/time.h CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW CLOCK_REALTIME CLOCK_BOOTTIME CLOCK_TAI . aux_watermark ( 4.1) PERF_RECORD_AUX. sample_max_stack ( 4.8) sample_type PERF_SAMPLE_CALLCHAIN . aux_sample_size ( 5.5) PERF_SAMPLE_AUX AUX. . sig_data ( 5.13) ( si_perf siginfo_t) . perf_event_open() . read_format attr . ENOSPC. : o PERF_FORMAT_GROUP : struct read_format { u64 nr; /* */ u64 time_enabled; /* PERF_FORMAT_TOTAL_TIME_ENABLED */ u64 time_running; /* PERF_FORMAT_TOTAL_TIME_RUNNING */ struct { u64 value; /* */ u64 id; /* PERF_FORMAT_ID */ u64 lost; /* PERF_FORMAT_LOST */ } values[nr]; }; o PERF_FORMAT_GROUP: struct read_format { u64 value; /* */ u64 time_enabled; /* PERF_FORMAT_TOTAL_TIME_ENABLED */ u64 time_running; /* PERF_FORMAT_TOTAL_TIME_RUNNING */ u64 id; /* PERF_FORMAT_ID */ u64 lost; /* PERF_FORMAT_LOST */ }; : nr . PERF_FORMAT_GROUP. time_enabled time_running . . (Multiplexing) PMU . time_enabled time_running . value 64 . id PERF_FORMAT_ID read_format. lost PERF_FORMAT_LOST read_format. MMAP perf_event_open() ( mmap PROT_EXEC) . mmap(2). mmap 1+2^n (struct perf_event_mmap_page) . 2.6.39 mmap . mmap : struct perf_event_mmap_page { __u32 version; /* */ __u32 compat_version; /* */ __u32 lock; /* (seqlock) */ __u32 index; /* */ __s64 offset; /* */ __u64 time_enabled; /* */ __u64 time_running; /* */ union { __u64 capabilities; struct { __u64 cap_usr_time / cap_usr_rdpmc / cap_bit0 : 1, cap_bit0_is_deprecated : 1, cap_user_rdpmc : 1, cap_user_time : 1, cap_user_time_zero : 1, }; }; __u16 pmc_width; __u16 time_shift; __u32 time_mult; __u64 time_offset; __u64 __reserved[120]; /* 1 */ __u64 data_head; /* */ __u64 data_tail; /* */ __u64 data_offset; /* */ __u64 data_size; /* */ __u64 aux_head; __u64 aux_tail; __u64 aux_offset; __u64 aux_size; } perf_event_mmap_page : . _ . (seqlock) . index . offset rdpmc offset rdpmc . time_enabled . time_running . cap_usr_time / cap_usr_rdpmc / cap_bit0 ( 3.4) cap_usr_time cap_usr_rdpmc 3.4 3.11. cap_usr_time cap_usr_rdpmc . 3.12 cap_bit0 cap_user_time cap_user_rdpmc . cap_bit0_is_deprecated ( 3.12) cap_user_time cap_user_rdpmc . cap_usr_time cap_usr_rdpmc . cap_user_rdpmc ( 3.12) ( "rdpmc" x86) : u32 seq, time_mult, time_shift, idx, width; u64 count, enabled, running; u64 cyc, time_offset; do { seq = pc->lock; barrier(); enabled = pc->time_enabled; running = pc->time_running; if (pc->cap_usr_time && enabled != running) { cyc = rdtsc(); time_offset = pc->time_offset; time_mult = pc->time_mult; time_shift = pc->time_shift; } idx = pc->index; count = pc->offset; if (pc->cap_usr_rdpmc && idx) { width = pc->pmc_width; count += rdpmc(idx - 1); } barrier(); } while (pc->lock != seq); cap_user_time ( 3.12) (TSC x86). cap_user_time_zero ( 3.12) time_zero . pmc_width cap_usr_rdpmc rdpmc . : pmc <<= 64 - pmc_width; pmc >>= 64 - pmc_width; // count += pmc; time_shift time_mult time_offset cap_usr_time time_enabled () rdtsc . u64 quot, rem; u64 delta; quot = cyc >> time_shift; rem = cyc & (((u64)1 << time_shift) - 1); delta = time_offset + quot * time_mult + ((rem * time_mult) >> time_shift); time_offset time_mult time_shift cyc seqcount . (delta) (enabled) (running) ( idx) : enabled += delta; if (idx) running += delta; quot = count / running; rem = count % running; count = quot * enabled + (rem * enabled) / running; time_zero ( 3.12) cap_usr_time_zero ( TSC x86) time_zero time_mult time_shift: time = timestamp - time_zero; quot = time / time_mult; rem = time % time_mult; cyc = (quot << time_shift) + (rem << time_shift) / time_mult; : quot = cyc >> time_shift; rem = cyc & (((u64)1 << time_shift) - 1); timestamp = time_zero + quot * time_mult + ((rem * time_mult) >> time_shift); data_head . . mmap . SMP data_head rmb(). data_tail PROT_WRITE data_tail . . data_offset ( 4.1) mmap . data_size ( 4.1) mmap. aux_head aux_tail aux_offset aux_size ( 4.1) AUX mmap(2) ( ). Intel . AUX aux_offset data_offset+data_size aux_size . . mmap AUX. AUX RLIMIT_MEMLOCK ( setrlimit(2)) perf_event_mlock_kb. AUX . AUX . . aux_head aux_tail data_head data_tail . 2^n . perf_event_attr.sample_id_all sample_type / () (TID, TIME, ID, CPU, STREAM_ID) PERF_RECORD_SAMPLE perf_event_header . perf.data perf . mmap : struct perf_event_header { __u32 type; __u16 misc; __u16 size; }; perf_event_header . . size . misc misc . PERF_RECORD_MISC_CPUMODE_MASK ( ): PERF_RECORD_MISC_CPUMODE_UNKNOWN . PERF_RECORD_MISC_KERNEL . PERF_RECORD_MISC_USER . PERF_RECORD_MISC_HYPERVISOR . PERF_RECORD_MISC_GUEST_KERNEL ( 2.6.35) . PERF_RECORD_MISC_GUEST_USER ( Linux 2.6.35) . : PERF_RECORD_MISC_MMAP_DATA ( Linux 3.10) (mapping) . PERF_RECORD_MISC_COMM_EXEC ( Linux 3.16) PERF_RECORD_COMM Linux 3.16 execve(2). PERF_RECORD_MISC_SWITCH_OUT ( Linux 4.3) PERF_RECORD_SWITCH PERF_RECORD_SWITCH_CPU_WIDE ( ). : PERF_RECORD_MISC_EXACT_IP PERF_SAMPLE_IP . perf_event_attr.precise_ip. PERF_RECORD_MISC_SWITCH_OUT_PREEMPT ( Linux 4.17) PERF_RECORD_SWITCH PERF_RECORD_SWITCH_CPU_WIDE (preemption). PERF_RECORD_MISC_MMAP_BUILD_ID ( Linux 5.12) PERF_SAMPLE_MMAP2 (build-ID) (inode). PERF_RECORD_MISC_EXT_RESERVED ( Linux 2.6.35) ( ). PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT . perf /proc/pid/maps mmap. type type . ( ) type . PERF_RECORD_MMAP MMAP PROT_EXEC IP . : struct { struct perf_event_header header; u32 pid, tid; u64 addr; u64 len; u64 pgoff; char filename[]; }; pid . tid . addr . len . pgoff . filename . PERF_RECORD_LOST . struct { struct perf_event_header header; u64 id; u64 lost; struct sample_id sample_id; }; id . lost . PERF_RECORD_COMM . struct { struct perf_event_header header; u32 pid; u32 tid; char comm[]; struct sample_id sample_id; }; pid . tid . comm . PERF_RECORD_EXIT . struct { struct perf_event_header header; u32 pid, ppid; u32 tid, ptid; u64 time; struct sample_id sample_id; }; PERF_RECORD_THROTTLE PERF_RECORD_UNTHROTTLE / (throttle/unthrottle). struct { struct perf_event_header header; u64 time; u64 id; u64 stream_id; struct sample_id sample_id; }; PERF_RECORD_FORK (fork). struct { struct perf_event_header header; u32 pid, ppid; u32 tid, ptid; u64 time; struct sample_id sample_id; }; PERF_RECORD_READ . struct { struct perf_event_header header; u32 pid, tid; struct read_format values; struct sample_id sample_id; }; PERF_RECORD_SAMPLE . struct { struct perf_event_header header; u64 sample_id; /* if PERF_SAMPLE_IDENTIFIER */ u64 ip; /* if PERF_SAMPLE_IP */ u32 pid, tid; /* if PERF_SAMPLE_TID */ u64 time; /* if PERF_SAMPLE_TIME */ u64 addr; /* if PERF_SAMPLE_ADDR */ u64 id; /* if PERF_SAMPLE_ID */ u64 stream_id; /* if PERF_SAMPLE_STREAM_ID */ u32 cpu, res; /* if PERF_SAMPLE_CPU */ u64 period; /* if PERF_SAMPLE_PERIOD */ struct read_format v; /* if PERF_SAMPLE_READ */ u64 nr; /* if PERF_SAMPLE_CALLCHAIN */ u64 ips[nr]; /* if PERF_SAMPLE_CALLCHAIN */ u32 size; /* if PERF_SAMPLE_RAW */ char data[size]; /* if PERF_SAMPLE_RAW */ u64 bnr; /* if PERF_SAMPLE_BRANCH_STACK */ struct perf_branch_entry lbr[bnr]; /* if PERF_SAMPLE_BRANCH_STACK */ u64 abi; /* if PERF_SAMPLE_REGS_USER */ u64 regs[weight(mask)]; /* if PERF_SAMPLE_REGS_USER */ u64 size; /* if PERF_SAMPLE_STACK_USER */ char data[size]; /* if PERF_SAMPLE_STACK_USER */ u64 dyn_size; /* if PERF_SAMPLE_STACK_USER && size != 0 */ union perf_sample_weight weight; /* if PERF_SAMPLE_WEIGHT */ /* || PERF_SAMPLE_WEIGHT_STRUCT */ u64 data_src; /* if PERF_SAMPLE_DATA_SRC */ u64 transaction; /* if PERF_SAMPLE_TRANSACTION */ u64 abi; /* if PERF_SAMPLE_REGS_INTR */ u64 regs[weight(mask)]; /* if PERF_SAMPLE_REGS_INTR */ u64 phys_addr; /* if PERF_SAMPLE_PHYS_ADDR */ u64 cgroup; /* if PERF_SAMPLE_CGROUP */ u64 data_page_size; /* if PERF_SAMPLE_DATA_PAGE_SIZE */ u64 code_page_size; /* if PERF_SAMPLE_CODE_PAGE_SIZE */ u64 size; /* if PERF_SAMPLE_AUX */ char data[size]; /* if PERF_SAMPLE_AUX */ }; sample_id PERF_SAMPLE_IDENTIFIER 64 . id PERF_SAMPLE_ID . ip PERF_SAMPLE_IP 64 . pid tid PERF_SAMPLE_TID 32 32 . time PERF_SAMPLE_TIME 64 . local_clock() jiffies . addr PERF_SAMPLE_ADDR 64 . 0. id PERF_SAMPLE_ID 64 . . PERF_FORMAT_ID. stream_id PERF_SAMPLE_STREAM_ID 64 . PERF_SAMPLE_ID . PERF_FORMAT_ID. res PERF_SAMPLE_CPU 32 32 ( ). period PERF_SAMPLE_PERIOD 64 . v PERF_SAMPLE_READ read_format . read_format perf_event_open(). nr ips[nr] PERF_SAMPLE_CALLCHAIN 64- (instruction pointers) 64- . . size data[size] PERF_SAMPLE_RAW 32- 8- size. 64-. (RAW) (ABI). ABI (Kernel). bnr lbr[bnr] PERF_SAMPLE_BRANCH_STACK 64- bnr perf_branch_entry : from ( ). to . mispred . predicted . in_tx ( 3.11) (transactional memory transaction). abort ( 3.11) . cycles ( 4.3) (cycles) (branch stack). . mispred predicted cycles 0. branch_sample_type. abi regs[weight(mask)] PERF_SAMPLE_REGS_USER (CPU) . abi PERF_SAMPLE_REGS_ABI_NONE PERF_SAMPLE_REGS_ABI_32 PERF_SAMPLE_REGS_ABI_64. regs CPU sample_regs_user (attr). sample_regs_user. size data[size] dyn_size PERF_SAMPLE_STACK_USER . (backtraces). size sample_stack_user . data ( ). dyn_size ( size). dyn_size size 0. weight PERF_SAMPLE_WEIGHT PERF_SAMPLE_WEIGHT_STRUCT 64- . (profiles). data_src PERF_SAMPLE_DATA_SRC 64- : mem_op (opcode) (bitwise combination) : PERF_MEM_OP_NA PERF_MEM_OP_LOAD (Load) PERF_MEM_OP_STORE (Store) PERF_MEM_OP_PFETCH PERF_MEM_OP_EXEC mem_lvl PERF_MEM_LVL_SHIFT: PERF_MEM_LVL_NA PERF_MEM_LVL_HIT (Hit) PERF_MEM_LVL_MISS (Miss) PERF_MEM_LVL_L1 1 PERF_MEM_LVL_LFB (Line fill buffer) PERF_MEM_LVL_L2 2 PERF_MEM_LVL_L3 3 PERF_MEM_LVL_LOC_RAM DRAM PERF_MEM_LVL_REM_RAM1 DRAM PERF_MEM_LVL_REM_RAM2 DRAM PERF_MEM_LVL_REM_CCE1 PERF_MEM_LVL_REM_CCE2 PERF_MEM_LVL_IO / PERF_MEM_LVL_UNC mem_snoop (Snoop mode) PERF_MEM_SNOOP_SHIFT: PERF_MEM_SNOOP_NA PERF_MEM_SNOOP_NONE PERF_MEM_SNOOP_HIT PERF_MEM_SNOOP_MISS PERF_MEM_SNOOP_HITM mem_lock PERF_MEM_LOCK_SHIFT: PERF_MEM_LOCK_NA PERF_MEM_LOCK_LOCKED mem_dtlb TLB PERF_MEM_TLB_SHIFT: PERF_MEM_TLB_NA PERF_MEM_TLB_HIT (Hit) PERF_MEM_TLB_MISS (Miss) PERF_MEM_TLB_L1 TLB 1 PERF_MEM_TLB_L2 TLB 2 PERF_MEM_TLB_WK PERF_MEM_TLB_OS transaction PERF_SAMPLE_TRANSACTION 64 . : PERF_TXN_ELISION ( ). PERF_TXN_TRANSACTION . PERF_TXN_SYNC ( ). PERF_TXN_ASYNC ( ). PERF_TXN_RETRY ( ). PERF_TXN_CONFLICT . PERF_TXN_CAPACITY_WRITE . PERF_TXN_CAPACITY_READ . 32 PERF_TXN_ABORT_SHIFT PERF_TXN_ABORT_MASK. abi regs[weight(mask)] PERF_SAMPLE_REGS_INTR . abi PERF_SAMPLE_REGS_ABI_NONE PERF_SAMPLE_REGS_ABI_32 PERF_SAMPLE_REGS_ABI_64. regs sample_regs_intr. sample_regs_intr. phys_addr PERF_SAMPLE_PHYS_ADDR 64 . cgroup PERF_SAMPLE_CGROUP cgroup 64 ( perf_event ). cgroup PERF_RECORD_CGROUP. data_page_size PERF_SAMPLE_DATA_PAGE_SIZE 64 data. code_page_size PERF_SAMPLE_CODE_PAGE_SIZE 64 ip. size data[size] PERF_SAMPLE_AUX aux . PERF_RECORD_MMAP2 mmap(2) . PERF_RECORD_MMAP . PERF_RECORD_MISC_MMAP_BUILD_ID . struct { struct perf_event_header header; u32 pid; u32 tid; u64 addr; u64 len; u64 pgoff; union { struct { u32 maj; u32 min; u64 ino; u64 ino_generation; }; struct { /* if PERF_RECORD_MISC_MMAP_BUILD_ID */ u8 build_id_size; u8 __reserved_1; u16 __reserved_2; u8 build_id[20]; }; }; u32 prot; u32 flags; char filename[]; struct sample_id sample_id; }; pid . tid . addr . len . pgoff . maj . min . ino (inode). ino_generation (inode). build_id_size build_id ( 20). build_id . prot . flags (flags). filename . PERF_RECORD_AUX ( 4.1) AUX . struct { struct perf_event_header header; u64 aux_offset; u64 aux_size; u64 flags; struct sample_id sample_id; }; aux_offset mmap AUX . aux_size . flags AUX. PERF_AUX_FLAG_TRUNCATED . PERF_AUX_FLAG_OVERWRITE . PERF_RECORD_ITRACE_START ( 4.1) AUX . struct { struct perf_event_header header; u32 pid; u32 tid; }; pid (thread) . tid (thread ID) . PERF_RECORD_LOST_SAMPLES ( 4.2) ( Intel PEBS) . struct { struct perf_event_header header; u64 lost; struct sample_id sample_id; }; lost . PERF_RECORD_SWITCH ( 4.3) . PERF_RECORD_MISC_SWITCH_OUT misc . struct { struct perf_event_header header; struct sample_id sample_id; }; PERF_RECORD_SWITCH_CPU_WIDE ( 4.3) PERF_RECORD_SWITCH (CPU-wide) . PERF_RECORD_MISC_SWITCH_OUT misc . struct { struct perf_event_header header; u32 next_prev_pid; u32 next_prev_tid; struct sample_id sample_id; }; next_prev_pid ( ) ( ) . next_prev_tid (thread ID) ( ) ( ) . PERF_RECORD_NAMESPACES ( 4.11) . struct { struct perf_event_header header; u32 pid; u32 tid; u64 nr_namespaces; struct { u64 dev, inode } [nr_namespaces]; struct sample_id sample_id; }; pid tid nr_namespace dev inode : NET_NS_INDEX=0 UTS_NS_INDEX=1 UTS IPC_NS_INDEX=2 IPC PID_NS_INDEX=3 PID USER_NS_INDEX=4 MNT_NS_INDEX=5 CGROUP_NS_INDEX=6 Cgroup PERF_RECORD_KSYMBOL ( 5.0) / . struct { struct perf_event_header header; u64 addr; u32 len; u16 ksym_type; u16 flags; char name[]; struct sample_id sample_id; }; addr . len . ksym_type . : PERF_RECORD_KSYMBOL_TYPE_BPF BPF. flags PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER . PERF_RECORD_BPF_EVENT ( 5.0) BPF . struct { struct perf_event_header header; u16 type; u16 flags; u32 id; u8 tag[BPF_TAG_SIZE]; struct sample_id sample_id; }; type : PERF_BPF_EVENT_PROG_LOAD BPF PERF_BPF_EVENT_PROG_UNLOAD BPF id BPF. BPF. BPF_TAG_SIZE 8. PERF_RECORD_CGROUP ( 5.7) cgroup . struct { struct perf_event_header header; u64 id; char path[]; struct sample_id sample_id; }; id cgroup. name_to_handle_at(2) cgroup ( ). cgroup . PERF_RECORD_TEXT_POKE ( 5.8) . . struct { struct perf_event_header header; u64 addr; u16 old_len; u16 new_len; u8 bytes[]; struct sample_id sample_id; }; addr old_len new_len bytes . . poll(2) select(2) epoll(7). / F_SETOWN F_SETSIG fcntl(2). ( sample_period ). . wakeup_events wakeup_watermark mmap. POLL_IN. ioctl PERF_EVENT_IOC_REFRESH. ioctl . POLL_IN 0 POLL_HUP . 0 . 3.18 POLL_HUP . rdpmc 3.4 x86 rdpmc . rdpmc . cap_usr_rdpmc mmap . rdpmc ( perf ) rdpmc . 4.0 rdpmc . 2 /sys/devices/cpu/rdpmc. ioctl perf_event ioctl perf_event_open(): PERF_EVENT_IOC_ENABLE . PERF_IOC_FLAG_GROUP ioctl ( BUGS). PERF_EVENT_IOC_DISABLE . . . PERF_IOC_FLAG_GROUP ioctl ( BUGS). PERF_EVENT_IOC_REFRESH . ioctl . POLL_IN 0 POLL_HUP . 0 . PERF_EVENT_IOC_RESET . time_enabled time_running. PERF_IOC_FLAG_GROUP ioctl ( BUGS). PERF_EVENT_IOC_PERIOD (overflow) . 3.7 ( ARM) 3.14 ( ) . . 64 . 2.6.36 ioctl . PERF_EVENT_IOC_SET_OUTPUT . . -1 . PERF_EVENT_IOC_SET_FILTER ( 2.6.33) ftrace . ftrace . PERF_EVENT_IOC_ID ( 3.12) . 64 . PERF_EVENT_IOC_SET_BPF ( 4.1) (BPF) kprobe . CAP_PERFMON ( 5.8) CAP_SYS_ADMIN ioctl . BPF bpf(2) . PERF_EVENT_IOC_PAUSE_OUTPUT ( 4.7) (ring-buffer) . . PERF_RECORD_LOST . . 32 . . PERF_EVENT_MODIFY_ATTRIBUTES ( 4.17) . (breakpoint events) . perf_event_attr . PERF_EVENT_IOC_QUERY_BPF ( 4.16) (BPF) kprobe . BPF . BPF . CAP_PERFMON ( 5.8) CAP_SYS_ADMIN ioctl . struct perf_event_query_bpf { __u32 ids_len; __u32 prog_cnt; __u32 ids[0]; }; ids_len ids . prog_cnt BPF . ids BPF . ENOSPC ids_len . prctl(2) prctl(2) PR_TASK_PERF_EVENTS_ENABLE PR_TASK_PERF_EVENTS_DISABLE. . . . perf_event /proc/sys/kernel/ /proc/sys/kernel/perf_event_paranoid perf_event_paranoid . 2 ( 4.6). 1 ( 4.6). 0 . -1 . perf_event_paranoid perf_event_open(). /proc/sys/kernel/perf_event_max_sample_rate . . 100000 ( ). /proc/sys/kernel/perf_event_max_stack (stack frame) (call trace). /proc/sys/kernel/perf_event_mlock_kb mlock(2). 516 (). /sys/bus/event_source/devices/ 2.6.34 (PMUs) . /sys/bus/event_source/devices/. PMU . /sys/bus/event_source/devices/*/type ( 2.6.38) type perf_event_attr PMU . /sys/bus/event_source/devices/cpu/rdpmc ( 3.4) 1 rdpmc. 0 . 4.0 1 perf 2 . /sys/bus/event_source/devices/*/format/ ( 3.4) config perf_event_attr. . event config1:1,6-10,44 1 6 10 44 perf_event_attr::config1. /sys/bus/event_source/devices/*/events/ ( 3.4) . ./format/ . PMU . . ( ). 1. : event=0x2,inv,ldlat=3. /sys/bus/event_source/devices/*/uevent (hotplug). /sys/bus/event_source/devices/*/cpumask ( 3.7) cpumask (socket) . uncore (northbridge) (PMUs) . perf_event_open() . -1 errno . perf_event_open() . E2BIG size perf_event_attr ( PERF_ATTR_SIZE_VER0) ( ) . E2BIG size perf_event_attr . EACCES CAP_PERFMON ( 5.8) CAP_SYS_ADMIN ( perf_event paranoid ). : ( pid -1) exclude_kernel paranoid . EBADF group_fd PERF_FLAG_PID_CGROUP cgroup pid . EBUSY ( 4.1) PMU. EFAULT attr . EINTR perf ftrace uprobe. EINVAL . : sample_freq cpu read_format sample_type flags exclusive pinned config . EMFILE . . ENODEV . ENOENT type . . ENOSPC 3.3 ENOSPC. 3.3 EINVAL. ENOSPC (breakpoint) . ENOSYS PERF_SAMPLE_STACK_USER sample_type . EOPNOTSUPP . (low-skid) (branch tracing) (sampling) PMU . EOVERFLOW ( 4.8) PERF_SAMPLE_CALLCHAIN sample_max_stack /proc/sys/kernel/perf_event_max_stack. EPERM ( ) exclude_hv exclude_idle exclude_user exclude_kernel. EACCES CAP_PERFMON ( 5.8) CAP_SYS_ADMIN ( perf_event paranoid ). ( 3.13) . ESRCH . . perf_event_open() 2.6.31 perf_counter_open(). 2.6.32. perf_event_open() /proc/sys/kernel/perf_event_paranoid. CAP_PERFMON ( 5.8) (POSIX IEEE 1003.1e). CAP_PERFMON CAP_SYS_ADMIN . CAP_SYS_ADMIN CAP_PERFMON . F_SETOWN_EX fcntl(2) . 2.6.32. 2.6.33 ( x86) . NMI . perf_event_open() . 2.6.34 . "0" . 2.6.34 . 2.6.35 2.6.39 "inherit" . 2.6.35 PERF_FORMAT_GROUP . 2.6.36 3.0 "watermark" wakeup_event (union) . 2.6.31 3.4 ioctl PERF_IOC_FLAG_GROUP . 3.4 3.11 mmap cap_usr_rdpmc cap_usr_time . cap_user_rdpmc cap_user_time . ! . (retired branches) AMD 2.6.35. printf(3). #include #include #include #include #include #include #include #include #include static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) { int ret; ret = syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); return ret; } int main(void) { int fd; long long count; struct perf_event_attr pe; memset(&pe, 0, sizeof(pe)); pe.type = PERF_TYPE_HARDWARE; pe.size = sizeof(pe); pe.config = PERF_COUNT_HW_INSTRUCTIONS; pe.disabled = 1; pe.exclude_kernel = 1; pe.exclude_hv = 1; fd = perf_event_open(&pe, 0, -1, -1, 0); if (fd == -1) err(EXIT_FAILURE, "Error opening leader %llx\n", pe.config); if (ioctl(fd, PERF_EVENT_IOC_RESET, 0) == -1) err(EXIT_FAILURE, "PERF_EVENT_IOC_RESET"); if (ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) == -1) err(EXIT_FAILURE, "PERF_EVENT_IOC_ENABLE"); printf("Measuring instruction count for this printf\n"); if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) == -1) err(EXIT_FAILURE, "PERF_EVENT_IOC_DISABLE"); if (read(fd, &count, sizeof(count)) != sizeof(count)) err(EXIT_FAILURE, "read"); printf("Used %lld instructions\n", count); if (close(fd) == -1) err(EXIT_FAILURE, "close"); } perf(1), fcntl(2), mmap(2), open(2), prctl(2), read(2) Documentation/admin-guide/perf-security.rst 3 . . : . 6.18 8 2026 perf_event_open(2)