xref: /linux/tools/perf/tests/sw-clock.c (revision 48219b08)
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