xref: /openbmc/linux/tools/perf/tests/event-times.c (revision 806731a9)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2b31d660dSJiri Olsa #include <linux/compiler.h>
38520a98dSArnaldo Carvalho de Melo #include <linux/string.h>
4a43783aeSArnaldo Carvalho de Melo #include <errno.h>
5fd20e811SArnaldo Carvalho de Melo #include <inttypes.h>
6b31d660dSJiri Olsa #include <string.h>
74208735dSArnaldo Carvalho de Melo #include <sys/wait.h>
89c3516d1SJiri Olsa #include <perf/cpumap.h>
9b31d660dSJiri Olsa #include "tests.h"
10b31d660dSJiri Olsa #include "evlist.h"
11b31d660dSJiri Olsa #include "evsel.h"
12b31d660dSJiri Olsa #include "debug.h"
13f2a39fe8SArnaldo Carvalho de Melo #include "parse-events.h"
14b31d660dSJiri Olsa #include "thread_map.h"
15b31d660dSJiri Olsa #include "target.h"
16b31d660dSJiri Olsa 
attach__enable_on_exec(struct evlist * evlist)1763503dbaSJiri Olsa static int attach__enable_on_exec(struct evlist *evlist)
18b31d660dSJiri Olsa {
19515dbe48SJiri Olsa 	struct evsel *evsel = evlist__last(evlist);
20b31d660dSJiri Olsa 	struct target target = {
21b31d660dSJiri Olsa 		.uid = UINT_MAX,
22b31d660dSJiri Olsa 	};
23b31d660dSJiri Olsa 	const char *argv[] = { "true", NULL, };
24b31d660dSJiri Olsa 	char sbuf[STRERR_BUFSIZE];
25b31d660dSJiri Olsa 	int err;
26b31d660dSJiri Olsa 
27b31d660dSJiri Olsa 	pr_debug("attaching to spawned child, enable on exec\n");
28b31d660dSJiri Olsa 
297748bb71SArnaldo Carvalho de Melo 	err = evlist__create_maps(evlist, &target);
30b31d660dSJiri Olsa 	if (err < 0) {
31b31d660dSJiri Olsa 		pr_debug("Not enough memory to create thread/cpu maps\n");
32b31d660dSJiri Olsa 		return err;
33b31d660dSJiri Olsa 	}
34b31d660dSJiri Olsa 
357b392ef0SArnaldo Carvalho de Melo 	err = evlist__prepare_workload(evlist, &target, argv, false, NULL);
36b31d660dSJiri Olsa 	if (err < 0) {
37b31d660dSJiri Olsa 		pr_debug("Couldn't run the workload!\n");
38b31d660dSJiri Olsa 		return err;
39b31d660dSJiri Olsa 	}
40b31d660dSJiri Olsa 
411fc632ceSJiri Olsa 	evsel->core.attr.enable_on_exec = 1;
42b31d660dSJiri Olsa 
43474ddc4cSJiri Olsa 	err = evlist__open(evlist);
44b31d660dSJiri Olsa 	if (err < 0) {
45b31d660dSJiri Olsa 		pr_debug("perf_evlist__open: %s\n",
46c8b5f2c9SArnaldo Carvalho de Melo 			 str_error_r(errno, sbuf, sizeof(sbuf)));
47b31d660dSJiri Olsa 		return err;
48b31d660dSJiri Olsa 	}
49b31d660dSJiri Olsa 
507b392ef0SArnaldo Carvalho de Melo 	return evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL;
51b31d660dSJiri Olsa }
52b31d660dSJiri Olsa 
detach__enable_on_exec(struct evlist * evlist)5363503dbaSJiri Olsa static int detach__enable_on_exec(struct evlist *evlist)
54b31d660dSJiri Olsa {
55b31d660dSJiri Olsa 	waitpid(evlist->workload.pid, NULL, 0);
56b31d660dSJiri Olsa 	return 0;
57b31d660dSJiri Olsa }
58b31d660dSJiri Olsa 
attach__current_disabled(struct evlist * evlist)5963503dbaSJiri Olsa static int attach__current_disabled(struct evlist *evlist)
60b31d660dSJiri Olsa {
61515dbe48SJiri Olsa 	struct evsel *evsel = evlist__last(evlist);
629749b90eSJiri Olsa 	struct perf_thread_map *threads;
63b31d660dSJiri Olsa 	int err;
64b31d660dSJiri Olsa 
65b31d660dSJiri Olsa 	pr_debug("attaching to current thread as disabled\n");
66b31d660dSJiri Olsa 
67b31d660dSJiri Olsa 	threads = thread_map__new(-1, getpid(), UINT_MAX);
68b31d660dSJiri Olsa 	if (threads == NULL) {
69b31d660dSJiri Olsa 		pr_debug("thread_map__new\n");
70b31d660dSJiri Olsa 		return -1;
71b31d660dSJiri Olsa 	}
72b31d660dSJiri Olsa 
731fc632ceSJiri Olsa 	evsel->core.attr.disabled = 1;
74b31d660dSJiri Olsa 
75aa8c406bSArnaldo Carvalho de Melo 	err = evsel__open_per_thread(evsel, threads);
76b31d660dSJiri Olsa 	if (err) {
77b31d660dSJiri Olsa 		pr_debug("Failed to open event cpu-clock:u\n");
78b31d660dSJiri Olsa 		return err;
79b31d660dSJiri Olsa 	}
80b31d660dSJiri Olsa 
817836e52eSJiri Olsa 	perf_thread_map__put(threads);
82ec7f24efSJiri Olsa 	return evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL;
83b31d660dSJiri Olsa }
84b31d660dSJiri Olsa 
attach__current_enabled(struct evlist * evlist)8563503dbaSJiri Olsa static int attach__current_enabled(struct evlist *evlist)
86b31d660dSJiri Olsa {
87515dbe48SJiri Olsa 	struct evsel *evsel = evlist__last(evlist);
889749b90eSJiri Olsa 	struct perf_thread_map *threads;
89b31d660dSJiri Olsa 	int err;
90b31d660dSJiri Olsa 
91b31d660dSJiri Olsa 	pr_debug("attaching to current thread as enabled\n");
92b31d660dSJiri Olsa 
93b31d660dSJiri Olsa 	threads = thread_map__new(-1, getpid(), UINT_MAX);
94b31d660dSJiri Olsa 	if (threads == NULL) {
95b31d660dSJiri Olsa 		pr_debug("failed to call thread_map__new\n");
96b31d660dSJiri Olsa 		return -1;
97b31d660dSJiri Olsa 	}
98b31d660dSJiri Olsa 
99aa8c406bSArnaldo Carvalho de Melo 	err = evsel__open_per_thread(evsel, threads);
100b31d660dSJiri Olsa 
1017836e52eSJiri Olsa 	perf_thread_map__put(threads);
102b31d660dSJiri Olsa 	return err == 0 ? TEST_OK : TEST_FAIL;
103b31d660dSJiri Olsa }
104b31d660dSJiri Olsa 
detach__disable(struct evlist * evlist)10563503dbaSJiri Olsa static int detach__disable(struct evlist *evlist)
106b31d660dSJiri Olsa {
107515dbe48SJiri Olsa 	struct evsel *evsel = evlist__last(evlist);
108b31d660dSJiri Olsa 
109ec7f24efSJiri Olsa 	return evsel__enable(evsel);
110b31d660dSJiri Olsa }
111b31d660dSJiri Olsa 
attach__cpu_disabled(struct evlist * evlist)11263503dbaSJiri Olsa static int attach__cpu_disabled(struct evlist *evlist)
113b31d660dSJiri Olsa {
114515dbe48SJiri Olsa 	struct evsel *evsel = evlist__last(evlist);
115f854839bSJiri Olsa 	struct perf_cpu_map *cpus;
116b31d660dSJiri Olsa 	int err;
117b31d660dSJiri Olsa 
118b31d660dSJiri Olsa 	pr_debug("attaching to CPU 0 as enabled\n");
119b31d660dSJiri Olsa 
1209c3516d1SJiri Olsa 	cpus = perf_cpu_map__new("0");
121b31d660dSJiri Olsa 	if (cpus == NULL) {
1229c3516d1SJiri Olsa 		pr_debug("failed to call perf_cpu_map__new\n");
123b31d660dSJiri Olsa 		return -1;
124b31d660dSJiri Olsa 	}
125b31d660dSJiri Olsa 
1261fc632ceSJiri Olsa 	evsel->core.attr.disabled = 1;
127b31d660dSJiri Olsa 
128aa8c406bSArnaldo Carvalho de Melo 	err = evsel__open_per_cpu(evsel, cpus, -1);
129b31d660dSJiri Olsa 	if (err) {
130b31d660dSJiri Olsa 		if (err == -EACCES)
131b31d660dSJiri Olsa 			return TEST_SKIP;
132b31d660dSJiri Olsa 
133b31d660dSJiri Olsa 		pr_debug("Failed to open event cpu-clock:u\n");
134b31d660dSJiri Olsa 		return err;
135b31d660dSJiri Olsa 	}
136b31d660dSJiri Olsa 
13738f01d8dSJiri Olsa 	perf_cpu_map__put(cpus);
138ec7f24efSJiri Olsa 	return evsel__enable(evsel);
139b31d660dSJiri Olsa }
140b31d660dSJiri Olsa 
attach__cpu_enabled(struct evlist * evlist)14163503dbaSJiri Olsa static int attach__cpu_enabled(struct evlist *evlist)
142b31d660dSJiri Olsa {
143515dbe48SJiri Olsa 	struct evsel *evsel = evlist__last(evlist);
144f854839bSJiri Olsa 	struct perf_cpu_map *cpus;
145b31d660dSJiri Olsa 	int err;
146b31d660dSJiri Olsa 
147b31d660dSJiri Olsa 	pr_debug("attaching to CPU 0 as enabled\n");
148b31d660dSJiri Olsa 
1499c3516d1SJiri Olsa 	cpus = perf_cpu_map__new("0");
150b31d660dSJiri Olsa 	if (cpus == NULL) {
1519c3516d1SJiri Olsa 		pr_debug("failed to call perf_cpu_map__new\n");
152b31d660dSJiri Olsa 		return -1;
153b31d660dSJiri Olsa 	}
154b31d660dSJiri Olsa 
155aa8c406bSArnaldo Carvalho de Melo 	err = evsel__open_per_cpu(evsel, cpus, -1);
156b31d660dSJiri Olsa 	if (err == -EACCES)
157b31d660dSJiri Olsa 		return TEST_SKIP;
158b31d660dSJiri Olsa 
15938f01d8dSJiri Olsa 	perf_cpu_map__put(cpus);
160b31d660dSJiri Olsa 	return err ? TEST_FAIL : TEST_OK;
161b31d660dSJiri Olsa }
162b31d660dSJiri Olsa 
test_times(int (attach)(struct evlist *),int (detach)(struct evlist *))16363503dbaSJiri Olsa static int test_times(int (attach)(struct evlist *),
16463503dbaSJiri Olsa 		      int (detach)(struct evlist *))
165b31d660dSJiri Olsa {
166b31d660dSJiri Olsa 	struct perf_counts_values count;
16763503dbaSJiri Olsa 	struct evlist *evlist = NULL;
16832dcd021SJiri Olsa 	struct evsel *evsel;
169b31d660dSJiri Olsa 	int err = -1, i;
170b31d660dSJiri Olsa 
1710f98b11cSJiri Olsa 	evlist = evlist__new();
172b31d660dSJiri Olsa 	if (!evlist) {
173b31d660dSJiri Olsa 		pr_debug("failed to create event list\n");
174b31d660dSJiri Olsa 		goto out_err;
175b31d660dSJiri Olsa 	}
176b31d660dSJiri Olsa 
177*806731a9SAdrian Hunter 	err = parse_event(evlist, "cpu-clock:u");
178b31d660dSJiri Olsa 	if (err) {
179b31d660dSJiri Olsa 		pr_debug("failed to parse event cpu-clock:u\n");
180b31d660dSJiri Olsa 		goto out_err;
181b31d660dSJiri Olsa 	}
182b31d660dSJiri Olsa 
183515dbe48SJiri Olsa 	evsel = evlist__last(evlist);
1841fc632ceSJiri Olsa 	evsel->core.attr.read_format |=
185b31d660dSJiri Olsa 		PERF_FORMAT_TOTAL_TIME_ENABLED |
186b31d660dSJiri Olsa 		PERF_FORMAT_TOTAL_TIME_RUNNING;
187b31d660dSJiri Olsa 
188b31d660dSJiri Olsa 	err = attach(evlist);
189b31d660dSJiri Olsa 	if (err == TEST_SKIP) {
190b31d660dSJiri Olsa 		pr_debug("  SKIP  : not enough rights\n");
191b31d660dSJiri Olsa 		return err;
192b31d660dSJiri Olsa 	}
193b31d660dSJiri Olsa 
194b31d660dSJiri Olsa 	TEST_ASSERT_VAL("failed to attach", !err);
195b31d660dSJiri Olsa 
196b31d660dSJiri Olsa 	for (i = 0; i < 100000000; i++) { }
197b31d660dSJiri Olsa 
198b31d660dSJiri Olsa 	TEST_ASSERT_VAL("failed to detach", !detach(evlist));
199b31d660dSJiri Olsa 
2005c30af92SJiri Olsa 	perf_evsel__read(&evsel->core, 0, 0, &count);
201b31d660dSJiri Olsa 
202b31d660dSJiri Olsa 	err = !(count.ena == count.run);
203b31d660dSJiri Olsa 
204b31d660dSJiri Olsa 	pr_debug("  %s: ena %" PRIu64", run %" PRIu64"\n",
205b31d660dSJiri Olsa 		 !err ? "OK    " : "FAILED",
206b31d660dSJiri Olsa 		 count.ena, count.run);
207b31d660dSJiri Olsa 
208b31d660dSJiri Olsa out_err:
209c12995a5SJiri Olsa 	evlist__delete(evlist);
210b31d660dSJiri Olsa 	return !err ? TEST_OK : TEST_FAIL;
211b31d660dSJiri Olsa }
212b31d660dSJiri Olsa 
213b31d660dSJiri Olsa /*
214b31d660dSJiri Olsa  * This test creates software event 'cpu-clock'
215b31d660dSJiri Olsa  * attaches it in several ways (explained below)
216b31d660dSJiri Olsa  * and checks that enabled and running times
217b31d660dSJiri Olsa  * match.
218b31d660dSJiri Olsa  */
test__event_times(struct test_suite * test __maybe_unused,int subtest __maybe_unused)21933f44bfdSIan Rogers static int test__event_times(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
220b31d660dSJiri Olsa {
221b31d660dSJiri Olsa 	int err, ret = 0;
222b31d660dSJiri Olsa 
223b31d660dSJiri Olsa #define _T(attach, detach)			\
224b31d660dSJiri Olsa 	err = test_times(attach, detach);	\
225b31d660dSJiri Olsa 	if (err && (ret == TEST_OK || ret == TEST_SKIP))	\
226b31d660dSJiri Olsa 		ret = err;
227b31d660dSJiri Olsa 
228b31d660dSJiri Olsa 	/* attach on newly spawned process after exec */
229b31d660dSJiri Olsa 	_T(attach__enable_on_exec,   detach__enable_on_exec)
230b31d660dSJiri Olsa 	/* attach on current process as enabled */
231b31d660dSJiri Olsa 	_T(attach__current_enabled,  detach__disable)
232b31d660dSJiri Olsa 	/* attach on current process as disabled */
233b31d660dSJiri Olsa 	_T(attach__current_disabled, detach__disable)
234b31d660dSJiri Olsa 	/* attach on cpu as disabled */
235b31d660dSJiri Olsa 	_T(attach__cpu_disabled,     detach__disable)
236b31d660dSJiri Olsa 	/* attach on cpu as enabled */
237b31d660dSJiri Olsa 	_T(attach__cpu_enabled,      detach__disable)
238b31d660dSJiri Olsa 
239b31d660dSJiri Olsa #undef _T
240b31d660dSJiri Olsa 	return ret;
241b31d660dSJiri Olsa }
242d68f0365SIan Rogers 
243d68f0365SIan Rogers DEFINE_SUITE("Event times", event_times);
244