aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/tests')
-rw-r--r--tools/perf/tests/attr.c9
-rw-r--r--tools/perf/tests/attr.py5
-rw-r--r--tools/perf/tests/attr/base-record1
-rw-r--r--tools/perf/tests/attr/base-stat1
-rw-r--r--tools/perf/tests/attr/test-record-C013
-rw-r--r--tools/perf/tests/attr/test-stat-C09
-rw-r--r--tools/perf/tests/bp_signal.c186
-rw-r--r--tools/perf/tests/bp_signal_overflow.c126
-rw-r--r--tools/perf/tests/builtin-test.c16
-rw-r--r--tools/perf/tests/evsel-roundtrip-name.c4
-rw-r--r--tools/perf/tests/hists_link.c2
-rw-r--r--tools/perf/tests/mmap-basic.c4
-rw-r--r--tools/perf/tests/open-syscall-tp-fields.c10
-rw-r--r--tools/perf/tests/parse-events.c4
-rw-r--r--tools/perf/tests/perf-record.c9
-rw-r--r--tools/perf/tests/sw-clock.c119
-rw-r--r--tools/perf/tests/task-exit.c123
-rw-r--r--tools/perf/tests/tests.h4
18 files changed, 629 insertions, 16 deletions
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index bdcceb886f77..038de3ecb8cb 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -147,10 +147,15 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
147 147
148static int run_dir(const char *d, const char *perf) 148static int run_dir(const char *d, const char *perf)
149{ 149{
150 char v[] = "-vvvvv";
151 int vcnt = min(verbose, (int) sizeof(v) - 1);
150 char cmd[3*PATH_MAX]; 152 char cmd[3*PATH_MAX];
151 153
152 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %s", 154 if (verbose)
153 d, d, perf, verbose ? "-v" : ""); 155 vcnt++;
156
157 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s",
158 d, d, perf, vcnt, v);
154 159
155 return system(cmd); 160 return system(cmd);
156} 161}
diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py
index 2f629ca485bc..c9b4b6269b51 100644
--- a/tools/perf/tests/attr.py
+++ b/tools/perf/tests/attr.py
@@ -24,6 +24,7 @@ class Unsup(Exception):
24 24
25class Event(dict): 25class Event(dict):
26 terms = [ 26 terms = [
27 'cpu',
27 'flags', 28 'flags',
28 'type', 29 'type',
29 'size', 30 'size',
@@ -121,7 +122,7 @@ class Test(object):
121 parser = ConfigParser.SafeConfigParser() 122 parser = ConfigParser.SafeConfigParser()
122 parser.read(path) 123 parser.read(path)
123 124
124 log.debug("running '%s'" % path) 125 log.warning("running '%s'" % path)
125 126
126 self.path = path 127 self.path = path
127 self.test_dir = options.test_dir 128 self.test_dir = options.test_dir
@@ -172,7 +173,7 @@ class Test(object):
172 self.perf, self.command, tempdir, self.args) 173 self.perf, self.command, tempdir, self.args)
173 ret = os.WEXITSTATUS(os.system(cmd)) 174 ret = os.WEXITSTATUS(os.system(cmd))
174 175
175 log.warning(" running '%s' ret %d " % (cmd, ret)) 176 log.info(" '%s' ret %d " % (cmd, ret))
176 177
177 if ret != int(self.ret): 178 if ret != int(self.ret):
178 raise Unsup(self) 179 raise Unsup(self)
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
index 5bc3880f7be5..b4fc835de607 100644
--- a/tools/perf/tests/attr/base-record
+++ b/tools/perf/tests/attr/base-record
@@ -2,6 +2,7 @@
2fd=1 2fd=1
3group_fd=-1 3group_fd=-1
4flags=0 4flags=0
5cpu=*
5type=0|1 6type=0|1
6size=96 7size=96
7config=0 8config=0
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat
index 4bd79a82784f..748ee949a204 100644
--- a/tools/perf/tests/attr/base-stat
+++ b/tools/perf/tests/attr/base-stat
@@ -2,6 +2,7 @@
2fd=1 2fd=1
3group_fd=-1 3group_fd=-1
4flags=0 4flags=0
5cpu=*
5type=0 6type=0
6size=96 7size=96
7config=0 8config=0
diff --git a/tools/perf/tests/attr/test-record-C0 b/tools/perf/tests/attr/test-record-C0
new file mode 100644
index 000000000000..d6a7e43f61b3
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-C0
@@ -0,0 +1,13 @@
1[config]
2command = record
3args = -C 0 kill >/dev/null 2>&1
4
5[event:base-record]
6cpu=0
7
8# no enable on exec for CPU attached
9enable_on_exec=0
10
11# PERF_SAMPLE_IP | PERF_SAMPLE_TID PERF_SAMPLE_TIME | # PERF_SAMPLE_PERIOD
12# + PERF_SAMPLE_CPU added by -C 0
13sample_type=391
diff --git a/tools/perf/tests/attr/test-stat-C0 b/tools/perf/tests/attr/test-stat-C0
new file mode 100644
index 000000000000..aa835950751f
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-C0
@@ -0,0 +1,9 @@
1[config]
2command = stat
3args = -e cycles -C 0 kill >/dev/null 2>&1
4ret = 1
5
6[event:base-stat]
7# events are enabled by default when attached to cpu
8disabled=0
9enable_on_exec=0
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
new file mode 100644
index 000000000000..68daa289e94c
--- /dev/null
+++ b/tools/perf/tests/bp_signal.c
@@ -0,0 +1,186 @@
1/*
2 * Inspired by breakpoint overflow test done by
3 * Vince Weaver <vincent.weaver@maine.edu> for perf_event_tests
4 * (git://github.com/deater/perf_event_tests)
5 */
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <unistd.h>
10#include <string.h>
11#include <sys/ioctl.h>
12#include <time.h>
13#include <fcntl.h>
14#include <signal.h>
15#include <sys/mman.h>
16#include <linux/compiler.h>
17#include <linux/hw_breakpoint.h>
18
19#include "tests.h"
20#include "debug.h"
21#include "perf.h"
22
23static int fd1;
24static int fd2;
25static int overflows;
26
27__attribute__ ((noinline))
28static int test_function(void)
29{
30 return time(NULL);
31}
32
33static void sig_handler(int signum __maybe_unused,
34 siginfo_t *oh __maybe_unused,
35 void *uc __maybe_unused)
36{
37 overflows++;
38
39 if (overflows > 10) {
40 /*
41 * This should be executed only once during
42 * this test, if we are here for the 10th
43 * time, consider this the recursive issue.
44 *
45 * We can get out of here by disable events,
46 * so no new SIGIO is delivered.
47 */
48 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
49 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
50 }
51}
52
53static int bp_event(void *fn, int setup_signal)
54{
55 struct perf_event_attr pe;
56 int fd;
57
58 memset(&pe, 0, sizeof(struct perf_event_attr));
59 pe.type = PERF_TYPE_BREAKPOINT;
60 pe.size = sizeof(struct perf_event_attr);
61
62 pe.config = 0;
63 pe.bp_type = HW_BREAKPOINT_X;
64 pe.bp_addr = (unsigned long) fn;
65 pe.bp_len = sizeof(long);
66
67 pe.sample_period = 1;
68 pe.sample_type = PERF_SAMPLE_IP;
69 pe.wakeup_events = 1;
70
71 pe.disabled = 1;
72 pe.exclude_kernel = 1;
73 pe.exclude_hv = 1;
74
75 fd = sys_perf_event_open(&pe, 0, -1, -1, 0);
76 if (fd < 0) {
77 pr_debug("failed opening event %llx\n", pe.config);
78 return TEST_FAIL;
79 }
80
81 if (setup_signal) {
82 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
83 fcntl(fd, F_SETSIG, SIGIO);
84 fcntl(fd, F_SETOWN, getpid());
85 }
86
87 ioctl(fd, PERF_EVENT_IOC_RESET, 0);
88
89 return fd;
90}
91
92static long long bp_count(int fd)
93{
94 long long count;
95 int ret;
96
97 ret = read(fd, &count, sizeof(long long));
98 if (ret != sizeof(long long)) {
99 pr_debug("failed to read: %d\n", ret);
100 return TEST_FAIL;
101 }
102
103 return count;
104}
105
106int test__bp_signal(void)
107{
108 struct sigaction sa;
109 long long count1, count2;
110
111 /* setup SIGIO signal handler */
112 memset(&sa, 0, sizeof(struct sigaction));
113 sa.sa_sigaction = (void *) sig_handler;
114 sa.sa_flags = SA_SIGINFO;
115
116 if (sigaction(SIGIO, &sa, NULL) < 0) {
117 pr_debug("failed setting up signal handler\n");
118 return TEST_FAIL;
119 }
120
121 /*
122 * We create following events:
123 *
124 * fd1 - breakpoint event on test_function with SIGIO
125 * signal configured. We should get signal
126 * notification each time the breakpoint is hit
127 *
128 * fd2 - breakpoint event on sig_handler without SIGIO
129 * configured.
130 *
131 * Following processing should happen:
132 * - execute test_function
133 * - fd1 event breakpoint hit -> count1 == 1
134 * - SIGIO is delivered -> overflows == 1
135 * - fd2 event breakpoint hit -> count2 == 1
136 *
137 * The test case check following error conditions:
138 * - we get stuck in signal handler because of debug
139 * exception being triggered receursively due to
140 * the wrong RF EFLAG management
141 *
142 * - we never trigger the sig_handler breakpoint due
143 * to the rong RF EFLAG management
144 *
145 */
146
147 fd1 = bp_event(test_function, 1);
148 fd2 = bp_event(sig_handler, 0);
149
150 ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0);
151 ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);
152
153 /*
154 * Kick off the test by trigering 'fd1'
155 * breakpoint.
156 */
157 test_function();
158
159 ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0);
160 ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0);
161
162 count1 = bp_count(fd1);
163 count2 = bp_count(fd2);
164
165 close(fd1);
166 close(fd2);
167
168 pr_debug("count1 %lld, count2 %lld, overflow %d\n",
169 count1, count2, overflows);
170
171 if (count1 != 1) {
172 if (count1 == 11)
173 pr_debug("failed: RF EFLAG recursion issue detected\n");
174 else
175 pr_debug("failed: wrong count for bp1%lld\n", count1);
176 }
177
178 if (overflows != 1)
179 pr_debug("failed: wrong overflow hit\n");
180
181 if (count2 != 1)
182 pr_debug("failed: wrong count for bp2\n");
183
184 return count1 == 1 && overflows == 1 && count2 == 1 ?
185 TEST_OK : TEST_FAIL;
186}
diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c
new file mode 100644
index 000000000000..fe7ed28815f8
--- /dev/null
+++ b/tools/perf/tests/bp_signal_overflow.c
@@ -0,0 +1,126 @@
1/*
2 * Originally done by Vince Weaver <vincent.weaver@maine.edu> for
3 * perf_event_tests (git://github.com/deater/perf_event_tests)
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <string.h>
10#include <sys/ioctl.h>
11#include <time.h>
12#include <fcntl.h>
13#include <signal.h>
14#include <sys/mman.h>
15#include <linux/compiler.h>
16#include <linux/hw_breakpoint.h>
17
18#include "tests.h"
19#include "debug.h"
20#include "perf.h"
21
22static int overflows;
23
24__attribute__ ((noinline))
25static int test_function(void)
26{
27 return time(NULL);
28}
29
30static void sig_handler(int signum __maybe_unused,
31 siginfo_t *oh __maybe_unused,
32 void *uc __maybe_unused)
33{
34 overflows++;
35}
36
37static long long bp_count(int fd)
38{
39 long long count;
40 int ret;
41
42 ret = read(fd, &count, sizeof(long long));
43 if (ret != sizeof(long long)) {
44 pr_debug("failed to read: %d\n", ret);
45 return TEST_FAIL;
46 }
47
48 return count;
49}
50
51#define EXECUTIONS 10000
52#define THRESHOLD 100
53
54int test__bp_signal_overflow(void)
55{
56 struct perf_event_attr pe;
57 struct sigaction sa;
58 long long count;
59 int fd, i, fails = 0;
60
61 /* setup SIGIO signal handler */
62 memset(&sa, 0, sizeof(struct sigaction));
63 sa.sa_sigaction = (void *) sig_handler;
64 sa.sa_flags = SA_SIGINFO;
65
66 if (sigaction(SIGIO, &sa, NULL) < 0) {
67 pr_debug("failed setting up signal handler\n");
68 return TEST_FAIL;
69 }
70
71 memset(&pe, 0, sizeof(struct perf_event_attr));
72 pe.type = PERF_TYPE_BREAKPOINT;
73 pe.size = sizeof(struct perf_event_attr);
74
75 pe.config = 0;
76 pe.bp_type = HW_BREAKPOINT_X;
77 pe.bp_addr = (unsigned long) test_function;
78 pe.bp_len = sizeof(long);
79
80 pe.sample_period = THRESHOLD;
81 pe.sample_type = PERF_SAMPLE_IP;
82 pe.wakeup_events = 1;
83
84 pe.disabled = 1;
85 pe.exclude_kernel = 1;
86 pe.exclude_hv = 1;
87
88 fd = sys_perf_event_open(&pe, 0, -1, -1, 0);
89 if (fd < 0) {
90 pr_debug("failed opening event %llx\n", pe.config);
91 return TEST_FAIL;
92 }
93
94 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
95 fcntl(fd, F_SETSIG, SIGIO);
96 fcntl(fd, F_SETOWN, getpid());
97
98 ioctl(fd, PERF_EVENT_IOC_RESET, 0);
99 ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
100
101 for (i = 0; i < EXECUTIONS; i++)
102 test_function();
103
104 ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
105
106 count = bp_count(fd);
107
108 close(fd);
109
110 pr_debug("count %lld, overflow %d\n",
111 count, overflows);
112
113 if (count != EXECUTIONS) {
114 pr_debug("\tWrong number of executions %lld != %d\n",
115 count, EXECUTIONS);
116 fails++;
117 }
118
119 if (overflows != EXECUTIONS / THRESHOLD) {
120 pr_debug("\tWrong number of overflows %d != %d\n",
121 overflows, EXECUTIONS / THRESHOLD);
122 fails++;
123 }
124
125 return fails ? TEST_FAIL : TEST_OK;
126}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index acb98e0e39f2..0918ada4cc41 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -78,6 +78,22 @@ static struct test {
78 .func = test__python_use, 78 .func = test__python_use,
79 }, 79 },
80 { 80 {
81 .desc = "Test breakpoint overflow signal handler",
82 .func = test__bp_signal,
83 },
84 {
85 .desc = "Test breakpoint overflow sampling",
86 .func = test__bp_signal_overflow,
87 },
88 {
89 .desc = "Test number of exit event of a simple workload",
90 .func = test__task_exit,
91 },
92 {
93 .desc = "Test software clock events have valid period values",
94 .func = test__sw_clock_freq,
95 },
96 {
81 .func = NULL, 97 .func = NULL,
82 }, 98 },
83}; 99};
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index 0fd99a9adb91..0197bda9c461 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -8,7 +8,7 @@ static int perf_evsel__roundtrip_cache_name_test(void)
8 char name[128]; 8 char name[128];
9 int type, op, err = 0, ret = 0, i, idx; 9 int type, op, err = 0, ret = 0, i, idx;
10 struct perf_evsel *evsel; 10 struct perf_evsel *evsel;
11 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 11 struct perf_evlist *evlist = perf_evlist__new();
12 12
13 if (evlist == NULL) 13 if (evlist == NULL)
14 return -ENOMEM; 14 return -ENOMEM;
@@ -64,7 +64,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
64{ 64{
65 int i, err; 65 int i, err;
66 struct perf_evsel *evsel; 66 struct perf_evsel *evsel;
67 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 67 struct perf_evlist *evlist = perf_evlist__new();
68 68
69 if (evlist == NULL) 69 if (evlist == NULL)
70 return -ENOMEM; 70 return -ENOMEM;
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 1be64a6c5daf..e0c0267858a1 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -436,7 +436,7 @@ int test__hists_link(void)
436 struct machines machines; 436 struct machines machines;
437 struct machine *machine = NULL; 437 struct machine *machine = NULL;
438 struct perf_evsel *evsel, *first; 438 struct perf_evsel *evsel, *first;
439 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 439 struct perf_evlist *evlist = perf_evlist__new();
440 440
441 if (evlist == NULL) 441 if (evlist == NULL)
442 return -ENOMEM; 442 return -ENOMEM;
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index cdd50755af51..5b1b5aba722b 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -53,12 +53,14 @@ int test__basic_mmap(void)
53 goto out_free_cpus; 53 goto out_free_cpus;
54 } 54 }
55 55
56 evlist = perf_evlist__new(cpus, threads); 56 evlist = perf_evlist__new();
57 if (evlist == NULL) { 57 if (evlist == NULL) {
58 pr_debug("perf_evlist__new\n"); 58 pr_debug("perf_evlist__new\n");
59 goto out_free_cpus; 59 goto out_free_cpus;
60 } 60 }
61 61
62 perf_evlist__set_maps(evlist, cpus, threads);
63
62 for (i = 0; i < nsyscalls; ++i) { 64 for (i = 0; i < nsyscalls; ++i) {
63 char name[64]; 65 char name[64];
64 66
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index 1c52fdc1164e..fc5b9fca8b47 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -18,7 +18,7 @@ int test__syscall_open_tp_fields(void)
18 }; 18 };
19 const char *filename = "/etc/passwd"; 19 const char *filename = "/etc/passwd";
20 int flags = O_RDONLY | O_DIRECTORY; 20 int flags = O_RDONLY | O_DIRECTORY;
21 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 21 struct perf_evlist *evlist = perf_evlist__new();
22 struct perf_evsel *evsel; 22 struct perf_evsel *evsel;
23 int err = -1, i, nr_events = 0, nr_polls = 0; 23 int err = -1, i, nr_events = 0, nr_polls = 0;
24 24
@@ -48,13 +48,13 @@ int test__syscall_open_tp_fields(void)
48 err = perf_evlist__open(evlist); 48 err = perf_evlist__open(evlist);
49 if (err < 0) { 49 if (err < 0) {
50 pr_debug("perf_evlist__open: %s\n", strerror(errno)); 50 pr_debug("perf_evlist__open: %s\n", strerror(errno));
51 goto out_delete_evlist; 51 goto out_delete_maps;
52 } 52 }
53 53
54 err = perf_evlist__mmap(evlist, UINT_MAX, false); 54 err = perf_evlist__mmap(evlist, UINT_MAX, false);
55 if (err < 0) { 55 if (err < 0) {
56 pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); 56 pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
57 goto out_delete_evlist; 57 goto out_close_evlist;
58 } 58 }
59 59
60 perf_evlist__enable(evlist); 60 perf_evlist__enable(evlist);
@@ -110,6 +110,10 @@ out_ok:
110 err = 0; 110 err = 0;
111out_munmap: 111out_munmap:
112 perf_evlist__munmap(evlist); 112 perf_evlist__munmap(evlist);
113out_close_evlist:
114 perf_evlist__close(evlist);
115out_delete_maps:
116 perf_evlist__delete_maps(evlist);
113out_delete_evlist: 117out_delete_evlist:
114 perf_evlist__delete(evlist); 118 perf_evlist__delete(evlist);
115out: 119out:
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index c5636f36fe31..88e2f44cb157 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -3,7 +3,7 @@
3#include "evsel.h" 3#include "evsel.h"
4#include "evlist.h" 4#include "evlist.h"
5#include "sysfs.h" 5#include "sysfs.h"
6#include "debugfs.h" 6#include <lk/debugfs.h>
7#include "tests.h" 7#include "tests.h"
8#include <linux/hw_breakpoint.h> 8#include <linux/hw_breakpoint.h>
9 9
@@ -1218,7 +1218,7 @@ static int test_event(struct evlist_test *e)
1218 struct perf_evlist *evlist; 1218 struct perf_evlist *evlist;
1219 int ret; 1219 int ret;
1220 1220
1221 evlist = perf_evlist__new(NULL, NULL); 1221 evlist = perf_evlist__new();
1222 if (evlist == NULL) 1222 if (evlist == NULL)
1223 return -ENOMEM; 1223 return -ENOMEM;
1224 1224
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 1e8e5128d0da..72d8881873b0 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -45,7 +45,7 @@ int test__PERF_RECORD(void)
45 }; 45 };
46 cpu_set_t cpu_mask; 46 cpu_set_t cpu_mask;
47 size_t cpu_mask_size = sizeof(cpu_mask); 47 size_t cpu_mask_size = sizeof(cpu_mask);
48 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 48 struct perf_evlist *evlist = perf_evlist__new();
49 struct perf_evsel *evsel; 49 struct perf_evsel *evsel;
50 struct perf_sample sample; 50 struct perf_sample sample;
51 const char *cmd = "sleep"; 51 const char *cmd = "sleep";
@@ -93,7 +93,8 @@ int test__PERF_RECORD(void)
93 * so that we have time to open the evlist (calling sys_perf_event_open 93 * so that we have time to open the evlist (calling sys_perf_event_open
94 * on all the fds) and then mmap them. 94 * on all the fds) and then mmap them.
95 */ 95 */
96 err = perf_evlist__prepare_workload(evlist, &opts, argv); 96 err = perf_evlist__prepare_workload(evlist, &opts.target, argv,
97 false, false);
97 if (err < 0) { 98 if (err < 0) {
98 pr_debug("Couldn't run the workload!\n"); 99 pr_debug("Couldn't run the workload!\n");
99 goto out_delete_maps; 100 goto out_delete_maps;
@@ -142,7 +143,7 @@ int test__PERF_RECORD(void)
142 err = perf_evlist__mmap(evlist, opts.mmap_pages, false); 143 err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
143 if (err < 0) { 144 if (err < 0) {
144 pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); 145 pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
145 goto out_delete_maps; 146 goto out_close_evlist;
146 } 147 }
147 148
148 /* 149 /*
@@ -305,6 +306,8 @@ found_exit:
305 } 306 }
306out_err: 307out_err:
307 perf_evlist__munmap(evlist); 308 perf_evlist__munmap(evlist);
309out_close_evlist:
310 perf_evlist__close(evlist);
308out_delete_maps: 311out_delete_maps:
309 perf_evlist__delete_maps(evlist); 312 perf_evlist__delete_maps(evlist);
310out_delete_evlist: 313out_delete_evlist:
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
new file mode 100644
index 000000000000..2e41e2d32ccc
--- /dev/null
+++ b/tools/perf/tests/sw-clock.c
@@ -0,0 +1,119 @@
1#include <unistd.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <sys/mman.h>
5
6#include "tests.h"
7#include "util/evsel.h"
8#include "util/evlist.h"
9#include "util/cpumap.h"
10#include "util/thread_map.h"
11
12#define NR_LOOPS 1000000
13
14/*
15 * This test will open software clock events (cpu-clock, task-clock)
16 * then check their frequency -> period conversion has no artifact of
17 * setting period to 1 forcefully.
18 */
19static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
20{
21 int i, err = -1;
22 volatile int tmp = 0;
23 u64 total_periods = 0;
24 int nr_samples = 0;
25 union perf_event *event;
26 struct perf_evsel *evsel;
27 struct perf_evlist *evlist;
28 struct perf_event_attr attr = {
29 .type = PERF_TYPE_SOFTWARE,
30 .config = clock_id,
31 .sample_type = PERF_SAMPLE_PERIOD,
32 .exclude_kernel = 1,
33 .disabled = 1,
34 .freq = 1,
35 };
36
37 attr.sample_freq = 10000;
38
39 evlist = perf_evlist__new();
40 if (evlist == NULL) {
41 pr_debug("perf_evlist__new\n");
42 return -1;
43 }
44
45 evsel = perf_evsel__new(&attr, 0);
46 if (evsel == NULL) {
47 pr_debug("perf_evsel__new\n");
48 goto out_free_evlist;
49 }
50 perf_evlist__add(evlist, evsel);
51
52 evlist->cpus = cpu_map__dummy_new();
53 evlist->threads = thread_map__new_by_tid(getpid());
54 if (!evlist->cpus || !evlist->threads) {
55 err = -ENOMEM;
56 pr_debug("Not enough memory to create thread/cpu maps\n");
57 goto out_delete_maps;
58 }
59
60 perf_evlist__open(evlist);
61
62 err = perf_evlist__mmap(evlist, 128, true);
63 if (err < 0) {
64 pr_debug("failed to mmap event: %d (%s)\n", errno,
65 strerror(errno));
66 goto out_close_evlist;
67 }
68
69 perf_evlist__enable(evlist);
70
71 /* collect samples */
72 for (i = 0; i < NR_LOOPS; i++)
73 tmp++;
74
75 perf_evlist__disable(evlist);
76
77 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
78 struct perf_sample sample;
79
80 if (event->header.type != PERF_RECORD_SAMPLE)
81 continue;
82
83 err = perf_evlist__parse_sample(evlist, event, &sample);
84 if (err < 0) {
85 pr_debug("Error during parse sample\n");
86 goto out_unmap_evlist;
87 }
88
89 total_periods += sample.period;
90 nr_samples++;
91 }
92
93 if ((u64) nr_samples == total_periods) {
94 pr_debug("All (%d) samples have period value of 1!\n",
95 nr_samples);
96 err = -1;
97 }
98
99out_unmap_evlist:
100 perf_evlist__munmap(evlist);
101out_close_evlist:
102 perf_evlist__close(evlist);
103out_delete_maps:
104 perf_evlist__delete_maps(evlist);
105out_free_evlist:
106 perf_evlist__delete(evlist);
107 return err;
108}
109
110int test__sw_clock_freq(void)
111{
112 int ret;
113
114 ret = __test__sw_clock_freq(PERF_COUNT_SW_CPU_CLOCK);
115 if (!ret)
116 ret = __test__sw_clock_freq(PERF_COUNT_SW_TASK_CLOCK);
117
118 return ret;
119}
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
new file mode 100644
index 000000000000..28fe5894b061
--- /dev/null
+++ b/tools/perf/tests/task-exit.c
@@ -0,0 +1,123 @@
1#include "evlist.h"
2#include "evsel.h"
3#include "thread_map.h"
4#include "cpumap.h"
5#include "tests.h"
6
7#include <signal.h>
8
9static int exited;
10static int nr_exit;
11
12static void sig_handler(int sig)
13{
14 exited = 1;
15
16 if (sig == SIGUSR1)
17 nr_exit = -1;
18}
19
20/*
21 * This test will start a workload that does nothing then it checks
22 * if the number of exit event reported by the kernel is 1 or not
23 * in order to check the kernel returns correct number of event.
24 */
25int test__task_exit(void)
26{
27 int err = -1;
28 union perf_event *event;
29 struct perf_evsel *evsel;
30 struct perf_evlist *evlist;
31 struct perf_target target = {
32 .uid = UINT_MAX,
33 .uses_mmap = true,
34 };
35 const char *argv[] = { "true", NULL };
36
37 signal(SIGCHLD, sig_handler);
38 signal(SIGUSR1, sig_handler);
39
40 evlist = perf_evlist__new();
41 if (evlist == NULL) {
42 pr_debug("perf_evlist__new\n");
43 return -1;
44 }
45 /*
46 * We need at least one evsel in the evlist, use the default
47 * one: "cycles".
48 */
49 err = perf_evlist__add_default(evlist);
50 if (err < 0) {
51 pr_debug("Not enough memory to create evsel\n");
52 goto out_free_evlist;
53 }
54
55 /*
56 * Create maps of threads and cpus to monitor. In this case
57 * we start with all threads and cpus (-1, -1) but then in
58 * perf_evlist__prepare_workload we'll fill in the only thread
59 * we're monitoring, the one forked there.
60 */
61 evlist->cpus = cpu_map__dummy_new();
62 evlist->threads = thread_map__new_by_tid(-1);
63 if (!evlist->cpus || !evlist->threads) {
64 err = -ENOMEM;
65 pr_debug("Not enough memory to create thread/cpu maps\n");
66 goto out_delete_maps;
67 }
68
69 err = perf_evlist__prepare_workload(evlist, &target, argv, false, true);
70 if (err < 0) {
71 pr_debug("Couldn't run the workload!\n");
72 goto out_delete_maps;
73 }
74
75 evsel = perf_evlist__first(evlist);
76 evsel->attr.task = 1;
77 evsel->attr.sample_freq = 0;
78 evsel->attr.inherit = 0;
79 evsel->attr.watermark = 0;
80 evsel->attr.wakeup_events = 1;
81 evsel->attr.exclude_kernel = 1;
82
83 err = perf_evlist__open(evlist);
84 if (err < 0) {
85 pr_debug("Couldn't open the evlist: %s\n", strerror(-err));
86 goto out_delete_maps;
87 }
88
89 if (perf_evlist__mmap(evlist, 128, true) < 0) {
90 pr_debug("failed to mmap events: %d (%s)\n", errno,
91 strerror(errno));
92 goto out_close_evlist;
93 }
94
95 perf_evlist__start_workload(evlist);
96
97retry:
98 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
99 if (event->header.type != PERF_RECORD_EXIT)
100 continue;
101
102 nr_exit++;
103 }
104
105 if (!exited || !nr_exit) {
106 poll(evlist->pollfd, evlist->nr_fds, -1);
107 goto retry;
108 }
109
110 if (nr_exit != 1) {
111 pr_debug("received %d EXIT records\n", nr_exit);
112 err = -1;
113 }
114
115 perf_evlist__munmap(evlist);
116out_close_evlist:
117 perf_evlist__close(evlist);
118out_delete_maps:
119 perf_evlist__delete_maps(evlist);
120out_free_evlist:
121 perf_evlist__delete(evlist);
122 return err;
123}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 5de0be1ff4b6..dd7feae2d37b 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -23,5 +23,9 @@ int test__dso_data(void);
23int test__parse_events(void); 23int test__parse_events(void);
24int test__hists_link(void); 24int test__hists_link(void);
25int test__python_use(void); 25int test__python_use(void);
26int test__bp_signal(void);
27int test__bp_signal_overflow(void);
28int test__task_exit(void);
29int test__sw_clock_freq(void);
26 30
27#endif /* TESTS_H */ 31#endif /* TESTS_H */