Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/lib/perf/tests/test-evsel.c
26288 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <stdarg.h>
3
#include <stdio.h>
4
#include <string.h>
5
#include <linux/perf_event.h>
6
#include <linux/kernel.h>
7
#include <perf/cpumap.h>
8
#include <perf/threadmap.h>
9
#include <perf/evsel.h>
10
#include <internal/evsel.h>
11
#include <internal/tests.h>
12
#include "tests.h"
13
14
static int libperf_print(enum libperf_print_level level,
15
const char *fmt, va_list ap)
16
{
17
return vfprintf(stderr, fmt, ap);
18
}
19
20
static int test_stat_cpu(void)
21
{
22
struct perf_cpu_map *cpus;
23
struct perf_evsel *evsel;
24
struct perf_event_attr attr = {
25
.type = PERF_TYPE_SOFTWARE,
26
.config = PERF_COUNT_SW_CPU_CLOCK,
27
};
28
int err, idx;
29
30
cpus = perf_cpu_map__new_online_cpus();
31
__T("failed to create cpus", cpus);
32
33
evsel = perf_evsel__new(&attr);
34
__T("failed to create evsel", evsel);
35
36
err = perf_evsel__open(evsel, cpus, NULL);
37
__T("failed to open evsel", err == 0);
38
39
for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
40
struct perf_counts_values counts = { .val = 0 };
41
42
perf_evsel__read(evsel, idx, 0, &counts);
43
__T("failed to read value for evsel", counts.val != 0);
44
}
45
46
perf_evsel__close(evsel);
47
perf_evsel__delete(evsel);
48
49
perf_cpu_map__put(cpus);
50
return 0;
51
}
52
53
static int test_stat_thread(void)
54
{
55
struct perf_counts_values counts = { .val = 0 };
56
struct perf_thread_map *threads;
57
struct perf_evsel *evsel;
58
struct perf_event_attr attr = {
59
.type = PERF_TYPE_SOFTWARE,
60
.config = PERF_COUNT_SW_TASK_CLOCK,
61
};
62
int err;
63
64
threads = perf_thread_map__new_dummy();
65
__T("failed to create threads", threads);
66
67
perf_thread_map__set_pid(threads, 0, 0);
68
69
evsel = perf_evsel__new(&attr);
70
__T("failed to create evsel", evsel);
71
72
err = perf_evsel__open(evsel, NULL, threads);
73
__T("failed to open evsel", err == 0);
74
75
perf_evsel__read(evsel, 0, 0, &counts);
76
__T("failed to read value for evsel", counts.val != 0);
77
78
perf_evsel__close(evsel);
79
perf_evsel__delete(evsel);
80
81
perf_thread_map__put(threads);
82
return 0;
83
}
84
85
static int test_stat_thread_enable(void)
86
{
87
struct perf_counts_values counts = { .val = 0 };
88
struct perf_thread_map *threads;
89
struct perf_evsel *evsel;
90
struct perf_event_attr attr = {
91
.type = PERF_TYPE_SOFTWARE,
92
.config = PERF_COUNT_SW_TASK_CLOCK,
93
.disabled = 1,
94
};
95
int err;
96
97
threads = perf_thread_map__new_dummy();
98
__T("failed to create threads", threads);
99
100
perf_thread_map__set_pid(threads, 0, 0);
101
102
evsel = perf_evsel__new(&attr);
103
__T("failed to create evsel", evsel);
104
105
err = perf_evsel__open(evsel, NULL, threads);
106
__T("failed to open evsel", err == 0);
107
108
perf_evsel__read(evsel, 0, 0, &counts);
109
__T("failed to read value for evsel", counts.val == 0);
110
111
err = perf_evsel__enable(evsel);
112
__T("failed to enable evsel", err == 0);
113
114
perf_evsel__read(evsel, 0, 0, &counts);
115
__T("failed to read value for evsel", counts.val != 0);
116
117
err = perf_evsel__disable(evsel);
118
__T("failed to enable evsel", err == 0);
119
120
perf_evsel__close(evsel);
121
perf_evsel__delete(evsel);
122
123
perf_thread_map__put(threads);
124
return 0;
125
}
126
127
static int test_stat_user_read(int event)
128
{
129
struct perf_counts_values counts = { .val = 0 };
130
struct perf_thread_map *threads;
131
struct perf_evsel *evsel;
132
struct perf_event_mmap_page *pc;
133
struct perf_event_attr attr = {
134
.type = PERF_TYPE_HARDWARE,
135
.config = event,
136
#ifdef __aarch64__
137
.config1 = 0x2, /* Request user access */
138
#endif
139
};
140
int err, i;
141
142
threads = perf_thread_map__new_dummy();
143
__T("failed to create threads", threads);
144
145
perf_thread_map__set_pid(threads, 0, 0);
146
147
evsel = perf_evsel__new(&attr);
148
__T("failed to create evsel", evsel);
149
150
err = perf_evsel__open(evsel, NULL, threads);
151
__T("failed to open evsel", err == 0);
152
153
err = perf_evsel__mmap(evsel, 0);
154
__T("failed to mmap evsel", err == 0);
155
156
pc = perf_evsel__mmap_base(evsel, 0, 0);
157
__T("failed to get mmapped address", pc);
158
159
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
160
__T("userspace counter access not supported", pc->cap_user_rdpmc);
161
__T("userspace counter access not enabled", pc->index);
162
__T("userspace counter width not set", pc->pmc_width >= 32);
163
#endif
164
165
perf_evsel__read(evsel, 0, 0, &counts);
166
__T("failed to read value for evsel", counts.val != 0);
167
168
for (i = 0; i < 5; i++) {
169
volatile int count = 0x10000 << i;
170
__u64 start, end, last = 0;
171
172
__T_VERBOSE("\tloop = %u, ", count);
173
174
perf_evsel__read(evsel, 0, 0, &counts);
175
start = counts.val;
176
177
while (count--) ;
178
179
perf_evsel__read(evsel, 0, 0, &counts);
180
end = counts.val;
181
182
__T("invalid counter data", (end - start) > last);
183
last = end - start;
184
__T_VERBOSE("count = %llu\n", end - start);
185
}
186
187
perf_evsel__munmap(evsel);
188
perf_evsel__close(evsel);
189
perf_evsel__delete(evsel);
190
191
perf_thread_map__put(threads);
192
return 0;
193
}
194
195
static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)
196
{
197
struct perf_evsel *evsel;
198
struct perf_counts_values counts;
199
volatile int count = 0x100000;
200
int err;
201
202
evsel = perf_evsel__new(attr);
203
__T("failed to create evsel", evsel);
204
205
/* skip old kernels that don't support the format */
206
err = perf_evsel__open(evsel, NULL, threads);
207
if (err < 0)
208
return 0;
209
210
while (count--) ;
211
212
memset(&counts, -1, sizeof(counts));
213
perf_evsel__read(evsel, 0, 0, &counts);
214
215
__T("failed to read value", counts.val);
216
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
217
__T("failed to read TOTAL_TIME_ENABLED", counts.ena);
218
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
219
__T("failed to read TOTAL_TIME_RUNNING", counts.run);
220
if (attr->read_format & PERF_FORMAT_ID)
221
__T("failed to read ID", counts.id);
222
if (attr->read_format & PERF_FORMAT_LOST)
223
__T("failed to read LOST", counts.lost == 0);
224
225
perf_evsel__close(evsel);
226
perf_evsel__delete(evsel);
227
return 0;
228
}
229
230
static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)
231
{
232
struct perf_evsel *leader, *member;
233
struct perf_counts_values counts;
234
volatile int count = 0x100000;
235
int err;
236
237
attr->read_format |= PERF_FORMAT_GROUP;
238
leader = perf_evsel__new(attr);
239
__T("failed to create leader", leader);
240
241
attr->read_format &= ~PERF_FORMAT_GROUP;
242
member = perf_evsel__new(attr);
243
__T("failed to create member", member);
244
245
member->leader = leader;
246
leader->nr_members = 2;
247
248
/* skip old kernels that don't support the format */
249
err = perf_evsel__open(leader, NULL, threads);
250
if (err < 0)
251
return 0;
252
err = perf_evsel__open(member, NULL, threads);
253
if (err < 0)
254
return 0;
255
256
while (count--) ;
257
258
memset(&counts, -1, sizeof(counts));
259
perf_evsel__read(leader, 0, 0, &counts);
260
261
__T("failed to read leader value", counts.val);
262
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
263
__T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);
264
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
265
__T("failed to read leader TOTAL_TIME_RUNNING", counts.run);
266
if (attr->read_format & PERF_FORMAT_ID)
267
__T("failed to read leader ID", counts.id);
268
if (attr->read_format & PERF_FORMAT_LOST)
269
__T("failed to read leader LOST", counts.lost == 0);
270
271
memset(&counts, -1, sizeof(counts));
272
perf_evsel__read(member, 0, 0, &counts);
273
274
__T("failed to read member value", counts.val);
275
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
276
__T("failed to read member TOTAL_TIME_ENABLED", counts.ena);
277
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
278
__T("failed to read member TOTAL_TIME_RUNNING", counts.run);
279
if (attr->read_format & PERF_FORMAT_ID)
280
__T("failed to read member ID", counts.id);
281
if (attr->read_format & PERF_FORMAT_LOST)
282
__T("failed to read member LOST", counts.lost == 0);
283
284
perf_evsel__close(member);
285
perf_evsel__close(leader);
286
perf_evsel__delete(member);
287
perf_evsel__delete(leader);
288
return 0;
289
}
290
291
static int test_stat_read_format(void)
292
{
293
struct perf_thread_map *threads;
294
struct perf_event_attr attr = {
295
.type = PERF_TYPE_SOFTWARE,
296
.config = PERF_COUNT_SW_TASK_CLOCK,
297
};
298
int err, i;
299
300
#define FMT(_fmt) PERF_FORMAT_ ## _fmt
301
#define FMT_TIME (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
302
303
uint64_t test_formats [] = {
304
0,
305
FMT_TIME,
306
FMT(ID),
307
FMT(LOST),
308
FMT_TIME | FMT(ID),
309
FMT_TIME | FMT(LOST),
310
FMT_TIME | FMT(ID) | FMT(LOST),
311
FMT(ID) | FMT(LOST),
312
};
313
314
#undef FMT
315
#undef FMT_TIME
316
317
threads = perf_thread_map__new_dummy();
318
__T("failed to create threads", threads);
319
320
perf_thread_map__set_pid(threads, 0, 0);
321
322
for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
323
attr.read_format = test_formats[i];
324
__T_VERBOSE("testing single read with read_format: %lx\n",
325
(unsigned long)test_formats[i]);
326
327
err = test_stat_read_format_single(&attr, threads);
328
__T("failed to read single format", err == 0);
329
}
330
331
perf_thread_map__put(threads);
332
333
threads = perf_thread_map__new_array(2, NULL);
334
__T("failed to create threads", threads);
335
336
perf_thread_map__set_pid(threads, 0, 0);
337
perf_thread_map__set_pid(threads, 1, 0);
338
339
for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
340
attr.read_format = test_formats[i];
341
__T_VERBOSE("testing group read with read_format: %lx\n",
342
(unsigned long)test_formats[i]);
343
344
err = test_stat_read_format_group(&attr, threads);
345
__T("failed to read group format", err == 0);
346
}
347
348
perf_thread_map__put(threads);
349
return 0;
350
}
351
352
int test_evsel(int argc, char **argv)
353
{
354
__T_START;
355
356
libperf_init(libperf_print);
357
358
test_stat_cpu();
359
test_stat_thread();
360
test_stat_thread_enable();
361
test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
362
test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
363
test_stat_read_format();
364
365
__T_END;
366
return tests_failed == 0 ? 0 : -1;
367
}
368
369