@@ -10,18 +10,83 @@ use std::mem;
1010
1111// Expanded from systing's code: www.github.com/josefbacik/systing
1212
13- const PERF_TYPE_HARDWARE : u32 = 0x0 ;
14- const PERF_TYPE_SOFTWARE : u32 = 0x1 ;
15- const PERF_TYPE_RAW : u32 = 0x3 ;
16- const PERF_TYPE_IBS : u32 = 0xb ;
17-
18- const PERF_COUNT_HW_CPU_CYCLES : u64 = 0 ;
19- const PERF_COUNT_HW_CACHE_REFERENCES : u64 = 2 ;
20- const PERF_COUNT_HW_CACHE_MISSES : u64 = 3 ;
21- const PERF_COUNT_HW_STALLED_CYCLES_FRONTEND : u64 = 7 ;
22- const PERF_COUNT_HW_STALLED_CYCLES_BACKEND : u64 = 8 ;
23-
24- const PERF_COUNT_SW_CPU_CLOCK : u64 = 0 ;
13+ const _PERF_TYPE_HARDWARE: u32 = 0x0 ;
14+ const _PERF_TYPE_SOFTWARE: u32 = 0x1 ;
15+ const _PERF_TYPE_RAW: u32 = 0x3 ;
16+ const _PERF_TYPE_AMD_IBS: u32 = 0xb ;
17+
18+ const _PERF_COUNT_HW_CPU_CYCLES: u64 = 0 ;
19+ const _PERF_COUNT_HW_CACHE_REFERENCES: u64 = 2 ;
20+ const _PERF_COUNT_HW_CACHE_MISSES: u64 = 3 ;
21+ const _PERF_COUNT_HW_STALLED_CYCLES_FRONTEND: u64 = 7 ;
22+ const _PERF_COUNT_HW_STALLED_CYCLES_BACKEND: u64 = 8 ;
23+
24+ const _PERF_COUNT_SW_CPU_CLOCK: u64 = 0 ;
25+
26+ // WARNING: These are not guaranteed to be correct because the layout of the bitfield
27+ // in the perf_sample_attr C struct that contains them is not guaranteed by the C standard.
28+ const _PERF_SAMPLE_FLAG_DISABLED: u64 = 1 << 0 ;
29+ const _PERF_SAMPLE_FLAG_INHERIT: u64 = 1 << 1 ;
30+ const _PERF_SAMPLE_FLAG_PINNED: u64 = 1 << 2 ;
31+ const _PERF_SAMPLE_FLAG_EXCLUSIVE: u64 = 1 << 3 ;
32+ const _PERF_SAMPLE_FLAG_EXCLUDE_USER: u64 = 1 << 4 ;
33+ const _PERF_SAMPLE_FLAG_EXCLUDE_KERNEL: u64 = 1 << 5 ;
34+ const _PERF_SAMPLE_FLAG_EXCLUDE_HV: u64 = 1 << 6 ;
35+ const _PERF_SAMPLE_FLAG_EXCLUDE_IDLE: u64 = 1 << 7 ;
36+ const _PERF_SAMPLE_FLAG_MMAP: u64 = 1 << 8 ;
37+ const _PERF_SAMPLE_FLAG_COMM: u64 = 1 << 9 ;
38+ const _PERF_SAMPLE_FLAG_FREQ: u64 = 1 << 10 ;
39+ const _PERF_SAMPLE_FLAG_INHERIT_STAT: u64 = 1 << 11 ;
40+ const _PERF_SAMPLE_FLAG_ENABLE_ON_EXEC: u64 = 1 << 12 ;
41+ const _PERF_SAMPLE_FLAG_TASK: u64 = 1 << 13 ;
42+ const _PERF_SAMPLE_FLAG_WATERMARK: u64 = 1 << 14 ;
43+ const _PERF_SAMPLE_FLAG_PRECISE_IP: u64 = 1 << 15 ;
44+ const _PERF_SAMPLE_FLAG_MMAP_DATA: u64 = 1 << 17 ;
45+ const _PERF_SAMPLE_FLAG_ID_ALL: u64 = 1 << 18 ;
46+ const _PERF_SAMPLE_FLAG_EXCLUDE_HOST: u64 = 1 << 19 ;
47+ const _PERF_SAMPLE_FLAG_EXCLUDE_GUEST: u64 = 1 << 20 ;
48+ const _PERF_SAMPLE_FLAG_EXCLUDE_CALLCHAIN_KERNEL: u64 = 1 << 21 ;
49+ const _PERF_SAMPLE_FLAG_EXCLUDE_CALLCHAIN_USER: u64 = 1 << 22 ;
50+ const _PERF_SAMPLE_FLAG_MMAP2: u64 = 1 << 23 ;
51+ const _PERF_SAMPLE_FLAG_COMM_EXEC: u64 = 1 << 24 ;
52+ const _PERF_SAMPLE_FLAG_USE_CLOCKID: u64 = 1 << 25 ;
53+ const _PERF_SAMPLE_FLAG_WRITE_BACKWARD: u64 = 1 << 26 ;
54+ const _PERF_SAMPLE_FLAG_NAMESPACES: u64 = 1 << 27 ;
55+ const _PERF_SAMPLE_FLAG_KSYMBOL: u64 = 1 << 28 ;
56+ const _PERF_SAMPLE_FLAG_BPF_SYMBOL: u64 = 1 << 29 ;
57+ const _PERF_SAMPLE_FLAG_AUX_OUTPUT: u64 = 1 << 30 ;
58+ const _PERF_SAMPLE_FLAG_CGROUP: u64 = 1 << 31 ;
59+ const _PERF_SAMPLE_FLAG_TEXT_POKE: u64 = 1 << 32 ;
60+ const _PERF_SAMPLE_FLAG_BUILD_ID: u64 = 1 << 33 ;
61+ const _PERF_SAMPLE_FLAG_INHERIT_THREAD: u64 = 1 << 34 ;
62+ const _PERF_SAMPLE_FLAG_REMOVE_ON_EXEC: u64 = 1 << 35 ;
63+ const _PERF_SAMPLE_FLAG_SIGTRAP: u64 = 1 << 36 ;
64+
65+ const _PERF_SAMPLE_IP: u64 = 1 << 0 ;
66+ const _PERF_SAMPLE_TID: u64 = 1 << 1 ;
67+ const _PERF_SAMPLE_TIME: u64 = 1 << 2 ;
68+ const _PERF_SAMPLE_ADDR: u64 = 1 << 3 ;
69+ const _PERF_SAMPLE_READ: u64 = 1 << 4 ;
70+ const _PERF_SAMPLE_CALLCHAIN: u64 = 1 << 5 ;
71+ const _PERF_SAMPLE_ID: u64 = 1 << 6 ;
72+ const _PERF_SAMPLE_CPU: u64 = 1 << 7 ;
73+ const _PERF_SAMPLE_PERIOD: u64 = 1 << 8 ;
74+ const _PERF_SAMPLE_STREAM_ID: u64 = 1 << 9 ;
75+ const _PERF_SAMPLE_RAW: u64 = 1 << 10 ;
76+ const _PERF_SAMPLE_BRANCH_STACK: u64 = 1 << 11 ;
77+ const _PERF_SAMPLE_REGS_USER: u64 = 1 << 12 ;
78+ const _PERF_SAMPLE_STACK_USER: u64 = 1 << 13 ;
79+ const _PERF_SAMPLE_WEIGHT: u64 = 1 << 14 ;
80+ const _PERF_SAMPLE_DATA_SRC: u64 = 1 << 15 ;
81+ const _PERF_SAMPLE_IDENTIFIER: u64 = 1 << 16 ;
82+ const _PERF_SAMPLE_TRANSACTION: u64 = 1 << 17 ;
83+ const _PERF_SAMPLE_REGS_INTR: u64 = 1 << 18 ;
84+ const _PERF_SAMPLE_PHYS_ADDR: u64 = 1 << 19 ;
85+ const _PERF_SAMPLE_PHYS_AUX: u64 = 1 << 20 ;
86+ const _PERF_SAMPLE_PHYS_CGROUP: u64 = 1 << 21 ;
87+ const _PERF_SAMPLE_DATA_PAGE_SIZE: u64 = 1 << 22 ;
88+ const _PERF_SAMPLE_CODE_PAGE_SIZE: u64 = 1 << 23 ;
89+ const _PERF_SAMPLE_WEIGHT_STRUCT: u64 = 1 << 24 ;
2590
2691#[ repr( C ) ]
2792union sample_un {
@@ -141,19 +206,24 @@ pub fn init_perf_counters(skel: &mut BpfSkel, cpu: &i32) -> Result<(i32, libbpf_
141206 )
142207 } ;
143208
144- attr. _type = PERF_TYPE_HARDWARE ;
209+ /*
210+ * XXX Discover the counter instead of hardcoding it.
211+ * Afterwards we can use any counter we care for.
212+ */
213+ attr. _type = _PERF_TYPE_AMD_IBS;
145214 attr. size = mem:: size_of :: < perf_event_attr > ( ) as u32 ;
146- attr. config = PERF_COUNT_HW_CPU_CYCLES ;
215+ attr. config = 0 ;
216+ attr. sample_type = _PERF_SAMPLE_CPU | _PERF_SAMPLE_IP | _PERF_SAMPLE_TID | _PERF_SAMPLE_DATA_SRC | _PERF_SAMPLE_PHYS_ADDR | _PERF_SAMPLE_ADDR;
147217 attr. sample . sample_period = 1000 ;
148- attr. flags = 0 ;
218+ attr. flags = 3 * _PERF_SAMPLE_FLAG_PRECISE_IP ;
149219
150220 let pefd = perf_event_open ( attr. as_ref ( ) , -1 , * cpu, -1 , 0 ) as i32 ;
151221 if pefd == -1 {
152222 let os_error = io:: Error :: last_os_error ( ) ;
153223 return Err ( libbpf_rs:: Error :: from ( os_error) ) ;
154224 }
155225
156- let link = skel. progs . drain_counters . attach_perf_event_with_opts ( pefd) ;
226+ let link = skel. progs . read_sample . attach_perf_event_with_opts ( pefd) ;
157227
158228 Ok ( ( pefd, link?) )
159229}
0 commit comments