1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2a43783aeSArnaldo Carvalho de Melo #include <errno.h>
3fd20e811SArnaldo Carvalho de Melo #include <inttypes.h>
4bc96b361SNamhyung Kim #include <unistd.h>
5bc96b361SNamhyung Kim #include <stdlib.h>
6bc96b361SNamhyung Kim #include <signal.h>
7bc96b361SNamhyung Kim #include <sys/mman.h>
8b4209025SArnaldo Carvalho de Melo #include <linux/string.h>
9bc96b361SNamhyung Kim
10bc96b361SNamhyung Kim #include "tests.h"
11b4209025SArnaldo Carvalho de Melo #include "util/debug.h"
12bc96b361SNamhyung Kim #include "util/evsel.h"
13bc96b361SNamhyung Kim #include "util/evlist.h"
14bc96b361SNamhyung Kim #include "util/cpumap.h"
15e0fcfb08SArnaldo Carvalho de Melo #include "util/mmap.h"
169823147dSArnaldo Carvalho de Melo #include "util/sample.h"
17bc96b361SNamhyung Kim #include "util/thread_map.h"
18453fa030SJiri Olsa #include <perf/evlist.h>
197728fa0cSJiri Olsa #include <perf/mmap.h>
20bc96b361SNamhyung Kim
213fe21305SAdrian Hunter #define NR_LOOPS 10000000
22bc96b361SNamhyung Kim
23bc96b361SNamhyung Kim /*
24bc96b361SNamhyung Kim * This test will open software clock events (cpu-clock, task-clock)
25bc96b361SNamhyung Kim * then check their frequency -> period conversion has no artifact of
26bc96b361SNamhyung Kim * setting period to 1 forcefully.
27bc96b361SNamhyung Kim */
__test__sw_clock_freq(enum perf_sw_ids clock_id)28bc96b361SNamhyung Kim static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
29bc96b361SNamhyung Kim {
30bc96b361SNamhyung Kim int i, err = -1;
31bc96b361SNamhyung Kim volatile int tmp = 0;
32bc96b361SNamhyung Kim u64 total_periods = 0;
33bc96b361SNamhyung Kim int nr_samples = 0;
34ba3dfff8SMasami Hiramatsu char sbuf[STRERR_BUFSIZE];
35bc96b361SNamhyung Kim union perf_event *event;
3632dcd021SJiri Olsa struct evsel *evsel;
3763503dbaSJiri Olsa struct evlist *evlist;
38bc96b361SNamhyung Kim struct perf_event_attr attr = {
39bc96b361SNamhyung Kim .type = PERF_TYPE_SOFTWARE,
40bc96b361SNamhyung Kim .config = clock_id,
41bc96b361SNamhyung Kim .sample_type = PERF_SAMPLE_PERIOD,
42bc96b361SNamhyung Kim .exclude_kernel = 1,
43bc96b361SNamhyung Kim .disabled = 1,
44bc96b361SNamhyung Kim .freq = 1,
45bc96b361SNamhyung Kim };
4697ab7c52SNamhyung Kim struct perf_cpu_map *cpus = NULL;
4797ab7c52SNamhyung Kim struct perf_thread_map *threads = NULL;
48a5830532SJiri Olsa struct mmap *md;
49bc96b361SNamhyung Kim
5067c1e4a5SArnaldo Carvalho de Melo attr.sample_freq = 500;
51bc96b361SNamhyung Kim
520f98b11cSJiri Olsa evlist = evlist__new();
53bc96b361SNamhyung Kim if (evlist == NULL) {
540f98b11cSJiri Olsa pr_debug("evlist__new\n");
55bc96b361SNamhyung Kim return -1;
56bc96b361SNamhyung Kim }
57bc96b361SNamhyung Kim
58365c3ae7SJiri Olsa evsel = evsel__new(&attr);
59bc96b361SNamhyung Kim if (evsel == NULL) {
608f6725a2SArnaldo Carvalho de Melo pr_debug("evsel__new\n");
6103ad9747SArnaldo Carvalho de Melo goto out_delete_evlist;
62bc96b361SNamhyung Kim }
63a1cf3a75SJiri Olsa evlist__add(evlist, evsel);
64bc96b361SNamhyung Kim
65*48219b08SIan Rogers cpus = perf_cpu_map__new_any_cpu();
66c5e6bd2eSAdrian Hunter threads = thread_map__new_by_tid(getpid());
67c5e6bd2eSAdrian Hunter if (!cpus || !threads) {
68bc96b361SNamhyung Kim err = -ENOMEM;
69bc96b361SNamhyung Kim pr_debug("Not enough memory to create thread/cpu maps\n");
7097ab7c52SNamhyung Kim goto out_delete_evlist;
71bc96b361SNamhyung Kim }
72bc96b361SNamhyung Kim
73453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads);
74c5e6bd2eSAdrian Hunter
75474ddc4cSJiri Olsa if (evlist__open(evlist)) {
7667c1e4a5SArnaldo Carvalho de Melo const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
7767c1e4a5SArnaldo Carvalho de Melo
78d0b849e9SArnaldo Carvalho de Melo err = -errno;
7967c1e4a5SArnaldo Carvalho de Melo pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
80c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, sbuf, sizeof(sbuf)),
81ba3dfff8SMasami Hiramatsu knob, (u64)attr.sample_freq);
8203ad9747SArnaldo Carvalho de Melo goto out_delete_evlist;
83d0b849e9SArnaldo Carvalho de Melo }
84bc96b361SNamhyung Kim
859521b5f2SJiri Olsa err = evlist__mmap(evlist, 128);
86bc96b361SNamhyung Kim if (err < 0) {
87bc96b361SNamhyung Kim pr_debug("failed to mmap event: %d (%s)\n", errno,
88c8b5f2c9SArnaldo Carvalho de Melo str_error_r(errno, sbuf, sizeof(sbuf)));
89f26e1c7cSArnaldo Carvalho de Melo goto out_delete_evlist;
90bc96b361SNamhyung Kim }
91bc96b361SNamhyung Kim
921c87f165SJiri Olsa evlist__enable(evlist);
93bc96b361SNamhyung Kim
94bc96b361SNamhyung Kim /* collect samples */
95bc96b361SNamhyung Kim for (i = 0; i < NR_LOOPS; i++)
96bc96b361SNamhyung Kim tmp++;
97bc96b361SNamhyung Kim
98e74676deSJiri Olsa evlist__disable(evlist);
99bc96b361SNamhyung Kim
1005d0007cdSKan Liang md = &evlist->mmap[0];
1017c4d4182SJiri Olsa if (perf_mmap__read_init(&md->core) < 0)
1025d0007cdSKan Liang goto out_init;
1035d0007cdSKan Liang
104151ed5d7SJiri Olsa while ((event = perf_mmap__read_event(&md->core)) != NULL) {
105bc96b361SNamhyung Kim struct perf_sample sample;
106bc96b361SNamhyung Kim
107bc96b361SNamhyung Kim if (event->header.type != PERF_RECORD_SAMPLE)
1088e50d384SZhouyi Zhou goto next_event;
109bc96b361SNamhyung Kim
1102a6599cdSArnaldo Carvalho de Melo err = evlist__parse_sample(evlist, event, &sample);
111bc96b361SNamhyung Kim if (err < 0) {
112bc96b361SNamhyung Kim pr_debug("Error during parse sample\n");
113983874d1SArnaldo Carvalho de Melo goto out_delete_evlist;
114bc96b361SNamhyung Kim }
115bc96b361SNamhyung Kim
116bc96b361SNamhyung Kim total_periods += sample.period;
117bc96b361SNamhyung Kim nr_samples++;
1188e50d384SZhouyi Zhou next_event:
1197728fa0cSJiri Olsa perf_mmap__consume(&md->core);
120bc96b361SNamhyung Kim }
12132fdc2caSJiri Olsa perf_mmap__read_done(&md->core);
122bc96b361SNamhyung Kim
1235d0007cdSKan Liang out_init:
124bc96b361SNamhyung Kim if ((u64) nr_samples == total_periods) {
125bc96b361SNamhyung Kim pr_debug("All (%d) samples have period value of 1!\n",
126bc96b361SNamhyung Kim nr_samples);
127bc96b361SNamhyung Kim err = -1;
128bc96b361SNamhyung Kim }
129bc96b361SNamhyung Kim
13097ab7c52SNamhyung Kim out_delete_evlist:
13138f01d8dSJiri Olsa perf_cpu_map__put(cpus);
1327836e52eSJiri Olsa perf_thread_map__put(threads);
133c12995a5SJiri Olsa evlist__delete(evlist);
134bc96b361SNamhyung Kim return err;
135bc96b361SNamhyung Kim }
136bc96b361SNamhyung Kim
test__sw_clock_freq(struct test_suite * test __maybe_unused,int subtest __maybe_unused)13733f44bfdSIan Rogers static int test__sw_clock_freq(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
138bc96b361SNamhyung Kim {
139bc96b361SNamhyung Kim int ret;
140bc96b361SNamhyung Kim
141bc96b361SNamhyung Kim ret = __test__sw_clock_freq(PERF_COUNT_SW_CPU_CLOCK);
142bc96b361SNamhyung Kim if (!ret)
143bc96b361SNamhyung Kim ret = __test__sw_clock_freq(PERF_COUNT_SW_TASK_CLOCK);
144bc96b361SNamhyung Kim
145bc96b361SNamhyung Kim return ret;
146bc96b361SNamhyung Kim }
147d68f0365SIan Rogers
148d68f0365SIan Rogers DEFINE_SUITE("Software clock events period values", sw_clock_freq);
149