xref: /linux/tools/lib/perf/tests/test-evsel.c (revision 47d01e7b9999b9591077a59a1ecec11c6ce570de)
13ce311afSJiri Olsa // SPDX-License-Identifier: GPL-2.0
23ce311afSJiri Olsa #include <stdarg.h>
33ce311afSJiri Olsa #include <stdio.h>
43ce311afSJiri Olsa #include <linux/perf_event.h>
53ce311afSJiri Olsa #include <perf/cpumap.h>
63ce311afSJiri Olsa #include <perf/threadmap.h>
73ce311afSJiri Olsa #include <perf/evsel.h>
83ce311afSJiri Olsa #include <internal/tests.h>
93ce311afSJiri Olsa 
103ce311afSJiri Olsa static int libperf_print(enum libperf_print_level level,
113ce311afSJiri Olsa 			 const char *fmt, va_list ap)
123ce311afSJiri Olsa {
133ce311afSJiri Olsa 	return vfprintf(stderr, fmt, ap);
143ce311afSJiri Olsa }
153ce311afSJiri Olsa 
163ce311afSJiri Olsa static int test_stat_cpu(void)
173ce311afSJiri Olsa {
183ce311afSJiri Olsa 	struct perf_cpu_map *cpus;
193ce311afSJiri Olsa 	struct perf_evsel *evsel;
203ce311afSJiri Olsa 	struct perf_event_attr attr = {
213ce311afSJiri Olsa 		.type	= PERF_TYPE_SOFTWARE,
223ce311afSJiri Olsa 		.config	= PERF_COUNT_SW_CPU_CLOCK,
233ce311afSJiri Olsa 	};
243ce311afSJiri Olsa 	int err, cpu, tmp;
253ce311afSJiri Olsa 
263ce311afSJiri Olsa 	cpus = perf_cpu_map__new(NULL);
273ce311afSJiri Olsa 	__T("failed to create cpus", cpus);
283ce311afSJiri Olsa 
293ce311afSJiri Olsa 	evsel = perf_evsel__new(&attr);
303ce311afSJiri Olsa 	__T("failed to create evsel", evsel);
313ce311afSJiri Olsa 
323ce311afSJiri Olsa 	err = perf_evsel__open(evsel, cpus, NULL);
333ce311afSJiri Olsa 	__T("failed to open evsel", err == 0);
343ce311afSJiri Olsa 
353ce311afSJiri Olsa 	perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
363ce311afSJiri Olsa 		struct perf_counts_values counts = { .val = 0 };
373ce311afSJiri Olsa 
383ce311afSJiri Olsa 		perf_evsel__read(evsel, cpu, 0, &counts);
393ce311afSJiri Olsa 		__T("failed to read value for evsel", counts.val != 0);
403ce311afSJiri Olsa 	}
413ce311afSJiri Olsa 
423ce311afSJiri Olsa 	perf_evsel__close(evsel);
433ce311afSJiri Olsa 	perf_evsel__delete(evsel);
443ce311afSJiri Olsa 
453ce311afSJiri Olsa 	perf_cpu_map__put(cpus);
463ce311afSJiri Olsa 	return 0;
473ce311afSJiri Olsa }
483ce311afSJiri Olsa 
493ce311afSJiri Olsa static int test_stat_thread(void)
503ce311afSJiri Olsa {
513ce311afSJiri Olsa 	struct perf_counts_values counts = { .val = 0 };
523ce311afSJiri Olsa 	struct perf_thread_map *threads;
533ce311afSJiri Olsa 	struct perf_evsel *evsel;
543ce311afSJiri Olsa 	struct perf_event_attr attr = {
553ce311afSJiri Olsa 		.type	= PERF_TYPE_SOFTWARE,
563ce311afSJiri Olsa 		.config	= PERF_COUNT_SW_TASK_CLOCK,
573ce311afSJiri Olsa 	};
583ce311afSJiri Olsa 	int err;
593ce311afSJiri Olsa 
603ce311afSJiri Olsa 	threads = perf_thread_map__new_dummy();
613ce311afSJiri Olsa 	__T("failed to create threads", threads);
623ce311afSJiri Olsa 
633ce311afSJiri Olsa 	perf_thread_map__set_pid(threads, 0, 0);
643ce311afSJiri Olsa 
653ce311afSJiri Olsa 	evsel = perf_evsel__new(&attr);
663ce311afSJiri Olsa 	__T("failed to create evsel", evsel);
673ce311afSJiri Olsa 
683ce311afSJiri Olsa 	err = perf_evsel__open(evsel, NULL, threads);
693ce311afSJiri Olsa 	__T("failed to open evsel", err == 0);
703ce311afSJiri Olsa 
713ce311afSJiri Olsa 	perf_evsel__read(evsel, 0, 0, &counts);
723ce311afSJiri Olsa 	__T("failed to read value for evsel", counts.val != 0);
733ce311afSJiri Olsa 
743ce311afSJiri Olsa 	perf_evsel__close(evsel);
753ce311afSJiri Olsa 	perf_evsel__delete(evsel);
763ce311afSJiri Olsa 
773ce311afSJiri Olsa 	perf_thread_map__put(threads);
783ce311afSJiri Olsa 	return 0;
793ce311afSJiri Olsa }
803ce311afSJiri Olsa 
813ce311afSJiri Olsa static int test_stat_thread_enable(void)
823ce311afSJiri Olsa {
833ce311afSJiri Olsa 	struct perf_counts_values counts = { .val = 0 };
843ce311afSJiri Olsa 	struct perf_thread_map *threads;
853ce311afSJiri Olsa 	struct perf_evsel *evsel;
863ce311afSJiri Olsa 	struct perf_event_attr attr = {
873ce311afSJiri Olsa 		.type	  = PERF_TYPE_SOFTWARE,
883ce311afSJiri Olsa 		.config	  = PERF_COUNT_SW_TASK_CLOCK,
893ce311afSJiri Olsa 		.disabled = 1,
903ce311afSJiri Olsa 	};
913ce311afSJiri Olsa 	int err;
923ce311afSJiri Olsa 
933ce311afSJiri Olsa 	threads = perf_thread_map__new_dummy();
943ce311afSJiri Olsa 	__T("failed to create threads", threads);
953ce311afSJiri Olsa 
963ce311afSJiri Olsa 	perf_thread_map__set_pid(threads, 0, 0);
973ce311afSJiri Olsa 
983ce311afSJiri Olsa 	evsel = perf_evsel__new(&attr);
993ce311afSJiri Olsa 	__T("failed to create evsel", evsel);
1003ce311afSJiri Olsa 
1013ce311afSJiri Olsa 	err = perf_evsel__open(evsel, NULL, threads);
1023ce311afSJiri Olsa 	__T("failed to open evsel", err == 0);
1033ce311afSJiri Olsa 
1043ce311afSJiri Olsa 	perf_evsel__read(evsel, 0, 0, &counts);
1053ce311afSJiri Olsa 	__T("failed to read value for evsel", counts.val == 0);
1063ce311afSJiri Olsa 
1073ce311afSJiri Olsa 	err = perf_evsel__enable(evsel);
1083ce311afSJiri Olsa 	__T("failed to enable evsel", err == 0);
1093ce311afSJiri Olsa 
1103ce311afSJiri Olsa 	perf_evsel__read(evsel, 0, 0, &counts);
1113ce311afSJiri Olsa 	__T("failed to read value for evsel", counts.val != 0);
1123ce311afSJiri Olsa 
1133ce311afSJiri Olsa 	err = perf_evsel__disable(evsel);
1143ce311afSJiri Olsa 	__T("failed to enable evsel", err == 0);
1153ce311afSJiri Olsa 
1163ce311afSJiri Olsa 	perf_evsel__close(evsel);
1173ce311afSJiri Olsa 	perf_evsel__delete(evsel);
1183ce311afSJiri Olsa 
1193ce311afSJiri Olsa 	perf_thread_map__put(threads);
1203ce311afSJiri Olsa 	return 0;
1213ce311afSJiri Olsa }
1223ce311afSJiri Olsa 
123*47d01e7bSRob Herring static int test_stat_user_read(int event)
124*47d01e7bSRob Herring {
125*47d01e7bSRob Herring 	struct perf_counts_values counts = { .val = 0 };
126*47d01e7bSRob Herring 	struct perf_thread_map *threads;
127*47d01e7bSRob Herring 	struct perf_evsel *evsel;
128*47d01e7bSRob Herring 	struct perf_event_mmap_page *pc;
129*47d01e7bSRob Herring 	struct perf_event_attr attr = {
130*47d01e7bSRob Herring 		.type	= PERF_TYPE_HARDWARE,
131*47d01e7bSRob Herring 		.config	= event,
132*47d01e7bSRob Herring 	};
133*47d01e7bSRob Herring 	int err, i;
134*47d01e7bSRob Herring 
135*47d01e7bSRob Herring 	threads = perf_thread_map__new_dummy();
136*47d01e7bSRob Herring 	__T("failed to create threads", threads);
137*47d01e7bSRob Herring 
138*47d01e7bSRob Herring 	perf_thread_map__set_pid(threads, 0, 0);
139*47d01e7bSRob Herring 
140*47d01e7bSRob Herring 	evsel = perf_evsel__new(&attr);
141*47d01e7bSRob Herring 	__T("failed to create evsel", evsel);
142*47d01e7bSRob Herring 
143*47d01e7bSRob Herring 	err = perf_evsel__open(evsel, NULL, threads);
144*47d01e7bSRob Herring 	__T("failed to open evsel", err == 0);
145*47d01e7bSRob Herring 
146*47d01e7bSRob Herring 	err = perf_evsel__mmap(evsel, 0);
147*47d01e7bSRob Herring 	__T("failed to mmap evsel", err == 0);
148*47d01e7bSRob Herring 
149*47d01e7bSRob Herring 	pc = perf_evsel__mmap_base(evsel, 0, 0);
150*47d01e7bSRob Herring 
151*47d01e7bSRob Herring #if defined(__i386__) || defined(__x86_64__)
152*47d01e7bSRob Herring 	__T("userspace counter access not supported", pc->cap_user_rdpmc);
153*47d01e7bSRob Herring 	__T("userspace counter access not enabled", pc->index);
154*47d01e7bSRob Herring 	__T("userspace counter width not set", pc->pmc_width >= 32);
155*47d01e7bSRob Herring #endif
156*47d01e7bSRob Herring 
157*47d01e7bSRob Herring 	perf_evsel__read(evsel, 0, 0, &counts);
158*47d01e7bSRob Herring 	__T("failed to read value for evsel", counts.val != 0);
159*47d01e7bSRob Herring 
160*47d01e7bSRob Herring 	for (i = 0; i < 5; i++) {
161*47d01e7bSRob Herring 		volatile int count = 0x10000 << i;
162*47d01e7bSRob Herring 		__u64 start, end, last = 0;
163*47d01e7bSRob Herring 
164*47d01e7bSRob Herring 		__T_VERBOSE("\tloop = %u, ", count);
165*47d01e7bSRob Herring 
166*47d01e7bSRob Herring 		perf_evsel__read(evsel, 0, 0, &counts);
167*47d01e7bSRob Herring 		start = counts.val;
168*47d01e7bSRob Herring 
169*47d01e7bSRob Herring 		while (count--) ;
170*47d01e7bSRob Herring 
171*47d01e7bSRob Herring 		perf_evsel__read(evsel, 0, 0, &counts);
172*47d01e7bSRob Herring 		end = counts.val;
173*47d01e7bSRob Herring 
174*47d01e7bSRob Herring 		__T("invalid counter data", (end - start) > last);
175*47d01e7bSRob Herring 		last = end - start;
176*47d01e7bSRob Herring 		__T_VERBOSE("count = %llu\n", end - start);
177*47d01e7bSRob Herring 	}
178*47d01e7bSRob Herring 
179*47d01e7bSRob Herring 	perf_evsel__munmap(evsel);
180*47d01e7bSRob Herring 	perf_evsel__close(evsel);
181*47d01e7bSRob Herring 	perf_evsel__delete(evsel);
182*47d01e7bSRob Herring 
183*47d01e7bSRob Herring 	perf_thread_map__put(threads);
184*47d01e7bSRob Herring 	return 0;
185*47d01e7bSRob Herring }
186*47d01e7bSRob Herring 
1873ce311afSJiri Olsa int main(int argc, char **argv)
1883ce311afSJiri Olsa {
1893ce311afSJiri Olsa 	__T_START;
1903ce311afSJiri Olsa 
1913ce311afSJiri Olsa 	libperf_init(libperf_print);
1923ce311afSJiri Olsa 
1933ce311afSJiri Olsa 	test_stat_cpu();
1943ce311afSJiri Olsa 	test_stat_thread();
1953ce311afSJiri Olsa 	test_stat_thread_enable();
196*47d01e7bSRob Herring 	test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
197*47d01e7bSRob Herring 	test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
1983ce311afSJiri Olsa 
1993ce311afSJiri Olsa 	__T_END;
200bba2ea17SIan Rogers 	return tests_failed == 0 ? 0 : -1;
2013ce311afSJiri Olsa }
202