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