]>
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 | ||
184 | static int test__checkevent_tracepoint_modifier(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 exclude_user", evsel->attr.exclude_user); | |
190 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
191 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
192 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
193 | ||
194 | return test__checkevent_tracepoint(evlist); | |
195 | } | |
196 | ||
197 | static int | |
198 | test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) | |
199 | { | |
200 | struct perf_evsel *evsel; | |
201 | ||
202 | TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); | |
203 | ||
204 | list_for_each_entry(evsel, &evlist->entries, node) { | |
205 | TEST_ASSERT_VAL("wrong exclude_user", | |
206 | !evsel->attr.exclude_user); | |
207 | TEST_ASSERT_VAL("wrong exclude_kernel", | |
208 | evsel->attr.exclude_kernel); | |
209 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
210 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
211 | } | |
212 | ||
213 | return test__checkevent_tracepoint_multi(evlist); | |
214 | } | |
215 | ||
216 | static int test__checkevent_raw_modifier(struct perf_evlist *evlist) | |
217 | { | |
218 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
219 | struct perf_evsel, node); | |
220 | ||
221 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
222 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
223 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
224 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
225 | ||
226 | return test__checkevent_raw(evlist); | |
227 | } | |
228 | ||
229 | static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) | |
230 | { | |
231 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
232 | struct perf_evsel, node); | |
233 | ||
234 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
235 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
236 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
237 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
238 | ||
239 | return test__checkevent_numeric(evlist); | |
240 | } | |
241 | ||
242 | static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) | |
243 | { | |
244 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
245 | struct perf_evsel, node); | |
246 | ||
247 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
248 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
249 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
250 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
251 | ||
252 | return test__checkevent_symbolic_name(evlist); | |
253 | } | |
254 | ||
255 | static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) | |
256 | { | |
257 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
258 | struct perf_evsel, node); | |
259 | ||
260 | TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); | |
261 | TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); | |
262 | ||
263 | return test__checkevent_symbolic_name(evlist); | |
264 | } | |
265 | ||
266 | static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) | |
267 | { | |
268 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
269 | struct perf_evsel, node); | |
270 | ||
271 | TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); | |
272 | TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); | |
273 | ||
274 | return test__checkevent_symbolic_name(evlist); | |
275 | } | |
276 | ||
277 | static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) | |
278 | { | |
279 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
280 | struct perf_evsel, node); | |
281 | ||
282 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
283 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
284 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
285 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
286 | ||
287 | return test__checkevent_symbolic_alias(evlist); | |
288 | } | |
289 | ||
290 | static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) | |
291 | { | |
292 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
293 | struct perf_evsel, node); | |
294 | ||
295 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
296 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
297 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
298 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
299 | ||
300 | return test__checkevent_genhw(evlist); | |
301 | } | |
302 | ||
303 | static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) | |
304 | { | |
305 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
306 | struct perf_evsel, node); | |
307 | ||
308 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
309 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
310 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
311 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
312 | ||
313 | return test__checkevent_breakpoint(evlist); | |
314 | } | |
315 | ||
316 | static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) | |
317 | { | |
318 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
319 | struct perf_evsel, node); | |
320 | ||
321 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
322 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
323 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
324 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
325 | ||
326 | return test__checkevent_breakpoint_x(evlist); | |
327 | } | |
328 | ||
329 | static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) | |
330 | { | |
331 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
332 | struct perf_evsel, node); | |
333 | ||
334 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
335 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
336 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
337 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
338 | ||
339 | return test__checkevent_breakpoint_r(evlist); | |
340 | } | |
341 | ||
342 | static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) | |
343 | { | |
344 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
345 | struct perf_evsel, node); | |
346 | ||
347 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
348 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
349 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
350 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
351 | ||
352 | return test__checkevent_breakpoint_w(evlist); | |
353 | } | |
354 | ||
355 | static int test__checkevent_pmu(struct perf_evlist *evlist) | |
356 | { | |
357 | ||
358 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | |
359 | struct perf_evsel, node); | |
360 | ||
361 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | |
362 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
363 | TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); | |
364 | TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); | |
365 | TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); | |
366 | TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); | |
367 | ||
368 | return 0; | |
369 | } | |
370 | ||
371 | static int test__checkevent_list(struct perf_evlist *evlist) | |
372 | { | |
373 | struct perf_evsel *evsel; | |
374 | ||
375 | TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); | |
376 | ||
377 | /* r1 */ | |
378 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); | |
379 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
380 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
381 | TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); | |
382 | TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); | |
383 | TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); | |
384 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
385 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
386 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
387 | ||
388 | /* syscalls:sys_enter_open:k */ | |
389 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | |
390 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | |
391 | TEST_ASSERT_VAL("wrong sample_type", | |
392 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | |
393 | evsel->attr.sample_type); | |
394 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | |
395 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
396 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | |
397 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | |
398 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | |
399 | ||
400 | /* 1:1:hp */ | |
401 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | |
402 | TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); | |
403 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
404 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | |
405 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | |
406 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | |
407 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | |
408 | ||
409 | return 0; | |
410 | } | |
411 | ||
6b5fc39b JO |
412 | static int test__checkevent_pmu_name(struct perf_evlist *evlist) |
413 | { | |
414 | struct perf_evsel *evsel; | |
415 | ||
7a25b2d3 | 416 | /* cpu/config=1,name=krava/u */ |
6b5fc39b JO |
417 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); |
418 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | |
419 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
420 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | |
22c8b843 | 421 | TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); |
6b5fc39b | 422 | |
7a25b2d3 | 423 | /* cpu/config=2/u" */ |
6b5fc39b JO |
424 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); |
425 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | |
426 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | |
427 | TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); | |
7a25b2d3 JO |
428 | TEST_ASSERT_VAL("wrong name", |
429 | !strcmp(perf_evsel__name(evsel), "raw 0x2:u")); | |
6b5fc39b JO |
430 | |
431 | return 0; | |
432 | } | |
433 | ||
4429392e JO |
434 | static int test__checkterms_simple(struct list_head *terms) |
435 | { | |
436 | struct parse_events__term *term; | |
437 | ||
438 | /* config=10 */ | |
439 | term = list_entry(terms->next, struct parse_events__term, list); | |
440 | TEST_ASSERT_VAL("wrong type term", | |
441 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); | |
442 | TEST_ASSERT_VAL("wrong type val", | |
443 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
444 | TEST_ASSERT_VAL("wrong val", term->val.num == 10); | |
445 | TEST_ASSERT_VAL("wrong config", !term->config); | |
446 | ||
447 | /* config1 */ | |
448 | term = list_entry(term->list.next, struct parse_events__term, list); | |
449 | TEST_ASSERT_VAL("wrong type term", | |
450 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); | |
451 | TEST_ASSERT_VAL("wrong type val", | |
452 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
453 | TEST_ASSERT_VAL("wrong val", term->val.num == 1); | |
454 | TEST_ASSERT_VAL("wrong config", !term->config); | |
455 | ||
456 | /* config2=3 */ | |
457 | term = list_entry(term->list.next, struct parse_events__term, list); | |
458 | TEST_ASSERT_VAL("wrong type term", | |
459 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); | |
460 | TEST_ASSERT_VAL("wrong type val", | |
461 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
462 | TEST_ASSERT_VAL("wrong val", term->val.num == 3); | |
463 | TEST_ASSERT_VAL("wrong config", !term->config); | |
464 | ||
465 | /* umask=1*/ | |
466 | term = list_entry(term->list.next, struct parse_events__term, list); | |
467 | TEST_ASSERT_VAL("wrong type term", | |
468 | term->type_term == PARSE_EVENTS__TERM_TYPE_USER); | |
469 | TEST_ASSERT_VAL("wrong type val", | |
470 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | |
471 | TEST_ASSERT_VAL("wrong val", term->val.num == 1); | |
472 | TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); | |
473 | ||
474 | return 0; | |
475 | } | |
476 | ||
f50246e2 JO |
477 | struct test__event_st { |
478 | const char *name; | |
479 | __u32 type; | |
480 | int (*check)(struct perf_evlist *evlist); | |
481 | }; | |
482 | ||
483 | static struct test__event_st test__events[] = { | |
484 | [0] = { | |
485 | .name = "syscalls:sys_enter_open", | |
486 | .check = test__checkevent_tracepoint, | |
487 | }, | |
488 | [1] = { | |
489 | .name = "syscalls:*", | |
490 | .check = test__checkevent_tracepoint_multi, | |
491 | }, | |
492 | [2] = { | |
493 | .name = "r1a", | |
494 | .check = test__checkevent_raw, | |
495 | }, | |
496 | [3] = { | |
497 | .name = "1:1", | |
498 | .check = test__checkevent_numeric, | |
499 | }, | |
500 | [4] = { | |
501 | .name = "instructions", | |
502 | .check = test__checkevent_symbolic_name, | |
503 | }, | |
504 | [5] = { | |
505 | .name = "cycles/period=100000,config2/", | |
506 | .check = test__checkevent_symbolic_name_config, | |
507 | }, | |
508 | [6] = { | |
509 | .name = "faults", | |
510 | .check = test__checkevent_symbolic_alias, | |
511 | }, | |
512 | [7] = { | |
513 | .name = "L1-dcache-load-miss", | |
514 | .check = test__checkevent_genhw, | |
515 | }, | |
516 | [8] = { | |
517 | .name = "mem:0", | |
518 | .check = test__checkevent_breakpoint, | |
519 | }, | |
520 | [9] = { | |
521 | .name = "mem:0:x", | |
522 | .check = test__checkevent_breakpoint_x, | |
523 | }, | |
524 | [10] = { | |
525 | .name = "mem:0:r", | |
526 | .check = test__checkevent_breakpoint_r, | |
527 | }, | |
528 | [11] = { | |
529 | .name = "mem:0:w", | |
530 | .check = test__checkevent_breakpoint_w, | |
531 | }, | |
532 | [12] = { | |
533 | .name = "syscalls:sys_enter_open:k", | |
534 | .check = test__checkevent_tracepoint_modifier, | |
535 | }, | |
536 | [13] = { | |
537 | .name = "syscalls:*:u", | |
538 | .check = test__checkevent_tracepoint_multi_modifier, | |
539 | }, | |
540 | [14] = { | |
541 | .name = "r1a:kp", | |
542 | .check = test__checkevent_raw_modifier, | |
543 | }, | |
544 | [15] = { | |
545 | .name = "1:1:hp", | |
546 | .check = test__checkevent_numeric_modifier, | |
547 | }, | |
548 | [16] = { | |
549 | .name = "instructions:h", | |
550 | .check = test__checkevent_symbolic_name_modifier, | |
551 | }, | |
552 | [17] = { | |
553 | .name = "faults:u", | |
554 | .check = test__checkevent_symbolic_alias_modifier, | |
555 | }, | |
556 | [18] = { | |
557 | .name = "L1-dcache-load-miss:kp", | |
558 | .check = test__checkevent_genhw_modifier, | |
559 | }, | |
560 | [19] = { | |
561 | .name = "mem:0:u", | |
562 | .check = test__checkevent_breakpoint_modifier, | |
563 | }, | |
564 | [20] = { | |
565 | .name = "mem:0:x:k", | |
566 | .check = test__checkevent_breakpoint_x_modifier, | |
567 | }, | |
568 | [21] = { | |
569 | .name = "mem:0:r:hp", | |
570 | .check = test__checkevent_breakpoint_r_modifier, | |
571 | }, | |
572 | [22] = { | |
573 | .name = "mem:0:w:up", | |
574 | .check = test__checkevent_breakpoint_w_modifier, | |
575 | }, | |
576 | [23] = { | |
577 | .name = "r1,syscalls:sys_enter_open:k,1:1:hp", | |
578 | .check = test__checkevent_list, | |
579 | }, | |
580 | [24] = { | |
581 | .name = "instructions:G", | |
582 | .check = test__checkevent_exclude_host_modifier, | |
583 | }, | |
584 | [25] = { | |
585 | .name = "instructions:H", | |
586 | .check = test__checkevent_exclude_guest_modifier, | |
587 | }, | |
588 | }; | |
589 | ||
590 | #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) | |
591 | ||
592 | static struct test__event_st test__events_pmu[] = { | |
593 | [0] = { | |
594 | .name = "cpu/config=10,config1,config2=3,period=1000/u", | |
595 | .check = test__checkevent_pmu, | |
596 | }, | |
6b5fc39b JO |
597 | [1] = { |
598 | .name = "cpu/config=1,name=krava/u,cpu/config=2/u", | |
599 | .check = test__checkevent_pmu_name, | |
600 | }, | |
f50246e2 JO |
601 | }; |
602 | ||
603 | #define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \ | |
604 | sizeof(struct test__event_st)) | |
605 | ||
4429392e JO |
606 | struct test__term { |
607 | const char *str; | |
608 | __u32 type; | |
609 | int (*check)(struct list_head *terms); | |
610 | }; | |
611 | ||
612 | static struct test__term test__terms[] = { | |
613 | [0] = { | |
614 | .str = "config=10,config1,config2=3,umask=1", | |
615 | .check = test__checkterms_simple, | |
616 | }, | |
617 | }; | |
618 | ||
619 | #define TEST__TERMS_CNT (sizeof(test__terms) / \ | |
620 | sizeof(struct test__term)) | |
621 | ||
622 | static int test_event(struct test__event_st *e) | |
f50246e2 JO |
623 | { |
624 | struct perf_evlist *evlist; | |
625 | int ret; | |
626 | ||
627 | evlist = perf_evlist__new(NULL, NULL); | |
628 | if (evlist == NULL) | |
629 | return -ENOMEM; | |
630 | ||
631 | ret = parse_events(evlist, e->name, 0); | |
632 | if (ret) { | |
633 | pr_debug("failed to parse event '%s', err %d\n", | |
634 | e->name, ret); | |
635 | return ret; | |
636 | } | |
637 | ||
638 | ret = e->check(evlist); | |
639 | perf_evlist__delete(evlist); | |
640 | ||
641 | return ret; | |
642 | } | |
643 | ||
644 | static int test_events(struct test__event_st *events, unsigned cnt) | |
645 | { | |
646 | int ret = 0; | |
647 | unsigned i; | |
648 | ||
649 | for (i = 0; i < cnt; i++) { | |
650 | struct test__event_st *e = &events[i]; | |
651 | ||
652 | pr_debug("running test %d '%s'\n", i, e->name); | |
4429392e JO |
653 | ret = test_event(e); |
654 | if (ret) | |
655 | break; | |
656 | } | |
657 | ||
658 | return ret; | |
659 | } | |
660 | ||
661 | static int test_term(struct test__term *t) | |
662 | { | |
663 | struct list_head *terms; | |
664 | int ret; | |
665 | ||
666 | terms = malloc(sizeof(*terms)); | |
667 | if (!terms) | |
668 | return -ENOMEM; | |
669 | ||
670 | INIT_LIST_HEAD(terms); | |
671 | ||
672 | ret = parse_events_terms(terms, t->str); | |
673 | if (ret) { | |
674 | pr_debug("failed to parse terms '%s', err %d\n", | |
675 | t->str , ret); | |
676 | return ret; | |
677 | } | |
678 | ||
679 | ret = t->check(terms); | |
680 | parse_events__free_terms(terms); | |
681 | ||
682 | return ret; | |
683 | } | |
684 | ||
685 | static int test_terms(struct test__term *terms, unsigned cnt) | |
686 | { | |
687 | int ret = 0; | |
688 | unsigned i; | |
689 | ||
690 | for (i = 0; i < cnt; i++) { | |
691 | struct test__term *t = &terms[i]; | |
692 | ||
693 | pr_debug("running test %d '%s'\n", i, t->str); | |
694 | ret = test_term(t); | |
f50246e2 JO |
695 | if (ret) |
696 | break; | |
697 | } | |
698 | ||
699 | return ret; | |
700 | } | |
701 | ||
702 | static int test_pmu(void) | |
703 | { | |
704 | struct stat st; | |
705 | char path[PATH_MAX]; | |
706 | int ret; | |
707 | ||
708 | snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/", | |
709 | sysfs_find_mountpoint()); | |
710 | ||
711 | ret = stat(path, &st); | |
712 | if (ret) | |
713 | pr_debug("ommiting PMU cpu tests\n"); | |
714 | return !ret; | |
715 | } | |
716 | ||
717 | int parse_events__test(void) | |
718 | { | |
719 | int ret; | |
720 | ||
4429392e JO |
721 | do { |
722 | ret = test_events(test__events, TEST__EVENTS_CNT); | |
723 | if (ret) | |
724 | break; | |
725 | ||
726 | if (test_pmu()) { | |
727 | ret = test_events(test__events_pmu, | |
728 | TEST__EVENTS_PMU_CNT); | |
729 | if (ret) | |
730 | break; | |
731 | } | |
732 | ||
733 | ret = test_terms(test__terms, TEST__TERMS_CNT); | |
734 | ||
735 | } while (0); | |
f50246e2 JO |
736 | |
737 | return ret; | |
738 | } |