diff options
Diffstat (limited to 'tools/perf/tests')
-rw-r--r-- | tools/perf/tests/attr.c | 9 | ||||
-rw-r--r-- | tools/perf/tests/attr.py | 5 | ||||
-rw-r--r-- | tools/perf/tests/attr/base-record | 1 | ||||
-rw-r--r-- | tools/perf/tests/attr/base-stat | 1 | ||||
-rw-r--r-- | tools/perf/tests/attr/test-record-C0 | 13 | ||||
-rw-r--r-- | tools/perf/tests/attr/test-stat-C0 | 9 | ||||
-rw-r--r-- | tools/perf/tests/bp_signal.c | 186 | ||||
-rw-r--r-- | tools/perf/tests/bp_signal_overflow.c | 126 | ||||
-rw-r--r-- | tools/perf/tests/builtin-test.c | 16 | ||||
-rw-r--r-- | tools/perf/tests/evsel-roundtrip-name.c | 4 | ||||
-rw-r--r-- | tools/perf/tests/hists_link.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/mmap-basic.c | 4 | ||||
-rw-r--r-- | tools/perf/tests/open-syscall-tp-fields.c | 10 | ||||
-rw-r--r-- | tools/perf/tests/parse-events.c | 4 | ||||
-rw-r--r-- | tools/perf/tests/perf-record.c | 9 | ||||
-rw-r--r-- | tools/perf/tests/sw-clock.c | 119 | ||||
-rw-r--r-- | tools/perf/tests/task-exit.c | 123 | ||||
-rw-r--r-- | tools/perf/tests/tests.h | 4 |
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 | ||
148 | static int run_dir(const char *d, const char *perf) | 148 | static 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 | ||
25 | class Event(dict): | 25 | class 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 @@ | |||
2 | fd=1 | 2 | fd=1 |
3 | group_fd=-1 | 3 | group_fd=-1 |
4 | flags=0 | 4 | flags=0 |
5 | cpu=* | ||
5 | type=0|1 | 6 | type=0|1 |
6 | size=96 | 7 | size=96 |
7 | config=0 | 8 | config=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 @@ | |||
2 | fd=1 | 2 | fd=1 |
3 | group_fd=-1 | 3 | group_fd=-1 |
4 | flags=0 | 4 | flags=0 |
5 | cpu=* | ||
5 | type=0 | 6 | type=0 |
6 | size=96 | 7 | size=96 |
7 | config=0 | 8 | config=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] | ||
2 | command = record | ||
3 | args = -C 0 kill >/dev/null 2>&1 | ||
4 | |||
5 | [event:base-record] | ||
6 | cpu=0 | ||
7 | |||
8 | # no enable on exec for CPU attached | ||
9 | enable_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 | ||
13 | sample_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] | ||
2 | command = stat | ||
3 | args = -e cycles -C 0 kill >/dev/null 2>&1 | ||
4 | ret = 1 | ||
5 | |||
6 | [event:base-stat] | ||
7 | # events are enabled by default when attached to cpu | ||
8 | disabled=0 | ||
9 | enable_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 | |||
23 | static int fd1; | ||
24 | static int fd2; | ||
25 | static int overflows; | ||
26 | |||
27 | __attribute__ ((noinline)) | ||
28 | static int test_function(void) | ||
29 | { | ||
30 | return time(NULL); | ||
31 | } | ||
32 | |||
33 | static 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 | |||
53 | static 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 | |||
92 | static 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 | |||
106 | int 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 | |||
22 | static int overflows; | ||
23 | |||
24 | __attribute__ ((noinline)) | ||
25 | static int test_function(void) | ||
26 | { | ||
27 | return time(NULL); | ||
28 | } | ||
29 | |||
30 | static void sig_handler(int signum __maybe_unused, | ||
31 | siginfo_t *oh __maybe_unused, | ||
32 | void *uc __maybe_unused) | ||
33 | { | ||
34 | overflows++; | ||
35 | } | ||
36 | |||
37 | static 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 | |||
54 | int 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; |
111 | out_munmap: | 111 | out_munmap: |
112 | perf_evlist__munmap(evlist); | 112 | perf_evlist__munmap(evlist); |
113 | out_close_evlist: | ||
114 | perf_evlist__close(evlist); | ||
115 | out_delete_maps: | ||
116 | perf_evlist__delete_maps(evlist); | ||
113 | out_delete_evlist: | 117 | out_delete_evlist: |
114 | perf_evlist__delete(evlist); | 118 | perf_evlist__delete(evlist); |
115 | out: | 119 | out: |
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 | } |
306 | out_err: | 307 | out_err: |
307 | perf_evlist__munmap(evlist); | 308 | perf_evlist__munmap(evlist); |
309 | out_close_evlist: | ||
310 | perf_evlist__close(evlist); | ||
308 | out_delete_maps: | 311 | out_delete_maps: |
309 | perf_evlist__delete_maps(evlist); | 312 | perf_evlist__delete_maps(evlist); |
310 | out_delete_evlist: | 313 | out_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 | */ | ||
19 | static 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 | |||
99 | out_unmap_evlist: | ||
100 | perf_evlist__munmap(evlist); | ||
101 | out_close_evlist: | ||
102 | perf_evlist__close(evlist); | ||
103 | out_delete_maps: | ||
104 | perf_evlist__delete_maps(evlist); | ||
105 | out_free_evlist: | ||
106 | perf_evlist__delete(evlist); | ||
107 | return err; | ||
108 | } | ||
109 | |||
110 | int 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 | |||
9 | static int exited; | ||
10 | static int nr_exit; | ||
11 | |||
12 | static 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 | */ | ||
25 | int 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 | |||
97 | retry: | ||
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); | ||
116 | out_close_evlist: | ||
117 | perf_evlist__close(evlist); | ||
118 | out_delete_maps: | ||
119 | perf_evlist__delete_maps(evlist); | ||
120 | out_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); | |||
23 | int test__parse_events(void); | 23 | int test__parse_events(void); |
24 | int test__hists_link(void); | 24 | int test__hists_link(void); |
25 | int test__python_use(void); | 25 | int test__python_use(void); |
26 | int test__bp_signal(void); | ||
27 | int test__bp_signal_overflow(void); | ||
28 | int test__task_exit(void); | ||
29 | int test__sw_clock_freq(void); | ||
26 | 30 | ||
27 | #endif /* TESTS_H */ | 31 | #endif /* TESTS_H */ |