Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.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}