Commit | Line | Data |
---|---|---|
f50246e2 JO |
1 | |
2 | #include "parse-events.h" | |
3 | #include "evsel.h" | |
4 | #include "evlist.h" | |
5 | #include "sysfs.h" | |
6 | #include "../../../include/linux/hw_breakpoint.h" | |
7 | ||
8 | #define TEST_ASSERT_VAL(text, cond) \ | |
9 | do { \ | |
10 | if (!(cond)) { \ | |
11 | pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ | |
12 | return -1; \ | |
13 | } \ | |
14 | } while (0) | |
15 | ||
16 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) | |
17 | { | |
18 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
19 | struct perf_evsel, node); | |
20 | ||
21 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
22 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | |
23 | TEST_ASSERT_VAL("wrong sample_type", | |
24 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | |
25 | evsel->attr.sample_type); | |
26 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | |
27 | return 0; | |
28 | } | |
29 | ||
30 | static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) | |
31 | { | |
32 | struct perf_evsel *evsel; | |
33 | ||
34 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | |
35 | ||
36 | list_for_each_entry(evsel, &evlist->entries, node) { | |
37 | TEST_ASSERT_VAL("wrong type", | |
38 | PERF_TYPE_TRACEPOINT == evsel->attr.type); | |
39 | TEST_ASSERT_VAL("wrong sample_type", | |
40 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) | |
41 | == evsel->attr.sample_type); | |
42 | TEST_ASSERT_VAL("wrong sample_period", | |
43 | 1 == evsel->attr.sample_period); | |
44 | } | |
45 | return 0; | |
46 | } | |
47 | ||
48 | static int test__checkevent_raw(struct perf_evlist *evlist) | |
49 | { | |
50 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
51 | struct perf_evsel, node); | |
52 | ||
53 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
54 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
55 | TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); | |
56 | return 0; | |
57 | } | |
58 | ||
59 | static int test__checkevent_numeric(struct perf_evlist *evlist) | |
60 | { | |
61 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
62 | struct perf_evsel, node); | |
63 | ||
64 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
65 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | |
66 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
67 | return 0; | |
68 | } | |
69 | ||
70 | static int test__checkevent_symbolic_name(struct perf_evlist *evlist) | |
71 | { | |
72 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
73 | struct perf_evsel, node); | |
74 | ||
75 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
76 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); | |
77 | TEST_ASSERT_VAL("wrong config", | |
78 | PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); | |
79 | return 0; | |
80 | } | |
81 | ||
82 | static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) | |
83 | { | |
84 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
85 | struct perf_evsel, node); | |
86 | ||
87 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
88 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); | |
89 | TEST_ASSERT_VAL("wrong config", | |
90 | PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); | |
91 | TEST_ASSERT_VAL("wrong period", | |
92 | 100000 == evsel->attr.sample_period); | |
93 | TEST_ASSERT_VAL("wrong config1", | |
94 | 0 == evsel->attr.config1); | |
95 | TEST_ASSERT_VAL("wrong config2", | |
96 | 1 == evsel->attr.config2); | |
97 | return 0; | |
98 | } | |
99 | ||
100 | static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) | |
101 | { | |
102 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
103 | struct perf_evsel, node); | |
104 | ||
105 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
106 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); | |
107 | TEST_ASSERT_VAL("wrong config", | |
108 | PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); | |
109 | return 0; | |
110 | } | |
111 | ||
112 | static int test__checkevent_genhw(struct perf_evlist *evlist) | |
113 | { | |
114 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
115 | struct perf_evsel, node); | |
116 | ||
117 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
118 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); | |
119 | TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); | |
120 | return 0; | |
121 | } | |
122 | ||
123 | static int test__checkevent_breakpoint(struct perf_evlist *evlist) | |
124 | { | |
125 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
126 | struct perf_evsel, node); | |
127 | ||
128 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
129 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | |
130 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | |
131 | TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == | |
132 | evsel->attr.bp_type); | |
133 | TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 == | |
134 | evsel->attr.bp_len); | |
135 | return 0; | |
136 | } | |
137 | ||
138 | static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) | |
139 | { | |
140 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
141 | struct perf_evsel, node); | |
142 | ||
143 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
144 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); | |
145 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | |
146 | TEST_ASSERT_VAL("wrong bp_type", | |
147 | HW_BREAKPOINT_X == evsel->attr.bp_type); | |
148 | TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len); | |
149 | return 0; | |
150 | } | |
151 | ||
152 | static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) | |
153 | { | |
154 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
155 | struct perf_evsel, node); | |
156 | ||
157 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
158 | TEST_ASSERT_VAL("wrong type", | |
159 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | |
160 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | |
161 | TEST_ASSERT_VAL("wrong bp_type", | |
162 | HW_BREAKPOINT_R == evsel->attr.bp_type); | |
163 | TEST_ASSERT_VAL("wrong bp_len", | |
164 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | |
165 | return 0; | |
166 | } | |
167 | ||
168 | static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) | |
169 | { | |
170 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
171 | struct perf_evsel, node); | |
172 | ||
173 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
174 | TEST_ASSERT_VAL("wrong type", | |
175 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | |
176 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | |
177 | TEST_ASSERT_VAL("wrong bp_type", | |
178 | HW_BREAKPOINT_W == evsel->attr.bp_type); | |
179 | TEST_ASSERT_VAL("wrong bp_len", | |
180 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | |
181 | return 0; | |
182 | } | |
183 | ||
7582732f JO |
184 | static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) |
185 | { | |
186 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
187 | struct perf_evsel, node); | |
188 | ||
189 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
190 | TEST_ASSERT_VAL("wrong type", | |
191 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | |
192 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | |
193 | TEST_ASSERT_VAL("wrong bp_type", | |
194 | (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); | |
195 | TEST_ASSERT_VAL("wrong bp_len", | |
196 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | |
197 | return 0; | |
198 | } | |
199 | ||
f50246e2 JO |
200 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) |
201 | { | |
202 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
203 | struct perf_evsel, node); | |
204 | ||
205 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
206 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
207 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
208 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
209 | ||
210 | return test__checkevent_tracepoint(evlist); | |
211 | } | |
212 | ||
213 | static int | |
214 | test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) | |
215 | { | |
216 | struct perf_evsel *evsel; | |
217 | ||
218 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | |
219 | ||
220 | list_for_each_entry(evsel, &evlist->entries, node) { | |
221 | TEST_ASSERT_VAL("wrong exclude_user", | |
222 | !evsel->attr.exclude_user); | |
223 | TEST_ASSERT_VAL("wrong exclude_kernel", | |
224 | evsel->attr.exclude_kernel); | |
225 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
226 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
227 | } | |
228 | ||
229 | return test__checkevent_tracepoint_multi(evlist); | |
230 | } | |
231 | ||
232 | static int test__checkevent_raw_modifier(struct perf_evlist *evlist) | |
233 | { | |
234 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
235 | struct perf_evsel, node); | |
236 | ||
237 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
238 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
239 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
240 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
241 | ||
242 | return test__checkevent_raw(evlist); | |
243 | } | |
244 | ||
245 | static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) | |
246 | { | |
247 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
248 | struct perf_evsel, node); | |
249 | ||
250 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
251 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
252 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
253 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
254 | ||
255 | return test__checkevent_numeric(evlist); | |
256 | } | |
257 | ||
258 | static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) | |
259 | { | |
260 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
261 | struct perf_evsel, node); | |
262 | ||
263 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
264 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
265 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
266 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
267 | ||
268 | return test__checkevent_symbolic_name(evlist); | |
269 | } | |
270 | ||
271 | static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) | |
272 | { | |
273 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
274 | struct perf_evsel, node); | |
275 | ||
276 | TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); | |
277 | TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); | |
278 | ||
279 | return test__checkevent_symbolic_name(evlist); | |
280 | } | |
281 | ||
282 | static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) | |
283 | { | |
284 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
285 | struct perf_evsel, node); | |
286 | ||
287 | TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); | |
288 | TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); | |
289 | ||
290 | return test__checkevent_symbolic_name(evlist); | |
291 | } | |
292 | ||
293 | static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) | |
294 | { | |
295 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
296 | struct perf_evsel, node); | |
297 | ||
298 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
299 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
300 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
301 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
302 | ||
303 | return test__checkevent_symbolic_alias(evlist); | |
304 | } | |
305 | ||
306 | static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) | |
307 | { | |
308 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
309 | struct perf_evsel, node); | |
310 | ||
311 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
312 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
313 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
314 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
315 | ||
316 | return test__checkevent_genhw(evlist); | |
317 | } | |
318 | ||
319 | static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) | |
320 | { | |
321 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
322 | struct perf_evsel, node); | |
323 | ||
324 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
325 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
326 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
327 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
287e74aa JO |
328 | TEST_ASSERT_VAL("wrong name", |
329 | !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:u")); | |
f50246e2 JO |
330 | |
331 | return test__checkevent_breakpoint(evlist); | |
332 | } | |
333 | ||
334 | static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) | |
335 | { | |
336 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
337 | struct perf_evsel, node); | |
338 | ||
339 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
340 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
341 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
342 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
287e74aa JO |
343 | TEST_ASSERT_VAL("wrong name", |
344 | !strcmp(perf_evsel__name(evsel), "mem:0x0:x:k")); | |
f50246e2 JO |
345 | |
346 | return test__checkevent_breakpoint_x(evlist); | |
347 | } | |
348 | ||
349 | static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) | |
350 | { | |
351 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
352 | struct perf_evsel, node); | |
353 | ||
354 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
355 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
356 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
357 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
287e74aa JO |
358 | TEST_ASSERT_VAL("wrong name", |
359 | !strcmp(perf_evsel__name(evsel), "mem:0x0:r:hp")); | |
f50246e2 JO |
360 | |
361 | return test__checkevent_breakpoint_r(evlist); | |
362 | } | |
363 | ||
364 | static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) | |
365 | { | |
366 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
367 | struct perf_evsel, node); | |
368 | ||
369 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
370 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
371 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
372 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
287e74aa JO |
373 | TEST_ASSERT_VAL("wrong name", |
374 | !strcmp(perf_evsel__name(evsel), "mem:0x0:w:up")); | |
f50246e2 JO |
375 | |
376 | return test__checkevent_breakpoint_w(evlist); | |
377 | } | |
378 | ||
7582732f JO |
379 | static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) |
380 | { | |
381 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
382 | struct perf_evsel, node); | |
383 | ||
384 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
385 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
386 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
387 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
287e74aa JO |
388 | TEST_ASSERT_VAL("wrong name", |
389 | !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:kp")); | |
7582732f JO |
390 | |
391 | return test__checkevent_breakpoint_rw(evlist); | |
392 | } | |
393 | ||
f50246e2 JO |
394 | static int test__checkevent_pmu(struct perf_evlist *evlist) |
395 | { | |
396 | ||
397 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
398 | struct perf_evsel, node); | |
399 | ||
400 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
401 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
402 | TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); | |
403 | TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); | |
404 | TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); | |
405 | TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); | |
406 | ||
407 | return 0; | |
408 | } | |
409 | ||
410 | static int test__checkevent_list(struct perf_evlist *evlist) | |
411 | { | |
412 | struct perf_evsel *evsel; | |
413 | ||
414 | TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); | |
415 | ||
416 | /* r1 */ | |
417 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); | |
418 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
419 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
420 | TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); | |
421 | TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); | |
422 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
423 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
424 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
425 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
426 | ||
427 | /* syscalls:sys_enter_open:k */ | |
428 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | |
429 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | |
430 | TEST_ASSERT_VAL("wrong sample_type", | |
431 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | |
432 | evsel->attr.sample_type); | |
433 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | |
434 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
435 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
436 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
437 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
438 | ||
439 | /* 1:1:hp */ | |
440 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | |
441 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | |
442 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
443 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
444 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
445 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
446 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
447 | ||
448 | return 0; | |
449 | } | |
450 | ||
6b5fc39b JO |
451 | static int test__checkevent_pmu_name(struct perf_evlist *evlist) |
452 | { | |
453 | struct perf_evsel *evsel; | |
454 | ||
7a25b2d3 | 455 | /* cpu/config=1,name=krava/u */ |
6b5fc39b JO |
456 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); |
457 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | |
458 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
459 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
22c8b843 | 460 | TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); |
6b5fc39b | 461 | |
7a25b2d3 | 462 | /* cpu/config=2/u" */ |
6b5fc39b JO |
463 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); |
464 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | |
465 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
466 | TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); | |
7a25b2d3 JO |
467 | TEST_ASSERT_VAL("wrong name", |
468 | !strcmp(perf_evsel__name(evsel), "raw 0x2:u")); | |
6b5fc39b JO |
469 | |
470 | return 0; | |
471 | } | |
472 | ||
4429392e JO |
473 | static int test__checkterms_simple(struct list_head *terms) |
474 | { | |
475 | struct parse_events__term *term; | |
476 | ||
477 | /* config=10 */ | |
478 | term = list_entry(terms->next, struct parse_events__term, list); | |
479 | TEST_ASSERT_VAL("wrong type term", | |
480 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); | |
481 | TEST_ASSERT_VAL("wrong type val", | |
482 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
483 | TEST_ASSERT_VAL("wrong val", term->val.num == 10); | |
484 | TEST_ASSERT_VAL("wrong config", !term->config); | |
485 | ||
486 | /* config1 */ | |
487 | term = list_entry(term->list.next, struct parse_events__term, list); | |
488 | TEST_ASSERT_VAL("wrong type term", | |
489 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); | |
490 | TEST_ASSERT_VAL("wrong type val", | |
491 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
492 | TEST_ASSERT_VAL("wrong val", term->val.num == 1); | |
493 | TEST_ASSERT_VAL("wrong config", !term->config); | |
494 | ||
495 | /* config2=3 */ | |
496 | term = list_entry(term->list.next, struct parse_events__term, list); | |
497 | TEST_ASSERT_VAL("wrong type term", | |
498 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); | |
499 | TEST_ASSERT_VAL("wrong type val", | |
500 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
501 | TEST_ASSERT_VAL("wrong val", term->val.num == 3); | |
502 | TEST_ASSERT_VAL("wrong config", !term->config); | |
503 | ||
504 | /* umask=1*/ | |
505 | term = list_entry(term->list.next, struct parse_events__term, list); | |
506 | TEST_ASSERT_VAL("wrong type term", | |
507 | term->type_term == PARSE_EVENTS__TERM_TYPE_USER); | |
508 | TEST_ASSERT_VAL("wrong type val", | |
509 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
510 | TEST_ASSERT_VAL("wrong val", term->val.num == 1); | |
511 | TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); | |
512 | ||
513 | return 0; | |
514 | } | |
515 | ||
f50246e2 JO |
516 | struct test__event_st { |
517 | const char *name; | |
518 | __u32 type; | |
519 | int (*check)(struct perf_evlist *evlist); | |
520 | }; | |
521 | ||
522 | static struct test__event_st test__events[] = { | |
523 | [0] = { | |
524 | .name = "syscalls:sys_enter_open", | |
525 | .check = test__checkevent_tracepoint, | |
526 | }, | |
527 | [1] = { | |
528 | .name = "syscalls:*", | |
529 | .check = test__checkevent_tracepoint_multi, | |
530 | }, | |
531 | [2] = { | |
532 | .name = "r1a", | |
533 | .check = test__checkevent_raw, | |
534 | }, | |
535 | [3] = { | |
536 | .name = "1:1", | |
537 | .check = test__checkevent_numeric, | |
538 | }, | |
539 | [4] = { | |
540 | .name = "instructions", | |
541 | .check = test__checkevent_symbolic_name, | |
542 | }, | |
543 | [5] = { | |
544 | .name = "cycles/period=100000,config2/", | |
545 | .check = test__checkevent_symbolic_name_config, | |
546 | }, | |
547 | [6] = { | |
548 | .name = "faults", | |
549 | .check = test__checkevent_symbolic_alias, | |
550 | }, | |
551 | [7] = { | |
552 | .name = "L1-dcache-load-miss", | |
553 | .check = test__checkevent_genhw, | |
554 | }, | |
555 | [8] = { | |
556 | .name = "mem:0", | |
557 | .check = test__checkevent_breakpoint, | |
558 | }, | |
559 | [9] = { | |
560 | .name = "mem:0:x", | |
561 | .check = test__checkevent_breakpoint_x, | |
562 | }, | |
563 | [10] = { | |
564 | .name = "mem:0:r", | |
565 | .check = test__checkevent_breakpoint_r, | |
566 | }, | |
567 | [11] = { | |
568 | .name = "mem:0:w", | |
569 | .check = test__checkevent_breakpoint_w, | |
570 | }, | |
571 | [12] = { | |
572 | .name = "syscalls:sys_enter_open:k", | |
573 | .check = test__checkevent_tracepoint_modifier, | |
574 | }, | |
575 | [13] = { | |
576 | .name = "syscalls:*:u", | |
577 | .check = test__checkevent_tracepoint_multi_modifier, | |
578 | }, | |
579 | [14] = { | |
580 | .name = "r1a:kp", | |
581 | .check = test__checkevent_raw_modifier, | |
582 | }, | |
583 | [15] = { | |
584 | .name = "1:1:hp", | |
585 | .check = test__checkevent_numeric_modifier, | |
586 | }, | |
587 | [16] = { | |
588 | .name = "instructions:h", | |
589 | .check = test__checkevent_symbolic_name_modifier, | |
590 | }, | |
591 | [17] = { | |
592 | .name = "faults:u", | |
593 | .check = test__checkevent_symbolic_alias_modifier, | |
594 | }, | |
595 | [18] = { | |
596 | .name = "L1-dcache-load-miss:kp", | |
597 | .check = test__checkevent_genhw_modifier, | |
598 | }, | |
599 | [19] = { | |
600 | .name = "mem:0:u", | |
601 | .check = test__checkevent_breakpoint_modifier, | |
602 | }, | |
603 | [20] = { | |
604 | .name = "mem:0:x:k", | |
605 | .check = test__checkevent_breakpoint_x_modifier, | |
606 | }, | |
607 | [21] = { | |
608 | .name = "mem:0:r:hp", | |
609 | .check = test__checkevent_breakpoint_r_modifier, | |
610 | }, | |
611 | [22] = { | |
612 | .name = "mem:0:w:up", | |
613 | .check = test__checkevent_breakpoint_w_modifier, | |
614 | }, | |
615 | [23] = { | |
616 | .name = "r1,syscalls:sys_enter_open:k,1:1:hp", | |
617 | .check = test__checkevent_list, | |
618 | }, | |
619 | [24] = { | |
620 | .name = "instructions:G", | |
621 | .check = test__checkevent_exclude_host_modifier, | |
622 | }, | |
623 | [25] = { | |
624 | .name = "instructions:H", | |
625 | .check = test__checkevent_exclude_guest_modifier, | |
626 | }, | |
7582732f JO |
627 | [26] = { |
628 | .name = "mem:0:rw", | |
629 | .check = test__checkevent_breakpoint_rw, | |
630 | }, | |
631 | [27] = { | |
632 | .name = "mem:0:rw:kp", | |
633 | .check = test__checkevent_breakpoint_rw_modifier, | |
634 | }, | |
f50246e2 JO |
635 | }; |
636 | ||
f50246e2 JO |
637 | static struct test__event_st test__events_pmu[] = { |
638 | [0] = { | |
639 | .name = "cpu/config=10,config1,config2=3,period=1000/u", | |
640 | .check = test__checkevent_pmu, | |
641 | }, | |
6b5fc39b JO |
642 | [1] = { |
643 | .name = "cpu/config=1,name=krava/u,cpu/config=2/u", | |
644 | .check = test__checkevent_pmu_name, | |
645 | }, | |
f50246e2 JO |
646 | }; |
647 | ||
4429392e JO |
648 | struct test__term { |
649 | const char *str; | |
650 | __u32 type; | |
651 | int (*check)(struct list_head *terms); | |
652 | }; | |
653 | ||
654 | static struct test__term test__terms[] = { | |
655 | [0] = { | |
656 | .str = "config=10,config1,config2=3,umask=1", | |
657 | .check = test__checkterms_simple, | |
658 | }, | |
659 | }; | |
660 | ||
661 | #define TEST__TERMS_CNT (sizeof(test__terms) / \ | |
662 | sizeof(struct test__term)) | |
663 | ||
664 | static int test_event(struct test__event_st *e) | |
f50246e2 JO |
665 | { |
666 | struct perf_evlist *evlist; | |
667 | int ret; | |
668 | ||
669 | evlist = perf_evlist__new(NULL, NULL); | |
670 | if (evlist == NULL) | |
671 | return -ENOMEM; | |
672 | ||
673 | ret = parse_events(evlist, e->name, 0); | |
674 | if (ret) { | |
675 | pr_debug("failed to parse event '%s', err %d\n", | |
676 | e->name, ret); | |
677 | return ret; | |
678 | } | |
679 | ||
680 | ret = e->check(evlist); | |
681 | perf_evlist__delete(evlist); | |
682 | ||
683 | return ret; | |
684 | } | |
685 | ||
686 | static int test_events(struct test__event_st *events, unsigned cnt) | |
687 | { | |
688 | int ret = 0; | |
689 | unsigned i; | |
690 | ||
691 | for (i = 0; i < cnt; i++) { | |
692 | struct test__event_st *e = &events[i]; | |
693 | ||
694 | pr_debug("running test %d '%s'\n", i, e->name); | |
4429392e JO |
695 | ret = test_event(e); |
696 | if (ret) | |
697 | break; | |
698 | } | |
699 | ||
700 | return ret; | |
701 | } | |
702 | ||
703 | static int test_term(struct test__term *t) | |
704 | { | |
705 | struct list_head *terms; | |
706 | int ret; | |
707 | ||
708 | terms = malloc(sizeof(*terms)); | |
709 | if (!terms) | |
710 | return -ENOMEM; | |
711 | ||
712 | INIT_LIST_HEAD(terms); | |
713 | ||
714 | ret = parse_events_terms(terms, t->str); | |
715 | if (ret) { | |
716 | pr_debug("failed to parse terms '%s', err %d\n", | |
717 | t->str , ret); | |
718 | return ret; | |
719 | } | |
720 | ||
721 | ret = t->check(terms); | |
722 | parse_events__free_terms(terms); | |
723 | ||
724 | return ret; | |
725 | } | |
726 | ||
727 | static int test_terms(struct test__term *terms, unsigned cnt) | |
728 | { | |
729 | int ret = 0; | |
730 | unsigned i; | |
731 | ||
732 | for (i = 0; i < cnt; i++) { | |
733 | struct test__term *t = &terms[i]; | |
734 | ||
735 | pr_debug("running test %d '%s'\n", i, t->str); | |
736 | ret = test_term(t); | |
f50246e2 JO |
737 | if (ret) |
738 | break; | |
739 | } | |
740 | ||
741 | return ret; | |
742 | } | |
743 | ||
744 | static int test_pmu(void) | |
745 | { | |
746 | struct stat st; | |
747 | char path[PATH_MAX]; | |
748 | int ret; | |
749 | ||
750 | snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/", | |
751 | sysfs_find_mountpoint()); | |
752 | ||
753 | ret = stat(path, &st); | |
754 | if (ret) | |
755 | pr_debug("ommiting PMU cpu tests\n"); | |
756 | return !ret; | |
757 | } | |
758 | ||
759 | int parse_events__test(void) | |
760 | { | |
761 | int ret; | |
762 | ||
ebf124ff JO |
763 | #define TEST_EVENTS(tests) \ |
764 | do { \ | |
765 | ret = test_events(tests, ARRAY_SIZE(tests)); \ | |
766 | if (ret) \ | |
767 | return ret; \ | |
768 | } while (0) | |
4429392e | 769 | |
ebf124ff | 770 | TEST_EVENTS(test__events); |
4429392e | 771 | |
ebf124ff JO |
772 | if (test_pmu()) |
773 | TEST_EVENTS(test__events_pmu); | |
f50246e2 | 774 | |
ebf124ff | 775 | return test_terms(test__terms, ARRAY_SIZE(test__terms)); |
f50246e2 | 776 | } |