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