xref: /linux/tools/lib/perf/tests/test-evsel.c (revision f304c8d949f9adc2ef51304b63e49d5ea1c2d288)
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>
93d970601SJiri Olsa #include "tests.h"
103ce311afSJiri Olsa 
113ce311afSJiri Olsa static int libperf_print(enum libperf_print_level level,
123ce311afSJiri Olsa 			 const char *fmt, va_list ap)
133ce311afSJiri Olsa {
143ce311afSJiri Olsa 	return vfprintf(stderr, fmt, ap);
153ce311afSJiri Olsa }
163ce311afSJiri Olsa 
173ce311afSJiri Olsa static int test_stat_cpu(void)
183ce311afSJiri Olsa {
193ce311afSJiri Olsa 	struct perf_cpu_map *cpus;
203ce311afSJiri Olsa 	struct perf_evsel *evsel;
213ce311afSJiri Olsa 	struct perf_event_attr attr = {
223ce311afSJiri Olsa 		.type	= PERF_TYPE_SOFTWARE,
233ce311afSJiri Olsa 		.config	= PERF_COUNT_SW_CPU_CLOCK,
243ce311afSJiri Olsa 	};
253ce311afSJiri Olsa 	int err, cpu, tmp;
263ce311afSJiri Olsa 
273ce311afSJiri Olsa 	cpus = perf_cpu_map__new(NULL);
283ce311afSJiri Olsa 	__T("failed to create cpus", cpus);
293ce311afSJiri Olsa 
303ce311afSJiri Olsa 	evsel = perf_evsel__new(&attr);
313ce311afSJiri Olsa 	__T("failed to create evsel", evsel);
323ce311afSJiri Olsa 
333ce311afSJiri Olsa 	err = perf_evsel__open(evsel, cpus, NULL);
343ce311afSJiri Olsa 	__T("failed to open evsel", err == 0);
353ce311afSJiri Olsa 
363ce311afSJiri Olsa 	perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
373ce311afSJiri Olsa 		struct perf_counts_values counts = { .val = 0 };
383ce311afSJiri Olsa 
393ce311afSJiri Olsa 		perf_evsel__read(evsel, cpu, 0, &counts);
403ce311afSJiri Olsa 		__T("failed to read value for evsel", counts.val != 0);
413ce311afSJiri Olsa 	}
423ce311afSJiri Olsa 
433ce311afSJiri Olsa 	perf_evsel__close(evsel);
443ce311afSJiri Olsa 	perf_evsel__delete(evsel);
453ce311afSJiri Olsa 
463ce311afSJiri Olsa 	perf_cpu_map__put(cpus);
473ce311afSJiri Olsa 	return 0;
483ce311afSJiri Olsa }
493ce311afSJiri Olsa 
503ce311afSJiri Olsa static int test_stat_thread(void)
513ce311afSJiri Olsa {
523ce311afSJiri Olsa 	struct perf_counts_values counts = { .val = 0 };
533ce311afSJiri Olsa 	struct perf_thread_map *threads;
543ce311afSJiri Olsa 	struct perf_evsel *evsel;
553ce311afSJiri Olsa 	struct perf_event_attr attr = {
563ce311afSJiri Olsa 		.type	= PERF_TYPE_SOFTWARE,
573ce311afSJiri Olsa 		.config	= PERF_COUNT_SW_TASK_CLOCK,
583ce311afSJiri Olsa 	};
593ce311afSJiri Olsa 	int err;
603ce311afSJiri Olsa 
613ce311afSJiri Olsa 	threads = perf_thread_map__new_dummy();
623ce311afSJiri Olsa 	__T("failed to create threads", threads);
633ce311afSJiri Olsa 
643ce311afSJiri Olsa 	perf_thread_map__set_pid(threads, 0, 0);
653ce311afSJiri Olsa 
663ce311afSJiri Olsa 	evsel = perf_evsel__new(&attr);
673ce311afSJiri Olsa 	__T("failed to create evsel", evsel);
683ce311afSJiri Olsa 
693ce311afSJiri Olsa 	err = perf_evsel__open(evsel, NULL, threads);
703ce311afSJiri Olsa 	__T("failed to open evsel", err == 0);
713ce311afSJiri Olsa 
723ce311afSJiri Olsa 	perf_evsel__read(evsel, 0, 0, &counts);
733ce311afSJiri Olsa 	__T("failed to read value for evsel", counts.val != 0);
743ce311afSJiri Olsa 
753ce311afSJiri Olsa 	perf_evsel__close(evsel);
763ce311afSJiri Olsa 	perf_evsel__delete(evsel);
773ce311afSJiri Olsa 
783ce311afSJiri Olsa 	perf_thread_map__put(threads);
793ce311afSJiri Olsa 	return 0;
803ce311afSJiri Olsa }
813ce311afSJiri Olsa 
823ce311afSJiri Olsa static int test_stat_thread_enable(void)
833ce311afSJiri Olsa {
843ce311afSJiri Olsa 	struct perf_counts_values counts = { .val = 0 };
853ce311afSJiri Olsa 	struct perf_thread_map *threads;
863ce311afSJiri Olsa 	struct perf_evsel *evsel;
873ce311afSJiri Olsa 	struct perf_event_attr attr = {
883ce311afSJiri Olsa 		.type	  = PERF_TYPE_SOFTWARE,
893ce311afSJiri Olsa 		.config	  = PERF_COUNT_SW_TASK_CLOCK,
903ce311afSJiri Olsa 		.disabled = 1,
913ce311afSJiri Olsa 	};
923ce311afSJiri Olsa 	int err;
933ce311afSJiri Olsa 
943ce311afSJiri Olsa 	threads = perf_thread_map__new_dummy();
953ce311afSJiri Olsa 	__T("failed to create threads", threads);
963ce311afSJiri Olsa 
973ce311afSJiri Olsa 	perf_thread_map__set_pid(threads, 0, 0);
983ce311afSJiri Olsa 
993ce311afSJiri Olsa 	evsel = perf_evsel__new(&attr);
1003ce311afSJiri Olsa 	__T("failed to create evsel", evsel);
1013ce311afSJiri Olsa 
1023ce311afSJiri Olsa 	err = perf_evsel__open(evsel, NULL, threads);
1033ce311afSJiri Olsa 	__T("failed to open evsel", err == 0);
1043ce311afSJiri Olsa 
1053ce311afSJiri Olsa 	perf_evsel__read(evsel, 0, 0, &counts);
1063ce311afSJiri Olsa 	__T("failed to read value for evsel", counts.val == 0);
1073ce311afSJiri Olsa 
1083ce311afSJiri Olsa 	err = perf_evsel__enable(evsel);
1093ce311afSJiri Olsa 	__T("failed to enable evsel", err == 0);
1103ce311afSJiri Olsa 
1113ce311afSJiri Olsa 	perf_evsel__read(evsel, 0, 0, &counts);
1123ce311afSJiri Olsa 	__T("failed to read value for evsel", counts.val != 0);
1133ce311afSJiri Olsa 
1143ce311afSJiri Olsa 	err = perf_evsel__disable(evsel);
1153ce311afSJiri Olsa 	__T("failed to enable evsel", err == 0);
1163ce311afSJiri Olsa 
1173ce311afSJiri Olsa 	perf_evsel__close(evsel);
1183ce311afSJiri Olsa 	perf_evsel__delete(evsel);
1193ce311afSJiri Olsa 
1203ce311afSJiri Olsa 	perf_thread_map__put(threads);
1213ce311afSJiri Olsa 	return 0;
1223ce311afSJiri Olsa }
1233ce311afSJiri Olsa 
12447d01e7bSRob Herring static int test_stat_user_read(int event)
12547d01e7bSRob Herring {
12647d01e7bSRob Herring 	struct perf_counts_values counts = { .val = 0 };
12747d01e7bSRob Herring 	struct perf_thread_map *threads;
12847d01e7bSRob Herring 	struct perf_evsel *evsel;
12947d01e7bSRob Herring 	struct perf_event_mmap_page *pc;
13047d01e7bSRob Herring 	struct perf_event_attr attr = {
13147d01e7bSRob Herring 		.type	= PERF_TYPE_HARDWARE,
13247d01e7bSRob Herring 		.config	= event,
13347d01e7bSRob Herring 	};
13447d01e7bSRob Herring 	int err, i;
13547d01e7bSRob Herring 
13647d01e7bSRob Herring 	threads = perf_thread_map__new_dummy();
13747d01e7bSRob Herring 	__T("failed to create threads", threads);
13847d01e7bSRob Herring 
13947d01e7bSRob Herring 	perf_thread_map__set_pid(threads, 0, 0);
14047d01e7bSRob Herring 
14147d01e7bSRob Herring 	evsel = perf_evsel__new(&attr);
14247d01e7bSRob Herring 	__T("failed to create evsel", evsel);
14347d01e7bSRob Herring 
14447d01e7bSRob Herring 	err = perf_evsel__open(evsel, NULL, threads);
14547d01e7bSRob Herring 	__T("failed to open evsel", err == 0);
14647d01e7bSRob Herring 
14747d01e7bSRob Herring 	err = perf_evsel__mmap(evsel, 0);
14847d01e7bSRob Herring 	__T("failed to mmap evsel", err == 0);
14947d01e7bSRob Herring 
15047d01e7bSRob Herring 	pc = perf_evsel__mmap_base(evsel, 0, 0);
151*f304c8d9SShunsuke Nakamura 	__T("failed to get mmapped address", pc);
15247d01e7bSRob Herring 
15347d01e7bSRob Herring #if defined(__i386__) || defined(__x86_64__)
15447d01e7bSRob Herring 	__T("userspace counter access not supported", pc->cap_user_rdpmc);
15547d01e7bSRob Herring 	__T("userspace counter access not enabled", pc->index);
15647d01e7bSRob Herring 	__T("userspace counter width not set", pc->pmc_width >= 32);
15747d01e7bSRob Herring #endif
15847d01e7bSRob Herring 
15947d01e7bSRob Herring 	perf_evsel__read(evsel, 0, 0, &counts);
16047d01e7bSRob Herring 	__T("failed to read value for evsel", counts.val != 0);
16147d01e7bSRob Herring 
16247d01e7bSRob Herring 	for (i = 0; i < 5; i++) {
16347d01e7bSRob Herring 		volatile int count = 0x10000 << i;
16447d01e7bSRob Herring 		__u64 start, end, last = 0;
16547d01e7bSRob Herring 
16647d01e7bSRob Herring 		__T_VERBOSE("\tloop = %u, ", count);
16747d01e7bSRob Herring 
16847d01e7bSRob Herring 		perf_evsel__read(evsel, 0, 0, &counts);
16947d01e7bSRob Herring 		start = counts.val;
17047d01e7bSRob Herring 
17147d01e7bSRob Herring 		while (count--) ;
17247d01e7bSRob Herring 
17347d01e7bSRob Herring 		perf_evsel__read(evsel, 0, 0, &counts);
17447d01e7bSRob Herring 		end = counts.val;
17547d01e7bSRob Herring 
17647d01e7bSRob Herring 		__T("invalid counter data", (end - start) > last);
17747d01e7bSRob Herring 		last = end - start;
17847d01e7bSRob Herring 		__T_VERBOSE("count = %llu\n", end - start);
17947d01e7bSRob Herring 	}
18047d01e7bSRob Herring 
18147d01e7bSRob Herring 	perf_evsel__munmap(evsel);
18247d01e7bSRob Herring 	perf_evsel__close(evsel);
18347d01e7bSRob Herring 	perf_evsel__delete(evsel);
18447d01e7bSRob Herring 
18547d01e7bSRob Herring 	perf_thread_map__put(threads);
18647d01e7bSRob Herring 	return 0;
18747d01e7bSRob Herring }
18847d01e7bSRob Herring 
1893d970601SJiri Olsa int test_evsel(int argc, char **argv)
1903ce311afSJiri Olsa {
1913ce311afSJiri Olsa 	__T_START;
1923ce311afSJiri Olsa 
1933ce311afSJiri Olsa 	libperf_init(libperf_print);
1943ce311afSJiri Olsa 
1953ce311afSJiri Olsa 	test_stat_cpu();
1963ce311afSJiri Olsa 	test_stat_thread();
1973ce311afSJiri Olsa 	test_stat_thread_enable();
19847d01e7bSRob Herring 	test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
19947d01e7bSRob Herring 	test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
2003ce311afSJiri Olsa 
2013ce311afSJiri Olsa 	__T_END;
202bba2ea17SIan Rogers 	return tests_failed == 0 ? 0 : -1;
2033ce311afSJiri Olsa }
204