Linux Audio

Check our new training course

Loading...
v6.2
  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
 14static int libperf_print(enum libperf_print_level level,
 15			 const char *fmt, va_list ap)
 16{
 17	return vfprintf(stderr, fmt, ap);
 18}
 19
 20static 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(NULL);
 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
 53static 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
 85static 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
127static 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
195static 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
230static 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
291static 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
352int 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}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2#include <stdarg.h>
  3#include <stdio.h>
 
  4#include <linux/perf_event.h>
 
  5#include <perf/cpumap.h>
  6#include <perf/threadmap.h>
  7#include <perf/evsel.h>
 
  8#include <internal/tests.h>
  9#include "tests.h"
 10
 11static int libperf_print(enum libperf_print_level level,
 12			 const char *fmt, va_list ap)
 13{
 14	return vfprintf(stderr, fmt, ap);
 15}
 16
 17static int test_stat_cpu(void)
 18{
 19	struct perf_cpu_map *cpus;
 20	struct perf_evsel *evsel;
 21	struct perf_event_attr attr = {
 22		.type	= PERF_TYPE_SOFTWARE,
 23		.config	= PERF_COUNT_SW_CPU_CLOCK,
 24	};
 25	int err, idx;
 26
 27	cpus = perf_cpu_map__new(NULL);
 28	__T("failed to create cpus", cpus);
 29
 30	evsel = perf_evsel__new(&attr);
 31	__T("failed to create evsel", evsel);
 32
 33	err = perf_evsel__open(evsel, cpus, NULL);
 34	__T("failed to open evsel", err == 0);
 35
 36	for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
 37		struct perf_counts_values counts = { .val = 0 };
 38
 39		perf_evsel__read(evsel, idx, 0, &counts);
 40		__T("failed to read value for evsel", counts.val != 0);
 41	}
 42
 43	perf_evsel__close(evsel);
 44	perf_evsel__delete(evsel);
 45
 46	perf_cpu_map__put(cpus);
 47	return 0;
 48}
 49
 50static int test_stat_thread(void)
 51{
 52	struct perf_counts_values counts = { .val = 0 };
 53	struct perf_thread_map *threads;
 54	struct perf_evsel *evsel;
 55	struct perf_event_attr attr = {
 56		.type	= PERF_TYPE_SOFTWARE,
 57		.config	= PERF_COUNT_SW_TASK_CLOCK,
 58	};
 59	int err;
 60
 61	threads = perf_thread_map__new_dummy();
 62	__T("failed to create threads", threads);
 63
 64	perf_thread_map__set_pid(threads, 0, 0);
 65
 66	evsel = perf_evsel__new(&attr);
 67	__T("failed to create evsel", evsel);
 68
 69	err = perf_evsel__open(evsel, NULL, threads);
 70	__T("failed to open evsel", err == 0);
 71
 72	perf_evsel__read(evsel, 0, 0, &counts);
 73	__T("failed to read value for evsel", counts.val != 0);
 74
 75	perf_evsel__close(evsel);
 76	perf_evsel__delete(evsel);
 77
 78	perf_thread_map__put(threads);
 79	return 0;
 80}
 81
 82static int test_stat_thread_enable(void)
 83{
 84	struct perf_counts_values counts = { .val = 0 };
 85	struct perf_thread_map *threads;
 86	struct perf_evsel *evsel;
 87	struct perf_event_attr attr = {
 88		.type	  = PERF_TYPE_SOFTWARE,
 89		.config	  = PERF_COUNT_SW_TASK_CLOCK,
 90		.disabled = 1,
 91	};
 92	int err;
 93
 94	threads = perf_thread_map__new_dummy();
 95	__T("failed to create threads", threads);
 96
 97	perf_thread_map__set_pid(threads, 0, 0);
 98
 99	evsel = perf_evsel__new(&attr);
100	__T("failed to create evsel", evsel);
101
102	err = perf_evsel__open(evsel, NULL, threads);
103	__T("failed to open evsel", err == 0);
104
105	perf_evsel__read(evsel, 0, 0, &counts);
106	__T("failed to read value for evsel", counts.val == 0);
107
108	err = perf_evsel__enable(evsel);
109	__T("failed to enable evsel", err == 0);
110
111	perf_evsel__read(evsel, 0, 0, &counts);
112	__T("failed to read value for evsel", counts.val != 0);
113
114	err = perf_evsel__disable(evsel);
115	__T("failed to enable evsel", err == 0);
116
117	perf_evsel__close(evsel);
118	perf_evsel__delete(evsel);
119
120	perf_thread_map__put(threads);
121	return 0;
122}
123
124static int test_stat_user_read(int event)
125{
126	struct perf_counts_values counts = { .val = 0 };
127	struct perf_thread_map *threads;
128	struct perf_evsel *evsel;
129	struct perf_event_mmap_page *pc;
130	struct perf_event_attr attr = {
131		.type	= PERF_TYPE_HARDWARE,
132		.config	= event,
 
 
 
133	};
134	int err, i;
135
136	threads = perf_thread_map__new_dummy();
137	__T("failed to create threads", threads);
138
139	perf_thread_map__set_pid(threads, 0, 0);
140
141	evsel = perf_evsel__new(&attr);
142	__T("failed to create evsel", evsel);
143
144	err = perf_evsel__open(evsel, NULL, threads);
145	__T("failed to open evsel", err == 0);
146
147	err = perf_evsel__mmap(evsel, 0);
148	__T("failed to mmap evsel", err == 0);
149
150	pc = perf_evsel__mmap_base(evsel, 0, 0);
151	__T("failed to get mmapped address", pc);
152
153#if defined(__i386__) || defined(__x86_64__)
154	__T("userspace counter access not supported", pc->cap_user_rdpmc);
155	__T("userspace counter access not enabled", pc->index);
156	__T("userspace counter width not set", pc->pmc_width >= 32);
157#endif
158
159	perf_evsel__read(evsel, 0, 0, &counts);
160	__T("failed to read value for evsel", counts.val != 0);
161
162	for (i = 0; i < 5; i++) {
163		volatile int count = 0x10000 << i;
164		__u64 start, end, last = 0;
165
166		__T_VERBOSE("\tloop = %u, ", count);
167
168		perf_evsel__read(evsel, 0, 0, &counts);
169		start = counts.val;
170
171		while (count--) ;
172
173		perf_evsel__read(evsel, 0, 0, &counts);
174		end = counts.val;
175
176		__T("invalid counter data", (end - start) > last);
177		last = end - start;
178		__T_VERBOSE("count = %llu\n", end - start);
179	}
180
181	perf_evsel__munmap(evsel);
182	perf_evsel__close(evsel);
183	perf_evsel__delete(evsel);
184
185	perf_thread_map__put(threads);
186	return 0;
187}
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189int test_evsel(int argc, char **argv)
190{
191	__T_START;
192
193	libperf_init(libperf_print);
194
195	test_stat_cpu();
196	test_stat_thread();
197	test_stat_thread_enable();
198	test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
199	test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
 
200
201	__T_END;
202	return tests_failed == 0 ? 0 : -1;
203}