13ce311afSJiri Olsa // SPDX-License-Identifier: GPL-2.0
23ce311afSJiri Olsa #include <stdarg.h>
33ce311afSJiri Olsa #include <stdio.h>
46d395a51SNamhyung Kim #include <string.h>
53ce311afSJiri Olsa #include <linux/perf_event.h>
66d395a51SNamhyung Kim #include <linux/kernel.h>
73ce311afSJiri Olsa #include <perf/cpumap.h>
83ce311afSJiri Olsa #include <perf/threadmap.h>
93ce311afSJiri Olsa #include <perf/evsel.h>
106d395a51SNamhyung Kim #include <internal/evsel.h>
113ce311afSJiri Olsa #include <internal/tests.h>
123d970601SJiri Olsa #include "tests.h"
133ce311afSJiri Olsa
libperf_print(enum libperf_print_level level,const char * fmt,va_list ap)143ce311afSJiri Olsa static int libperf_print(enum libperf_print_level level,
153ce311afSJiri Olsa const char *fmt, va_list ap)
163ce311afSJiri Olsa {
173ce311afSJiri Olsa return vfprintf(stderr, fmt, ap);
183ce311afSJiri Olsa }
193ce311afSJiri Olsa
test_stat_cpu(void)203ce311afSJiri Olsa static int test_stat_cpu(void)
213ce311afSJiri Olsa {
223ce311afSJiri Olsa struct perf_cpu_map *cpus;
233ce311afSJiri Olsa struct perf_evsel *evsel;
243ce311afSJiri Olsa struct perf_event_attr attr = {
253ce311afSJiri Olsa .type = PERF_TYPE_SOFTWARE,
263ce311afSJiri Olsa .config = PERF_COUNT_SW_CPU_CLOCK,
273ce311afSJiri Olsa };
283ff6d64eSShunsuke Nakamura int err, idx;
293ce311afSJiri Olsa
30*effe957cSIan Rogers cpus = perf_cpu_map__new_online_cpus();
313ce311afSJiri Olsa __T("failed to create cpus", cpus);
323ce311afSJiri Olsa
333ce311afSJiri Olsa evsel = perf_evsel__new(&attr);
343ce311afSJiri Olsa __T("failed to create evsel", evsel);
353ce311afSJiri Olsa
363ce311afSJiri Olsa err = perf_evsel__open(evsel, cpus, NULL);
373ce311afSJiri Olsa __T("failed to open evsel", err == 0);
383ce311afSJiri Olsa
393ff6d64eSShunsuke Nakamura for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
403ce311afSJiri Olsa struct perf_counts_values counts = { .val = 0 };
413ce311afSJiri Olsa
423ff6d64eSShunsuke Nakamura perf_evsel__read(evsel, idx, 0, &counts);
433ce311afSJiri Olsa __T("failed to read value for evsel", counts.val != 0);
443ce311afSJiri Olsa }
453ce311afSJiri Olsa
463ce311afSJiri Olsa perf_evsel__close(evsel);
473ce311afSJiri Olsa perf_evsel__delete(evsel);
483ce311afSJiri Olsa
493ce311afSJiri Olsa perf_cpu_map__put(cpus);
503ce311afSJiri Olsa return 0;
513ce311afSJiri Olsa }
523ce311afSJiri Olsa
test_stat_thread(void)533ce311afSJiri Olsa static int test_stat_thread(void)
543ce311afSJiri Olsa {
553ce311afSJiri Olsa struct perf_counts_values counts = { .val = 0 };
563ce311afSJiri Olsa struct perf_thread_map *threads;
573ce311afSJiri Olsa struct perf_evsel *evsel;
583ce311afSJiri Olsa struct perf_event_attr attr = {
593ce311afSJiri Olsa .type = PERF_TYPE_SOFTWARE,
603ce311afSJiri Olsa .config = PERF_COUNT_SW_TASK_CLOCK,
613ce311afSJiri Olsa };
623ce311afSJiri Olsa int err;
633ce311afSJiri Olsa
643ce311afSJiri Olsa threads = perf_thread_map__new_dummy();
653ce311afSJiri Olsa __T("failed to create threads", threads);
663ce311afSJiri Olsa
673ce311afSJiri Olsa perf_thread_map__set_pid(threads, 0, 0);
683ce311afSJiri Olsa
693ce311afSJiri Olsa evsel = perf_evsel__new(&attr);
703ce311afSJiri Olsa __T("failed to create evsel", evsel);
713ce311afSJiri Olsa
723ce311afSJiri Olsa err = perf_evsel__open(evsel, NULL, threads);
733ce311afSJiri Olsa __T("failed to open evsel", err == 0);
743ce311afSJiri Olsa
753ce311afSJiri Olsa perf_evsel__read(evsel, 0, 0, &counts);
763ce311afSJiri Olsa __T("failed to read value for evsel", counts.val != 0);
773ce311afSJiri Olsa
783ce311afSJiri Olsa perf_evsel__close(evsel);
793ce311afSJiri Olsa perf_evsel__delete(evsel);
803ce311afSJiri Olsa
813ce311afSJiri Olsa perf_thread_map__put(threads);
823ce311afSJiri Olsa return 0;
833ce311afSJiri Olsa }
843ce311afSJiri Olsa
test_stat_thread_enable(void)853ce311afSJiri Olsa static int test_stat_thread_enable(void)
863ce311afSJiri Olsa {
873ce311afSJiri Olsa struct perf_counts_values counts = { .val = 0 };
883ce311afSJiri Olsa struct perf_thread_map *threads;
893ce311afSJiri Olsa struct perf_evsel *evsel;
903ce311afSJiri Olsa struct perf_event_attr attr = {
913ce311afSJiri Olsa .type = PERF_TYPE_SOFTWARE,
923ce311afSJiri Olsa .config = PERF_COUNT_SW_TASK_CLOCK,
933ce311afSJiri Olsa .disabled = 1,
943ce311afSJiri Olsa };
953ce311afSJiri Olsa int err;
963ce311afSJiri Olsa
973ce311afSJiri Olsa threads = perf_thread_map__new_dummy();
983ce311afSJiri Olsa __T("failed to create threads", threads);
993ce311afSJiri Olsa
1003ce311afSJiri Olsa perf_thread_map__set_pid(threads, 0, 0);
1013ce311afSJiri Olsa
1023ce311afSJiri Olsa evsel = perf_evsel__new(&attr);
1033ce311afSJiri Olsa __T("failed to create evsel", evsel);
1043ce311afSJiri Olsa
1053ce311afSJiri Olsa err = perf_evsel__open(evsel, NULL, threads);
1063ce311afSJiri Olsa __T("failed to open evsel", err == 0);
1073ce311afSJiri Olsa
1083ce311afSJiri Olsa perf_evsel__read(evsel, 0, 0, &counts);
1093ce311afSJiri Olsa __T("failed to read value for evsel", counts.val == 0);
1103ce311afSJiri Olsa
1113ce311afSJiri Olsa err = perf_evsel__enable(evsel);
1123ce311afSJiri Olsa __T("failed to enable evsel", err == 0);
1133ce311afSJiri Olsa
1143ce311afSJiri Olsa perf_evsel__read(evsel, 0, 0, &counts);
1153ce311afSJiri Olsa __T("failed to read value for evsel", counts.val != 0);
1163ce311afSJiri Olsa
1173ce311afSJiri Olsa err = perf_evsel__disable(evsel);
1183ce311afSJiri Olsa __T("failed to enable evsel", err == 0);
1193ce311afSJiri Olsa
1203ce311afSJiri Olsa perf_evsel__close(evsel);
1213ce311afSJiri Olsa perf_evsel__delete(evsel);
1223ce311afSJiri Olsa
1233ce311afSJiri Olsa perf_thread_map__put(threads);
1243ce311afSJiri Olsa return 0;
1253ce311afSJiri Olsa }
1263ce311afSJiri Olsa
test_stat_user_read(int event)12747d01e7bSRob Herring static int test_stat_user_read(int event)
12847d01e7bSRob Herring {
12947d01e7bSRob Herring struct perf_counts_values counts = { .val = 0 };
13047d01e7bSRob Herring struct perf_thread_map *threads;
13147d01e7bSRob Herring struct perf_evsel *evsel;
13247d01e7bSRob Herring struct perf_event_mmap_page *pc;
13347d01e7bSRob Herring struct perf_event_attr attr = {
13447d01e7bSRob Herring .type = PERF_TYPE_HARDWARE,
13547d01e7bSRob Herring .config = event,
136407eb43aSRob Herring #ifdef __aarch64__
137407eb43aSRob Herring .config1 = 0x2, /* Request user access */
138407eb43aSRob Herring #endif
13947d01e7bSRob Herring };
14047d01e7bSRob Herring int err, i;
14147d01e7bSRob Herring
14247d01e7bSRob Herring threads = perf_thread_map__new_dummy();
14347d01e7bSRob Herring __T("failed to create threads", threads);
14447d01e7bSRob Herring
14547d01e7bSRob Herring perf_thread_map__set_pid(threads, 0, 0);
14647d01e7bSRob Herring
14747d01e7bSRob Herring evsel = perf_evsel__new(&attr);
14847d01e7bSRob Herring __T("failed to create evsel", evsel);
14947d01e7bSRob Herring
15047d01e7bSRob Herring err = perf_evsel__open(evsel, NULL, threads);
15147d01e7bSRob Herring __T("failed to open evsel", err == 0);
15247d01e7bSRob Herring
15347d01e7bSRob Herring err = perf_evsel__mmap(evsel, 0);
15447d01e7bSRob Herring __T("failed to mmap evsel", err == 0);
15547d01e7bSRob Herring
15647d01e7bSRob Herring pc = perf_evsel__mmap_base(evsel, 0, 0);
157f304c8d9SShunsuke Nakamura __T("failed to get mmapped address", pc);
15847d01e7bSRob Herring
159407eb43aSRob Herring #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
16047d01e7bSRob Herring __T("userspace counter access not supported", pc->cap_user_rdpmc);
16147d01e7bSRob Herring __T("userspace counter access not enabled", pc->index);
16247d01e7bSRob Herring __T("userspace counter width not set", pc->pmc_width >= 32);
16347d01e7bSRob Herring #endif
16447d01e7bSRob Herring
16547d01e7bSRob Herring perf_evsel__read(evsel, 0, 0, &counts);
16647d01e7bSRob Herring __T("failed to read value for evsel", counts.val != 0);
16747d01e7bSRob Herring
16847d01e7bSRob Herring for (i = 0; i < 5; i++) {
16947d01e7bSRob Herring volatile int count = 0x10000 << i;
17047d01e7bSRob Herring __u64 start, end, last = 0;
17147d01e7bSRob Herring
17247d01e7bSRob Herring __T_VERBOSE("\tloop = %u, ", count);
17347d01e7bSRob Herring
17447d01e7bSRob Herring perf_evsel__read(evsel, 0, 0, &counts);
17547d01e7bSRob Herring start = counts.val;
17647d01e7bSRob Herring
17747d01e7bSRob Herring while (count--) ;
17847d01e7bSRob Herring
17947d01e7bSRob Herring perf_evsel__read(evsel, 0, 0, &counts);
18047d01e7bSRob Herring end = counts.val;
18147d01e7bSRob Herring
18247d01e7bSRob Herring __T("invalid counter data", (end - start) > last);
18347d01e7bSRob Herring last = end - start;
18447d01e7bSRob Herring __T_VERBOSE("count = %llu\n", end - start);
18547d01e7bSRob Herring }
18647d01e7bSRob Herring
18747d01e7bSRob Herring perf_evsel__munmap(evsel);
18847d01e7bSRob Herring perf_evsel__close(evsel);
18947d01e7bSRob Herring perf_evsel__delete(evsel);
19047d01e7bSRob Herring
19147d01e7bSRob Herring perf_thread_map__put(threads);
19247d01e7bSRob Herring return 0;
19347d01e7bSRob Herring }
19447d01e7bSRob Herring
test_stat_read_format_single(struct perf_event_attr * attr,struct perf_thread_map * threads)1956d395a51SNamhyung Kim static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)
1966d395a51SNamhyung Kim {
1976d395a51SNamhyung Kim struct perf_evsel *evsel;
1986d395a51SNamhyung Kim struct perf_counts_values counts;
1996d395a51SNamhyung Kim volatile int count = 0x100000;
2006d395a51SNamhyung Kim int err;
2016d395a51SNamhyung Kim
2026d395a51SNamhyung Kim evsel = perf_evsel__new(attr);
2036d395a51SNamhyung Kim __T("failed to create evsel", evsel);
2046d395a51SNamhyung Kim
2056d395a51SNamhyung Kim /* skip old kernels that don't support the format */
2066d395a51SNamhyung Kim err = perf_evsel__open(evsel, NULL, threads);
2076d395a51SNamhyung Kim if (err < 0)
2086d395a51SNamhyung Kim return 0;
2096d395a51SNamhyung Kim
2106d395a51SNamhyung Kim while (count--) ;
2116d395a51SNamhyung Kim
2126d395a51SNamhyung Kim memset(&counts, -1, sizeof(counts));
2136d395a51SNamhyung Kim perf_evsel__read(evsel, 0, 0, &counts);
2146d395a51SNamhyung Kim
2156d395a51SNamhyung Kim __T("failed to read value", counts.val);
2166d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
2176d395a51SNamhyung Kim __T("failed to read TOTAL_TIME_ENABLED", counts.ena);
2186d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
2196d395a51SNamhyung Kim __T("failed to read TOTAL_TIME_RUNNING", counts.run);
2206d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_ID)
2216d395a51SNamhyung Kim __T("failed to read ID", counts.id);
2226d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_LOST)
2236d395a51SNamhyung Kim __T("failed to read LOST", counts.lost == 0);
2246d395a51SNamhyung Kim
2256d395a51SNamhyung Kim perf_evsel__close(evsel);
2266d395a51SNamhyung Kim perf_evsel__delete(evsel);
2276d395a51SNamhyung Kim return 0;
2286d395a51SNamhyung Kim }
2296d395a51SNamhyung Kim
test_stat_read_format_group(struct perf_event_attr * attr,struct perf_thread_map * threads)2306d395a51SNamhyung Kim static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)
2316d395a51SNamhyung Kim {
2326d395a51SNamhyung Kim struct perf_evsel *leader, *member;
2336d395a51SNamhyung Kim struct perf_counts_values counts;
2346d395a51SNamhyung Kim volatile int count = 0x100000;
2356d395a51SNamhyung Kim int err;
2366d395a51SNamhyung Kim
2376d395a51SNamhyung Kim attr->read_format |= PERF_FORMAT_GROUP;
2386d395a51SNamhyung Kim leader = perf_evsel__new(attr);
2396d395a51SNamhyung Kim __T("failed to create leader", leader);
2406d395a51SNamhyung Kim
2416d395a51SNamhyung Kim attr->read_format &= ~PERF_FORMAT_GROUP;
2426d395a51SNamhyung Kim member = perf_evsel__new(attr);
2436d395a51SNamhyung Kim __T("failed to create member", member);
2446d395a51SNamhyung Kim
2456d395a51SNamhyung Kim member->leader = leader;
2466d395a51SNamhyung Kim leader->nr_members = 2;
2476d395a51SNamhyung Kim
2486d395a51SNamhyung Kim /* skip old kernels that don't support the format */
2496d395a51SNamhyung Kim err = perf_evsel__open(leader, NULL, threads);
2506d395a51SNamhyung Kim if (err < 0)
2516d395a51SNamhyung Kim return 0;
2526d395a51SNamhyung Kim err = perf_evsel__open(member, NULL, threads);
2536d395a51SNamhyung Kim if (err < 0)
2546d395a51SNamhyung Kim return 0;
2556d395a51SNamhyung Kim
2566d395a51SNamhyung Kim while (count--) ;
2576d395a51SNamhyung Kim
2586d395a51SNamhyung Kim memset(&counts, -1, sizeof(counts));
2596d395a51SNamhyung Kim perf_evsel__read(leader, 0, 0, &counts);
2606d395a51SNamhyung Kim
2616d395a51SNamhyung Kim __T("failed to read leader value", counts.val);
2626d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
2636d395a51SNamhyung Kim __T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);
2646d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
2656d395a51SNamhyung Kim __T("failed to read leader TOTAL_TIME_RUNNING", counts.run);
2666d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_ID)
2676d395a51SNamhyung Kim __T("failed to read leader ID", counts.id);
2686d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_LOST)
2696d395a51SNamhyung Kim __T("failed to read leader LOST", counts.lost == 0);
2706d395a51SNamhyung Kim
2716d395a51SNamhyung Kim memset(&counts, -1, sizeof(counts));
2726d395a51SNamhyung Kim perf_evsel__read(member, 0, 0, &counts);
2736d395a51SNamhyung Kim
2746d395a51SNamhyung Kim __T("failed to read member value", counts.val);
2756d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
2766d395a51SNamhyung Kim __T("failed to read member TOTAL_TIME_ENABLED", counts.ena);
2776d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
2786d395a51SNamhyung Kim __T("failed to read member TOTAL_TIME_RUNNING", counts.run);
2796d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_ID)
2806d395a51SNamhyung Kim __T("failed to read member ID", counts.id);
2816d395a51SNamhyung Kim if (attr->read_format & PERF_FORMAT_LOST)
2826d395a51SNamhyung Kim __T("failed to read member LOST", counts.lost == 0);
2836d395a51SNamhyung Kim
2846d395a51SNamhyung Kim perf_evsel__close(member);
2856d395a51SNamhyung Kim perf_evsel__close(leader);
2866d395a51SNamhyung Kim perf_evsel__delete(member);
2876d395a51SNamhyung Kim perf_evsel__delete(leader);
2886d395a51SNamhyung Kim return 0;
2896d395a51SNamhyung Kim }
2906d395a51SNamhyung Kim
test_stat_read_format(void)2916d395a51SNamhyung Kim static int test_stat_read_format(void)
2926d395a51SNamhyung Kim {
2936d395a51SNamhyung Kim struct perf_thread_map *threads;
2946d395a51SNamhyung Kim struct perf_event_attr attr = {
2956d395a51SNamhyung Kim .type = PERF_TYPE_SOFTWARE,
2966d395a51SNamhyung Kim .config = PERF_COUNT_SW_TASK_CLOCK,
2976d395a51SNamhyung Kim };
2986d395a51SNamhyung Kim int err, i;
2996d395a51SNamhyung Kim
3006d395a51SNamhyung Kim #define FMT(_fmt) PERF_FORMAT_ ## _fmt
3016d395a51SNamhyung Kim #define FMT_TIME (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
3026d395a51SNamhyung Kim
3036d395a51SNamhyung Kim uint64_t test_formats [] = {
3046d395a51SNamhyung Kim 0,
3056d395a51SNamhyung Kim FMT_TIME,
3066d395a51SNamhyung Kim FMT(ID),
3076d395a51SNamhyung Kim FMT(LOST),
3086d395a51SNamhyung Kim FMT_TIME | FMT(ID),
3096d395a51SNamhyung Kim FMT_TIME | FMT(LOST),
3106d395a51SNamhyung Kim FMT_TIME | FMT(ID) | FMT(LOST),
3116d395a51SNamhyung Kim FMT(ID) | FMT(LOST),
3126d395a51SNamhyung Kim };
3136d395a51SNamhyung Kim
3146d395a51SNamhyung Kim #undef FMT
3156d395a51SNamhyung Kim #undef FMT_TIME
3166d395a51SNamhyung Kim
3176d395a51SNamhyung Kim threads = perf_thread_map__new_dummy();
3186d395a51SNamhyung Kim __T("failed to create threads", threads);
3196d395a51SNamhyung Kim
3206d395a51SNamhyung Kim perf_thread_map__set_pid(threads, 0, 0);
3216d395a51SNamhyung Kim
3226d395a51SNamhyung Kim for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
3236d395a51SNamhyung Kim attr.read_format = test_formats[i];
3246d395a51SNamhyung Kim __T_VERBOSE("testing single read with read_format: %lx\n",
3256d395a51SNamhyung Kim (unsigned long)test_formats[i]);
3266d395a51SNamhyung Kim
3276d395a51SNamhyung Kim err = test_stat_read_format_single(&attr, threads);
3286d395a51SNamhyung Kim __T("failed to read single format", err == 0);
3296d395a51SNamhyung Kim }
3306d395a51SNamhyung Kim
3316d395a51SNamhyung Kim perf_thread_map__put(threads);
3326d395a51SNamhyung Kim
3336d395a51SNamhyung Kim threads = perf_thread_map__new_array(2, NULL);
3346d395a51SNamhyung Kim __T("failed to create threads", threads);
3356d395a51SNamhyung Kim
3366d395a51SNamhyung Kim perf_thread_map__set_pid(threads, 0, 0);
3376d395a51SNamhyung Kim perf_thread_map__set_pid(threads, 1, 0);
3386d395a51SNamhyung Kim
3396d395a51SNamhyung Kim for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
3406d395a51SNamhyung Kim attr.read_format = test_formats[i];
3416d395a51SNamhyung Kim __T_VERBOSE("testing group read with read_format: %lx\n",
3426d395a51SNamhyung Kim (unsigned long)test_formats[i]);
3436d395a51SNamhyung Kim
3446d395a51SNamhyung Kim err = test_stat_read_format_group(&attr, threads);
3456d395a51SNamhyung Kim __T("failed to read group format", err == 0);
3466d395a51SNamhyung Kim }
3476d395a51SNamhyung Kim
3486d395a51SNamhyung Kim perf_thread_map__put(threads);
3496d395a51SNamhyung Kim return 0;
3506d395a51SNamhyung Kim }
3516d395a51SNamhyung Kim
test_evsel(int argc,char ** argv)3523d970601SJiri Olsa int test_evsel(int argc, char **argv)
3533ce311afSJiri Olsa {
3543ce311afSJiri Olsa __T_START;
3553ce311afSJiri Olsa
3563ce311afSJiri Olsa libperf_init(libperf_print);
3573ce311afSJiri Olsa
3583ce311afSJiri Olsa test_stat_cpu();
3593ce311afSJiri Olsa test_stat_thread();
3603ce311afSJiri Olsa test_stat_thread_enable();
36147d01e7bSRob Herring test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
36247d01e7bSRob Herring test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
3636d395a51SNamhyung Kim test_stat_read_format();
3643ce311afSJiri Olsa
3653ce311afSJiri Olsa __T_END;
366bba2ea17SIan Rogers return tests_failed == 0 ? 0 : -1;
3673ce311afSJiri Olsa }
368