aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/tests')
-rw-r--r--tools/perf/tests/attr.c174
-rw-r--r--tools/perf/tests/attr.py322
-rw-r--r--tools/perf/tests/attr/README64
-rw-r--r--tools/perf/tests/attr/base-record39
-rw-r--r--tools/perf/tests/attr/base-stat39
-rw-r--r--tools/perf/tests/attr/test-record-basic5
-rw-r--r--tools/perf/tests/attr/test-record-branch-any8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-any8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-any_call8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-any_ret8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-hv8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-ind_call8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-k8
-rw-r--r--tools/perf/tests/attr/test-record-branch-filter-u8
-rw-r--r--tools/perf/tests/attr/test-record-count8
-rw-r--r--tools/perf/tests/attr/test-record-data8
-rw-r--r--tools/perf/tests/attr/test-record-freq6
-rw-r--r--tools/perf/tests/attr/test-record-graph-default6
-rw-r--r--tools/perf/tests/attr/test-record-graph-dwarf10
-rw-r--r--tools/perf/tests/attr/test-record-graph-fp6
-rw-r--r--tools/perf/tests/attr/test-record-group17
-rw-r--r--tools/perf/tests/attr/test-record-group120
-rw-r--r--tools/perf/tests/attr/test-record-no-delay9
-rw-r--r--tools/perf/tests/attr/test-record-no-inherit7
-rw-r--r--tools/perf/tests/attr/test-record-no-samples6
-rw-r--r--tools/perf/tests/attr/test-record-period7
-rw-r--r--tools/perf/tests/attr/test-record-raw7
-rw-r--r--tools/perf/tests/attr/test-stat-basic6
-rw-r--r--tools/perf/tests/attr/test-stat-default64
-rw-r--r--tools/perf/tests/attr/test-stat-detailed-1101
-rw-r--r--tools/perf/tests/attr/test-stat-detailed-2155
-rw-r--r--tools/perf/tests/attr/test-stat-detailed-3173
-rw-r--r--tools/perf/tests/attr/test-stat-group15
-rw-r--r--tools/perf/tests/attr/test-stat-group117
-rw-r--r--tools/perf/tests/attr/test-stat-no-inherit7
-rw-r--r--tools/perf/tests/builtin-test.c1550
-rw-r--r--tools/perf/tests/dso-data.c154
-rw-r--r--tools/perf/tests/parse-events.c1116
38 files changed, 4182 insertions, 0 deletions
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
new file mode 100644
index 000000000000..6e2feee8db2a
--- /dev/null
+++ b/tools/perf/tests/attr.c
@@ -0,0 +1,174 @@
1
2/*
3 * The struct perf_event_attr test support.
4 *
5 * This test is embedded inside into perf directly and is governed
6 * by the PERF_TEST_ATTR environment variable and hook inside
7 * sys_perf_event_open function.
8 *
9 * The general idea is to store 'struct perf_event_attr' details for
10 * each event created within single perf command. Each event details
11 * are stored into separate text file. Once perf command is finished
12 * these files can be checked for values we expect for command.
13 *
14 * Besides 'struct perf_event_attr' values we also store 'fd' and
15 * 'group_fd' values to allow checking for groups created.
16 *
17 * This all is triggered by setting PERF_TEST_ATTR environment variable.
18 * It must contain name of existing directory with access and write
19 * permissions. All the event text files are stored there.
20 */
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <inttypes.h>
25#include <linux/types.h>
26#include <linux/kernel.h>
27#include "../perf.h"
28#include "util.h"
29#include "exec_cmd.h"
30
31#define ENV "PERF_TEST_ATTR"
32
33extern int verbose;
34
35bool test_attr__enabled;
36
37static char *dir;
38
39void test_attr__init(void)
40{
41 dir = getenv(ENV);
42 test_attr__enabled = (dir != NULL);
43}
44
45#define BUFSIZE 1024
46
47#define __WRITE_ASS(str, fmt, data) \
48do { \
49 char buf[BUFSIZE]; \
50 size_t size; \
51 \
52 size = snprintf(buf, BUFSIZE, #str "=%"fmt "\n", data); \
53 if (1 != fwrite(buf, size, 1, file)) { \
54 perror("test attr - failed to write event file"); \
55 fclose(file); \
56 return -1; \
57 } \
58 \
59} while (0)
60
61#define WRITE_ASS(field, fmt) __WRITE_ASS(field, fmt, attr->field)
62
63static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu,
64 int fd, int group_fd, unsigned long flags)
65{
66 FILE *file;
67 char path[PATH_MAX];
68
69 snprintf(path, PATH_MAX, "%s/event-%d-%llu-%d", dir,
70 attr->type, attr->config, fd);
71
72 file = fopen(path, "w+");
73 if (!file) {
74 perror("test attr - failed to open event file");
75 return -1;
76 }
77
78 if (fprintf(file, "[event-%d-%llu-%d]\n",
79 attr->type, attr->config, fd) < 0) {
80 perror("test attr - failed to write event file");
81 fclose(file);
82 return -1;
83 }
84
85 /* syscall arguments */
86 __WRITE_ASS(fd, "d", fd);
87 __WRITE_ASS(group_fd, "d", group_fd);
88 __WRITE_ASS(cpu, "d", cpu);
89 __WRITE_ASS(pid, "d", pid);
90 __WRITE_ASS(flags, "lu", flags);
91
92 /* struct perf_event_attr */
93 WRITE_ASS(type, PRIu32);
94 WRITE_ASS(size, PRIu32);
95 WRITE_ASS(config, "llu");
96 WRITE_ASS(sample_period, "llu");
97 WRITE_ASS(sample_type, "llu");
98 WRITE_ASS(read_format, "llu");
99 WRITE_ASS(disabled, "d");
100 WRITE_ASS(inherit, "d");
101 WRITE_ASS(pinned, "d");
102 WRITE_ASS(exclusive, "d");
103 WRITE_ASS(exclude_user, "d");
104 WRITE_ASS(exclude_kernel, "d");
105 WRITE_ASS(exclude_hv, "d");
106 WRITE_ASS(exclude_idle, "d");
107 WRITE_ASS(mmap, "d");
108 WRITE_ASS(comm, "d");
109 WRITE_ASS(freq, "d");
110 WRITE_ASS(inherit_stat, "d");
111 WRITE_ASS(enable_on_exec, "d");
112 WRITE_ASS(task, "d");
113 WRITE_ASS(watermark, "d");
114 WRITE_ASS(precise_ip, "d");
115 WRITE_ASS(mmap_data, "d");
116 WRITE_ASS(sample_id_all, "d");
117 WRITE_ASS(exclude_host, "d");
118 WRITE_ASS(exclude_guest, "d");
119 WRITE_ASS(exclude_callchain_kernel, "d");
120 WRITE_ASS(exclude_callchain_user, "d");
121 WRITE_ASS(wakeup_events, PRIu32);
122 WRITE_ASS(bp_type, PRIu32);
123 WRITE_ASS(config1, "llu");
124 WRITE_ASS(config2, "llu");
125 WRITE_ASS(branch_sample_type, "llu");
126 WRITE_ASS(sample_regs_user, "llu");
127 WRITE_ASS(sample_stack_user, PRIu32);
128
129 fclose(file);
130 return 0;
131}
132
133void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
134 int fd, int group_fd, unsigned long flags)
135{
136 int errno_saved = errno;
137
138 if (store_event(attr, pid, cpu, fd, group_fd, flags))
139 die("test attr FAILED");
140
141 errno = errno_saved;
142}
143
144static int run_dir(const char *d, const char *perf)
145{
146 char cmd[3*PATH_MAX];
147
148 snprintf(cmd, 3*PATH_MAX, "python %s/attr.py -d %s/attr/ -p %s %s",
149 d, d, perf, verbose ? "-v" : "");
150
151 return system(cmd);
152}
153
154int test_attr__run(void)
155{
156 struct stat st;
157 char path_perf[PATH_MAX];
158 char path_dir[PATH_MAX];
159
160 /* First try developement tree tests. */
161 if (!lstat("./tests", &st))
162 return run_dir("./tests", "./perf");
163
164 /* Then installed path. */
165 snprintf(path_dir, PATH_MAX, "%s/tests", perf_exec_path());
166 snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR);
167
168 if (!lstat(path_dir, &st) &&
169 !lstat(path_perf, &st))
170 return run_dir(path_dir, path_perf);
171
172 fprintf(stderr, " (ommitted)");
173 return 0;
174}
diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py
new file mode 100644
index 000000000000..e702b82dcb86
--- /dev/null
+++ b/tools/perf/tests/attr.py
@@ -0,0 +1,322 @@
1#! /usr/bin/python
2
3import os
4import sys
5import glob
6import optparse
7import tempfile
8import logging
9import shutil
10import ConfigParser
11
12class Fail(Exception):
13 def __init__(self, test, msg):
14 self.msg = msg
15 self.test = test
16 def getMsg(self):
17 return '\'%s\' - %s' % (self.test.path, self.msg)
18
19class Unsup(Exception):
20 def __init__(self, test):
21 self.test = test
22 def getMsg(self):
23 return '\'%s\'' % self.test.path
24
25class Event(dict):
26 terms = [
27 'flags',
28 'type',
29 'size',
30 'config',
31 'sample_period',
32 'sample_type',
33 'read_format',
34 'disabled',
35 'inherit',
36 'pinned',
37 'exclusive',
38 'exclude_user',
39 'exclude_kernel',
40 'exclude_hv',
41 'exclude_idle',
42 'mmap',
43 'comm',
44 'freq',
45 'inherit_stat',
46 'enable_on_exec',
47 'task',
48 'watermark',
49 'precise_ip',
50 'mmap_data',
51 'sample_id_all',
52 'exclude_host',
53 'exclude_guest',
54 'exclude_callchain_kernel',
55 'exclude_callchain_user',
56 'wakeup_events',
57 'bp_type',
58 'config1',
59 'config2',
60 'branch_sample_type',
61 'sample_regs_user',
62 'sample_stack_user',
63 ]
64
65 def add(self, data):
66 for key, val in data:
67 log.debug(" %s = %s" % (key, val))
68 self[key] = val
69
70 def __init__(self, name, data, base):
71 log.info(" Event %s" % name);
72 self.name = name;
73 self.group = ''
74 self.add(base)
75 self.add(data)
76
77 def compare_data(self, a, b):
78 # Allow multiple values in assignment separated by '|'
79 a_list = a.split('|')
80 b_list = b.split('|')
81
82 for a_item in a_list:
83 for b_item in b_list:
84 if (a_item == b_item):
85 return True
86 elif (a_item == '*') or (b_item == '*'):
87 return True
88
89 return False
90
91 def equal(self, other):
92 for t in Event.terms:
93 log.debug(" [%s] %s %s" % (t, self[t], other[t]));
94 if not self.has_key(t) or not other.has_key(t):
95 return False
96 if not self.compare_data(self[t], other[t]):
97 return False
98 return True
99
100# Test file description needs to have following sections:
101# [config]
102# - just single instance in file
103# - needs to specify:
104# 'command' - perf command name
105# 'args' - special command arguments
106# 'ret' - expected command return value (0 by default)
107#
108# [eventX:base]
109# - one or multiple instances in file
110# - expected values assignments
111class Test(object):
112 def __init__(self, path, options):
113 parser = ConfigParser.SafeConfigParser()
114 parser.read(path)
115
116 log.warning("running '%s'" % path)
117
118 self.path = path
119 self.test_dir = options.test_dir
120 self.perf = options.perf
121 self.command = parser.get('config', 'command')
122 self.args = parser.get('config', 'args')
123
124 try:
125 self.ret = parser.get('config', 'ret')
126 except:
127 self.ret = 0
128
129 self.expect = {}
130 self.result = {}
131 log.info(" loading expected events");
132 self.load_events(path, self.expect)
133
134 def is_event(self, name):
135 if name.find("event") == -1:
136 return False
137 else:
138 return True
139
140 def load_events(self, path, events):
141 parser_event = ConfigParser.SafeConfigParser()
142 parser_event.read(path)
143
144 # The event record section header contains 'event' word,
145 # optionaly followed by ':' allowing to load 'parent
146 # event' first as a base
147 for section in filter(self.is_event, parser_event.sections()):
148
149 parser_items = parser_event.items(section);
150 base_items = {}
151
152 # Read parent event if there's any
153 if (':' in section):
154 base = section[section.index(':') + 1:]
155 parser_base = ConfigParser.SafeConfigParser()
156 parser_base.read(self.test_dir + '/' + base)
157 base_items = parser_base.items('event')
158
159 e = Event(section, parser_items, base_items)
160 events[section] = e
161
162 def run_cmd(self, tempdir):
163 cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir,
164 self.perf, self.command, tempdir, self.args)
165 ret = os.WEXITSTATUS(os.system(cmd))
166
167 log.info(" running '%s' ret %d " % (cmd, ret))
168
169 if ret != int(self.ret):
170 raise Unsup(self)
171
172 def compare(self, expect, result):
173 match = {}
174
175 log.info(" compare");
176
177 # For each expected event find all matching
178 # events in result. Fail if there's not any.
179 for exp_name, exp_event in expect.items():
180 exp_list = []
181 log.debug(" matching [%s]" % exp_name)
182 for res_name, res_event in result.items():
183 log.debug(" to [%s]" % res_name)
184 if (exp_event.equal(res_event)):
185 exp_list.append(res_name)
186 log.debug(" ->OK")
187 else:
188 log.debug(" ->FAIL");
189
190 log.info(" match: [%s] matches %s" % (exp_name, str(exp_list)))
191
192 # we did not any matching event - fail
193 if (not exp_list):
194 raise Fail(self, 'match failure');
195
196 match[exp_name] = exp_list
197
198 # For each defined group in the expected events
199 # check we match the same group in the result.
200 for exp_name, exp_event in expect.items():
201 group = exp_event.group
202
203 if (group == ''):
204 continue
205
206 for res_name in match[exp_name]:
207 res_group = result[res_name].group
208 if res_group not in match[group]:
209 raise Fail(self, 'group failure')
210
211 log.info(" group: [%s] matches group leader %s" %
212 (exp_name, str(match[group])))
213
214 log.info(" matched")
215
216 def resolve_groups(self, events):
217 for name, event in events.items():
218 group_fd = event['group_fd'];
219 if group_fd == '-1':
220 continue;
221
222 for iname, ievent in events.items():
223 if (ievent['fd'] == group_fd):
224 event.group = iname
225 log.debug('[%s] has group leader [%s]' % (name, iname))
226 break;
227
228 def run(self):
229 tempdir = tempfile.mkdtemp();
230
231 try:
232 # run the test script
233 self.run_cmd(tempdir);
234
235 # load events expectation for the test
236 log.info(" loading result events");
237 for f in glob.glob(tempdir + '/event*'):
238 self.load_events(f, self.result);
239
240 # resolve group_fd to event names
241 self.resolve_groups(self.expect);
242 self.resolve_groups(self.result);
243
244 # do the expectation - results matching - both ways
245 self.compare(self.expect, self.result)
246 self.compare(self.result, self.expect)
247
248 finally:
249 # cleanup
250 shutil.rmtree(tempdir)
251
252
253def run_tests(options):
254 for f in glob.glob(options.test_dir + '/' + options.test):
255 try:
256 Test(f, options).run()
257 except Unsup, obj:
258 log.warning("unsupp %s" % obj.getMsg())
259
260def setup_log(verbose):
261 global log
262 level = logging.CRITICAL
263
264 if verbose == 1:
265 level = logging.WARNING
266 if verbose == 2:
267 level = logging.INFO
268 if verbose >= 3:
269 level = logging.DEBUG
270
271 log = logging.getLogger('test')
272 log.setLevel(level)
273 ch = logging.StreamHandler()
274 ch.setLevel(level)
275 formatter = logging.Formatter('%(message)s')
276 ch.setFormatter(formatter)
277 log.addHandler(ch)
278
279USAGE = '''%s [OPTIONS]
280 -d dir # tests dir
281 -p path # perf binary
282 -t test # single test
283 -v # verbose level
284''' % sys.argv[0]
285
286def main():
287 parser = optparse.OptionParser(usage=USAGE)
288
289 parser.add_option("-t", "--test",
290 action="store", type="string", dest="test")
291 parser.add_option("-d", "--test-dir",
292 action="store", type="string", dest="test_dir")
293 parser.add_option("-p", "--perf",
294 action="store", type="string", dest="perf")
295 parser.add_option("-v", "--verbose",
296 action="count", dest="verbose")
297
298 options, args = parser.parse_args()
299 if args:
300 parser.error('FAILED wrong arguments %s' % ' '.join(args))
301 return -1
302
303 setup_log(options.verbose)
304
305 if not options.test_dir:
306 print 'FAILED no -d option specified'
307 sys.exit(-1)
308
309 if not options.test:
310 options.test = 'test*'
311
312 try:
313 run_tests(options)
314
315 except Fail, obj:
316 print "FAILED %s" % obj.getMsg();
317 sys.exit(-1)
318
319 sys.exit(0)
320
321if __name__ == '__main__':
322 main()
diff --git a/tools/perf/tests/attr/README b/tools/perf/tests/attr/README
new file mode 100644
index 000000000000..d102957cd59a
--- /dev/null
+++ b/tools/perf/tests/attr/README
@@ -0,0 +1,64 @@
1The struct perf_event_attr test (attr tests) support
2====================================================
3This testing support is embedded into perf directly and is governed
4by the PERF_TEST_ATTR environment variable and hook inside the
5sys_perf_event_open function.
6
7The general idea is to store 'struct perf_event_attr' details for
8each event created within single perf command. Each event details
9are stored into separate text file. Once perf command is finished
10these files are checked for values we expect for command.
11
12The attr tests consist of following parts:
13
14tests/attr.c
15------------
16This is the sys_perf_event_open hook implementation. The hook
17is triggered when the PERF_TEST_ATTR environment variable is
18defined. It must contain name of existing directory with access
19and write permissions.
20
21For each sys_perf_event_open call event details are stored in
22separate file. Besides 'struct perf_event_attr' values we also
23store 'fd' and 'group_fd' values to allow checking for groups.
24
25tests/attr.py
26-------------
27This is the python script that does all the hard work. It reads
28the test definition, executes it and checks results.
29
30tests/attr/
31-----------
32Directory containing all attr test definitions.
33Following tests are defined (with perf commands):
34
35 perf record kill (test-record-basic)
36 perf record -b kill (test-record-branch-any)
37 perf record -j any kill (test-record-branch-filter-any)
38 perf record -j any_call kill (test-record-branch-filter-any_call)
39 perf record -j any_ret kill (test-record-branch-filter-any_ret)
40 perf record -j hv kill (test-record-branch-filter-hv)
41 perf record -j ind_call kill (test-record-branch-filter-ind_call)
42 perf record -j k kill (test-record-branch-filter-k)
43 perf record -j u kill (test-record-branch-filter-u)
44 perf record -c 123 kill (test-record-count)
45 perf record -d kill (test-record-data)
46 perf record -F 100 kill (test-record-freq)
47 perf record -g -- kill (test-record-graph-default)
48 perf record -g dwarf -- kill (test-record-graph-dwarf)
49 perf record -g fp kill (test-record-graph-fp)
50 perf record --group -e cycles,instructions kill (test-record-group)
51 perf record -e '{cycles,instructions}' kill (test-record-group1)
52 perf record -D kill (test-record-no-delay)
53 perf record -i kill (test-record-no-inherit)
54 perf record -n kill (test-record-no-samples)
55 perf record -c 100 -P kill (test-record-period)
56 perf record -R kill (test-record-raw)
57 perf stat -e cycles kill (test-stat-basic)
58 perf stat kill (test-stat-default)
59 perf stat -d kill (test-stat-detailed-1)
60 perf stat -dd kill (test-stat-detailed-2)
61 perf stat -ddd kill (test-stat-detailed-3)
62 perf stat --group -e cycles,instructions kill (test-stat-group)
63 perf stat -e '{cycles,instructions}' kill (test-stat-group1)
64 perf stat -i -e cycles kill (test-stat-no-inherit)
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
new file mode 100644
index 000000000000..f1485d8e6a0b
--- /dev/null
+++ b/tools/perf/tests/attr/base-record
@@ -0,0 +1,39 @@
1[event]
2fd=1
3group_fd=-1
4flags=0
5type=0|1
6size=96
7config=0
8sample_period=4000
9sample_type=263
10read_format=7
11disabled=1
12inherit=1
13pinned=0
14exclusive=0
15exclude_user=0
16exclude_kernel=0
17exclude_hv=0
18exclude_idle=0
19mmap=1
20comm=1
21freq=1
22inherit_stat=0
23enable_on_exec=1
24task=0
25watermark=0
26precise_ip=0
27mmap_data=0
28sample_id_all=1
29exclude_host=0
30exclude_guest=1
31exclude_callchain_kernel=0
32exclude_callchain_user=0
33wakeup_events=0
34bp_type=0
35config1=0
36config2=0
37branch_sample_type=0
38sample_regs_user=0
39sample_stack_user=0
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat
new file mode 100644
index 000000000000..4bd79a82784f
--- /dev/null
+++ b/tools/perf/tests/attr/base-stat
@@ -0,0 +1,39 @@
1[event]
2fd=1
3group_fd=-1
4flags=0
5type=0
6size=96
7config=0
8sample_period=0
9sample_type=0
10read_format=3
11disabled=1
12inherit=1
13pinned=0
14exclusive=0
15exclude_user=0
16exclude_kernel=0
17exclude_hv=0
18exclude_idle=0
19mmap=0
20comm=0
21freq=0
22inherit_stat=0
23enable_on_exec=1
24task=0
25watermark=0
26precise_ip=0
27mmap_data=0
28sample_id_all=0
29exclude_host=0
30exclude_guest=1
31exclude_callchain_kernel=0
32exclude_callchain_user=0
33wakeup_events=0
34bp_type=0
35config1=0
36config2=0
37branch_sample_type=0
38sample_regs_user=0
39sample_stack_user=0
diff --git a/tools/perf/tests/attr/test-record-basic b/tools/perf/tests/attr/test-record-basic
new file mode 100644
index 000000000000..55c0428370ca
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-basic
@@ -0,0 +1,5 @@
1[config]
2command = record
3args = kill >/dev/null 2>&1
4
5[event:base-record]
diff --git a/tools/perf/tests/attr/test-record-branch-any b/tools/perf/tests/attr/test-record-branch-any
new file mode 100644
index 000000000000..1421960ed4e9
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-any
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -b kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-any b/tools/perf/tests/attr/test-record-branch-filter-any
new file mode 100644
index 000000000000..915c4df0e0c2
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-any
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j any kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_call b/tools/perf/tests/attr/test-record-branch-filter-any_call
new file mode 100644
index 000000000000..8708dbd4f373
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-any_call
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j any_call kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=16
diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_ret b/tools/perf/tests/attr/test-record-branch-filter-any_ret
new file mode 100644
index 000000000000..0d3607a6dcbe
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-any_ret
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j any_ret kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=32
diff --git a/tools/perf/tests/attr/test-record-branch-filter-hv b/tools/perf/tests/attr/test-record-branch-filter-hv
new file mode 100644
index 000000000000..f25526740cec
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-hv
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j hv kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-ind_call b/tools/perf/tests/attr/test-record-branch-filter-ind_call
new file mode 100644
index 000000000000..e862dd179128
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-ind_call
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j ind_call kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=64
diff --git a/tools/perf/tests/attr/test-record-branch-filter-k b/tools/perf/tests/attr/test-record-branch-filter-k
new file mode 100644
index 000000000000..182971e898f5
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-k
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j k kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-branch-filter-u b/tools/perf/tests/attr/test-record-branch-filter-u
new file mode 100644
index 000000000000..83449ef9e687
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-branch-filter-u
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -j u kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=2311
8branch_sample_type=8
diff --git a/tools/perf/tests/attr/test-record-count b/tools/perf/tests/attr/test-record-count
new file mode 100644
index 000000000000..2f841de56f6b
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-count
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -c 123 kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=123
7sample_type=7
8freq=0
diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data
new file mode 100644
index 000000000000..6627c3e7534a
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-data
@@ -0,0 +1,8 @@
1[config]
2command = record
3args = -d kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=271
8mmap_data=1
diff --git a/tools/perf/tests/attr/test-record-freq b/tools/perf/tests/attr/test-record-freq
new file mode 100644
index 000000000000..600d0f8f2583
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-freq
@@ -0,0 +1,6 @@
1[config]
2command = record
3args = -F 100 kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=100
diff --git a/tools/perf/tests/attr/test-record-graph-default b/tools/perf/tests/attr/test-record-graph-default
new file mode 100644
index 000000000000..833d1849d767
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-graph-default
@@ -0,0 +1,6 @@
1[config]
2command = record
3args = -g -- kill >/dev/null 2>&1
4
5[event:base-record]
6sample_type=295
diff --git a/tools/perf/tests/attr/test-record-graph-dwarf b/tools/perf/tests/attr/test-record-graph-dwarf
new file mode 100644
index 000000000000..e93e082f5208
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-graph-dwarf
@@ -0,0 +1,10 @@
1[config]
2command = record
3args = -g dwarf -- kill >/dev/null 2>&1
4
5[event:base-record]
6sample_type=12583
7exclude_callchain_user=1
8sample_stack_user=8192
9# TODO different for each arch, no support for that now
10sample_regs_user=*
diff --git a/tools/perf/tests/attr/test-record-graph-fp b/tools/perf/tests/attr/test-record-graph-fp
new file mode 100644
index 000000000000..7cef3743f03f
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-graph-fp
@@ -0,0 +1,6 @@
1[config]
2command = record
3args = -g fp kill >/dev/null 2>&1
4
5[event:base-record]
6sample_type=295
diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group
new file mode 100644
index 000000000000..b945f770dc9e
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-group
@@ -0,0 +1,17 @@
1[config]
2command = record
3args = --group -e cycles,instructions kill >/dev/null 2>&1
4
5[event-1:base-record]
6fd=1
7group_fd=-1
8sample_type=327
9
10[event-2:base-record]
11fd=2
12group_fd=1
13config=1
14sample_type=327
15mmap=0
16comm=0
17enable_on_exec=0
diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1
new file mode 100644
index 000000000000..39bf8609538c
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-group1
@@ -0,0 +1,20 @@
1[config]
2command = record
3args = -e '{cycles,instructions}' kill >/tmp/krava 2>&1
4
5[event-1:base-record]
6fd=1
7group_fd=-1
8sample_type=327
9
10[event-2:base-record]
11fd=2
12group_fd=1
13type=0
14config=1
15sample_type=327
16mmap=0
17comm=0
18# TODO this is disabled for --group option, enabled otherwise
19# check why..
20enable_on_exec=1
diff --git a/tools/perf/tests/attr/test-record-no-delay b/tools/perf/tests/attr/test-record-no-delay
new file mode 100644
index 000000000000..f253b78cdbf2
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-no-delay
@@ -0,0 +1,9 @@
1[config]
2command = record
3args = -D kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=263
8watermark=0
9wakeup_events=1
diff --git a/tools/perf/tests/attr/test-record-no-inherit b/tools/perf/tests/attr/test-record-no-inherit
new file mode 100644
index 000000000000..9079a25cd643
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-no-inherit
@@ -0,0 +1,7 @@
1[config]
2command = record
3args = -i kill >/dev/null 2>&1
4
5[event:base-record]
6sample_type=259
7inherit=0
diff --git a/tools/perf/tests/attr/test-record-no-samples b/tools/perf/tests/attr/test-record-no-samples
new file mode 100644
index 000000000000..d0141b2418b5
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-no-samples
@@ -0,0 +1,6 @@
1[config]
2command = record
3args = -n kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=0
diff --git a/tools/perf/tests/attr/test-record-period b/tools/perf/tests/attr/test-record-period
new file mode 100644
index 000000000000..8abc5314fc52
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-period
@@ -0,0 +1,7 @@
1[config]
2command = record
3args = -c 100 -P kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=100
7freq=0
diff --git a/tools/perf/tests/attr/test-record-raw b/tools/perf/tests/attr/test-record-raw
new file mode 100644
index 000000000000..4a8ef25b5f49
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-raw
@@ -0,0 +1,7 @@
1[config]
2command = record
3args = -R kill >/dev/null 2>&1
4
5[event:base-record]
6sample_period=4000
7sample_type=1415
diff --git a/tools/perf/tests/attr/test-stat-basic b/tools/perf/tests/attr/test-stat-basic
new file mode 100644
index 000000000000..74e17881f2ba
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-basic
@@ -0,0 +1,6 @@
1[config]
2command = stat
3args = -e cycles kill >/dev/null 2>&1
4ret = 1
5
6[event:base-stat]
diff --git a/tools/perf/tests/attr/test-stat-default b/tools/perf/tests/attr/test-stat-default
new file mode 100644
index 000000000000..19270f54c96e
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-default
@@ -0,0 +1,64 @@
1[config]
2command = stat
3args = kill >/dev/null 2>&1
4ret = 1
5
6# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
7[event1:base-stat]
8fd=1
9type=1
10config=1
11
12# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
13[event2:base-stat]
14fd=2
15type=1
16config=3
17
18# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
19[event3:base-stat]
20fd=3
21type=1
22config=4
23
24# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
25[event4:base-stat]
26fd=4
27type=1
28config=2
29
30# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
31[event5:base-stat]
32fd=5
33type=0
34config=0
35
36# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
37[event6:base-stat]
38fd=6
39type=0
40config=7
41
42# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
43[event7:base-stat]
44fd=7
45type=0
46config=8
47
48# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
49[event8:base-stat]
50fd=8
51type=0
52config=1
53
54# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
55[event9:base-stat]
56fd=9
57type=0
58config=4
59
60# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
61[event10:base-stat]
62fd=10
63type=0
64config=5
diff --git a/tools/perf/tests/attr/test-stat-detailed-1 b/tools/perf/tests/attr/test-stat-detailed-1
new file mode 100644
index 000000000000..51426b87153b
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-detailed-1
@@ -0,0 +1,101 @@
1[config]
2command = stat
3args = -d kill >/dev/null 2>&1
4ret = 1
5
6
7# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
8[event1:base-stat]
9fd=1
10type=1
11config=1
12
13# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
14[event2:base-stat]
15fd=2
16type=1
17config=3
18
19# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
20[event3:base-stat]
21fd=3
22type=1
23config=4
24
25# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
26[event4:base-stat]
27fd=4
28type=1
29config=2
30
31# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
32[event5:base-stat]
33fd=5
34type=0
35config=0
36
37# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
38[event6:base-stat]
39fd=6
40type=0
41config=7
42
43# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
44[event7:base-stat]
45fd=7
46type=0
47config=8
48
49# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
50[event8:base-stat]
51fd=8
52type=0
53config=1
54
55# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
56[event9:base-stat]
57fd=9
58type=0
59config=4
60
61# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
62[event10:base-stat]
63fd=10
64type=0
65config=5
66
67# PERF_TYPE_HW_CACHE /
68# PERF_COUNT_HW_CACHE_L1D << 0 |
69# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
70# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
71[event11:base-stat]
72fd=11
73type=3
74config=0
75
76# PERF_TYPE_HW_CACHE /
77# PERF_COUNT_HW_CACHE_L1D << 0 |
78# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
79# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
80[event12:base-stat]
81fd=12
82type=3
83config=65536
84
85# PERF_TYPE_HW_CACHE /
86# PERF_COUNT_HW_CACHE_LL << 0 |
87# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
88# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
89[event13:base-stat]
90fd=13
91type=3
92config=2
93
94# PERF_TYPE_HW_CACHE,
95# PERF_COUNT_HW_CACHE_LL << 0 |
96# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
97# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
98[event14:base-stat]
99fd=14
100type=3
101config=65538
diff --git a/tools/perf/tests/attr/test-stat-detailed-2 b/tools/perf/tests/attr/test-stat-detailed-2
new file mode 100644
index 000000000000..8de5acc31c27
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-detailed-2
@@ -0,0 +1,155 @@
1[config]
2command = stat
3args = -dd kill >/dev/null 2>&1
4ret = 1
5
6
7# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
8[event1:base-stat]
9fd=1
10type=1
11config=1
12
13# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
14[event2:base-stat]
15fd=2
16type=1
17config=3
18
19# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
20[event3:base-stat]
21fd=3
22type=1
23config=4
24
25# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
26[event4:base-stat]
27fd=4
28type=1
29config=2
30
31# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
32[event5:base-stat]
33fd=5
34type=0
35config=0
36
37# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
38[event6:base-stat]
39fd=6
40type=0
41config=7
42
43# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
44[event7:base-stat]
45fd=7
46type=0
47config=8
48
49# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
50[event8:base-stat]
51fd=8
52type=0
53config=1
54
55# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
56[event9:base-stat]
57fd=9
58type=0
59config=4
60
61# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
62[event10:base-stat]
63fd=10
64type=0
65config=5
66
67# PERF_TYPE_HW_CACHE /
68# PERF_COUNT_HW_CACHE_L1D << 0 |
69# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
70# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
71[event11:base-stat]
72fd=11
73type=3
74config=0
75
76# PERF_TYPE_HW_CACHE /
77# PERF_COUNT_HW_CACHE_L1D << 0 |
78# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
79# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
80[event12:base-stat]
81fd=12
82type=3
83config=65536
84
85# PERF_TYPE_HW_CACHE /
86# PERF_COUNT_HW_CACHE_LL << 0 |
87# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
88# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
89[event13:base-stat]
90fd=13
91type=3
92config=2
93
94# PERF_TYPE_HW_CACHE,
95# PERF_COUNT_HW_CACHE_LL << 0 |
96# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
97# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
98[event14:base-stat]
99fd=14
100type=3
101config=65538
102
103# PERF_TYPE_HW_CACHE,
104# PERF_COUNT_HW_CACHE_L1I << 0 |
105# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
106# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
107[event15:base-stat]
108fd=15
109type=3
110config=1
111
112# PERF_TYPE_HW_CACHE,
113# PERF_COUNT_HW_CACHE_L1I << 0 |
114# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
115# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
116[event16:base-stat]
117fd=16
118type=3
119config=65537
120
121# PERF_TYPE_HW_CACHE,
122# PERF_COUNT_HW_CACHE_DTLB << 0 |
123# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
124# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
125[event17:base-stat]
126fd=17
127type=3
128config=3
129
130# PERF_TYPE_HW_CACHE,
131# PERF_COUNT_HW_CACHE_DTLB << 0 |
132# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
133# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
134[event18:base-stat]
135fd=18
136type=3
137config=65539
138
139# PERF_TYPE_HW_CACHE,
140# PERF_COUNT_HW_CACHE_ITLB << 0 |
141# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
142# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
143[event19:base-stat]
144fd=19
145type=3
146config=4
147
148# PERF_TYPE_HW_CACHE,
149# PERF_COUNT_HW_CACHE_ITLB << 0 |
150# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
151# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
152[event20:base-stat]
153fd=20
154type=3
155config=65540
diff --git a/tools/perf/tests/attr/test-stat-detailed-3 b/tools/perf/tests/attr/test-stat-detailed-3
new file mode 100644
index 000000000000..0a1f45bf7d79
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-detailed-3
@@ -0,0 +1,173 @@
1[config]
2command = stat
3args = -ddd kill >/dev/null 2>&1
4ret = 1
5
6
7# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK
8[event1:base-stat]
9fd=1
10type=1
11config=1
12
13# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES
14[event2:base-stat]
15fd=2
16type=1
17config=3
18
19# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS
20[event3:base-stat]
21fd=3
22type=1
23config=4
24
25# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS
26[event4:base-stat]
27fd=4
28type=1
29config=2
30
31# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES
32[event5:base-stat]
33fd=5
34type=0
35config=0
36
37# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
38[event6:base-stat]
39fd=6
40type=0
41config=7
42
43# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND
44[event7:base-stat]
45fd=7
46type=0
47config=8
48
49# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS
50[event8:base-stat]
51fd=8
52type=0
53config=1
54
55# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS
56[event9:base-stat]
57fd=9
58type=0
59config=4
60
61# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES
62[event10:base-stat]
63fd=10
64type=0
65config=5
66
67# PERF_TYPE_HW_CACHE /
68# PERF_COUNT_HW_CACHE_L1D << 0 |
69# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
70# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
71[event11:base-stat]
72fd=11
73type=3
74config=0
75
76# PERF_TYPE_HW_CACHE /
77# PERF_COUNT_HW_CACHE_L1D << 0 |
78# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
79# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
80[event12:base-stat]
81fd=12
82type=3
83config=65536
84
85# PERF_TYPE_HW_CACHE /
86# PERF_COUNT_HW_CACHE_LL << 0 |
87# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
88# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
89[event13:base-stat]
90fd=13
91type=3
92config=2
93
94# PERF_TYPE_HW_CACHE,
95# PERF_COUNT_HW_CACHE_LL << 0 |
96# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
97# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
98[event14:base-stat]
99fd=14
100type=3
101config=65538
102
103# PERF_TYPE_HW_CACHE,
104# PERF_COUNT_HW_CACHE_L1I << 0 |
105# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
106# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
107[event15:base-stat]
108fd=15
109type=3
110config=1
111
112# PERF_TYPE_HW_CACHE,
113# PERF_COUNT_HW_CACHE_L1I << 0 |
114# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
115# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
116[event16:base-stat]
117fd=16
118type=3
119config=65537
120
121# PERF_TYPE_HW_CACHE,
122# PERF_COUNT_HW_CACHE_DTLB << 0 |
123# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
124# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
125[event17:base-stat]
126fd=17
127type=3
128config=3
129
130# PERF_TYPE_HW_CACHE,
131# PERF_COUNT_HW_CACHE_DTLB << 0 |
132# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
133# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
134[event18:base-stat]
135fd=18
136type=3
137config=65539
138
139# PERF_TYPE_HW_CACHE,
140# PERF_COUNT_HW_CACHE_ITLB << 0 |
141# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
142# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
143[event19:base-stat]
144fd=19
145type=3
146config=4
147
148# PERF_TYPE_HW_CACHE,
149# PERF_COUNT_HW_CACHE_ITLB << 0 |
150# (PERF_COUNT_HW_CACHE_OP_READ << 8) |
151# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
152[event20:base-stat]
153fd=20
154type=3
155config=65540
156
157# PERF_TYPE_HW_CACHE,
158# PERF_COUNT_HW_CACHE_L1D << 0 |
159# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
160# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
161[event21:base-stat]
162fd=21
163type=3
164config=512
165
166# PERF_TYPE_HW_CACHE,
167# PERF_COUNT_HW_CACHE_L1D << 0 |
168# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
169# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
170[event22:base-stat]
171fd=22
172type=3
173config=66048
diff --git a/tools/perf/tests/attr/test-stat-group b/tools/perf/tests/attr/test-stat-group
new file mode 100644
index 000000000000..fdc1596a8862
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-group
@@ -0,0 +1,15 @@
1[config]
2command = stat
3args = --group -e cycles,instructions kill >/dev/null 2>&1
4ret = 1
5
6[event-1:base-stat]
7fd=1
8group_fd=-1
9
10[event-2:base-stat]
11fd=2
12group_fd=1
13config=1
14disabled=0
15enable_on_exec=0
diff --git a/tools/perf/tests/attr/test-stat-group1 b/tools/perf/tests/attr/test-stat-group1
new file mode 100644
index 000000000000..5ae2718de864
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-group1
@@ -0,0 +1,17 @@
1[config]
2command = stat
3args = -e '{cycles,instructions}' kill >/dev/null 2>&1
4ret = 1
5
6[event-1:base-stat]
7fd=1
8group_fd=-1
9
10[event-2:base-stat]
11fd=2
12group_fd=1
13config=1
14# TODO both disabled and enable_on_exec are disabled for --group option,
15# enabled otherwise, check why..
16disabled=1
17enable_on_exec=1
diff --git a/tools/perf/tests/attr/test-stat-no-inherit b/tools/perf/tests/attr/test-stat-no-inherit
new file mode 100644
index 000000000000..d54b2a1e3e28
--- /dev/null
+++ b/tools/perf/tests/attr/test-stat-no-inherit
@@ -0,0 +1,7 @@
1[config]
2command = stat
3args = -i -e cycles kill >/dev/null 2>&1
4ret = 1
5
6[event:base-stat]
7inherit=0
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
new file mode 100644
index 000000000000..5d4354e24457
--- /dev/null
+++ b/tools/perf/tests/builtin-test.c
@@ -0,0 +1,1550 @@
1/*
2 * builtin-test.c
3 *
4 * Builtin regression testing command: ever growing number of sanity tests
5 */
6#include "builtin.h"
7
8#include "util/cache.h"
9#include "util/color.h"
10#include "util/debug.h"
11#include "util/debugfs.h"
12#include "util/evlist.h"
13#include "util/machine.h"
14#include "util/parse-options.h"
15#include "util/parse-events.h"
16#include "util/symbol.h"
17#include "util/thread_map.h"
18#include "util/pmu.h"
19#include "event-parse.h"
20#include "../../include/linux/hw_breakpoint.h"
21
22#include <sys/mman.h>
23
24static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused,
25 struct symbol *sym)
26{
27 bool *visited = symbol__priv(sym);
28 *visited = true;
29 return 0;
30}
31
32static int test__vmlinux_matches_kallsyms(void)
33{
34 int err = -1;
35 struct rb_node *nd;
36 struct symbol *sym;
37 struct map *kallsyms_map, *vmlinux_map;
38 struct machine kallsyms, vmlinux;
39 enum map_type type = MAP__FUNCTION;
40 struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
41
42 /*
43 * Step 1:
44 *
45 * Init the machines that will hold kernel, modules obtained from
46 * both vmlinux + .ko files and from /proc/kallsyms split by modules.
47 */
48 machine__init(&kallsyms, "", HOST_KERNEL_ID);
49 machine__init(&vmlinux, "", HOST_KERNEL_ID);
50
51 /*
52 * Step 2:
53 *
54 * Create the kernel maps for kallsyms and the DSO where we will then
55 * load /proc/kallsyms. Also create the modules maps from /proc/modules
56 * and find the .ko files that match them in /lib/modules/`uname -r`/.
57 */
58 if (machine__create_kernel_maps(&kallsyms) < 0) {
59 pr_debug("machine__create_kernel_maps ");
60 return -1;
61 }
62
63 /*
64 * Step 3:
65 *
66 * Load and split /proc/kallsyms into multiple maps, one per module.
67 */
68 if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
69 pr_debug("dso__load_kallsyms ");
70 goto out;
71 }
72
73 /*
74 * Step 4:
75 *
76 * kallsyms will be internally on demand sorted by name so that we can
77 * find the reference relocation * symbol, i.e. the symbol we will use
78 * to see if the running kernel was relocated by checking if it has the
79 * same value in the vmlinux file we load.
80 */
81 kallsyms_map = machine__kernel_map(&kallsyms, type);
82
83 sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
84 if (sym == NULL) {
85 pr_debug("dso__find_symbol_by_name ");
86 goto out;
87 }
88
89 ref_reloc_sym.addr = sym->start;
90
91 /*
92 * Step 5:
93 *
94 * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
95 */
96 if (machine__create_kernel_maps(&vmlinux) < 0) {
97 pr_debug("machine__create_kernel_maps ");
98 goto out;
99 }
100
101 vmlinux_map = machine__kernel_map(&vmlinux, type);
102 map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;
103
104 /*
105 * Step 6:
106 *
107 * Locate a vmlinux file in the vmlinux path that has a buildid that
108 * matches the one of the running kernel.
109 *
110 * While doing that look if we find the ref reloc symbol, if we find it
111 * we'll have its ref_reloc_symbol.unrelocated_addr and then
112 * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
113 * to fixup the symbols.
114 */
115 if (machine__load_vmlinux_path(&vmlinux, type,
116 vmlinux_matches_kallsyms_filter) <= 0) {
117 pr_debug("machine__load_vmlinux_path ");
118 goto out;
119 }
120
121 err = 0;
122 /*
123 * Step 7:
124 *
125 * Now look at the symbols in the vmlinux DSO and check if we find all of them
126 * in the kallsyms dso. For the ones that are in both, check its names and
127 * end addresses too.
128 */
129 for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
130 struct symbol *pair, *first_pair;
131 bool backwards = true;
132
133 sym = rb_entry(nd, struct symbol, rb_node);
134
135 if (sym->start == sym->end)
136 continue;
137
138 first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
139 pair = first_pair;
140
141 if (pair && pair->start == sym->start) {
142next_pair:
143 if (strcmp(sym->name, pair->name) == 0) {
144 /*
145 * kallsyms don't have the symbol end, so we
146 * set that by using the next symbol start - 1,
147 * in some cases we get this up to a page
148 * wrong, trace_kmalloc when I was developing
149 * this code was one such example, 2106 bytes
150 * off the real size. More than that and we
151 * _really_ have a problem.
152 */
153 s64 skew = sym->end - pair->end;
154 if (llabs(skew) < page_size)
155 continue;
156
157 pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n",
158 sym->start, sym->name, sym->end, pair->end);
159 } else {
160 struct rb_node *nnd;
161detour:
162 nnd = backwards ? rb_prev(&pair->rb_node) :
163 rb_next(&pair->rb_node);
164 if (nnd) {
165 struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
166
167 if (next->start == sym->start) {
168 pair = next;
169 goto next_pair;
170 }
171 }
172
173 if (backwards) {
174 backwards = false;
175 pair = first_pair;
176 goto detour;
177 }
178
179 pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n",
180 sym->start, sym->name, pair->name);
181 }
182 } else
183 pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name);
184
185 err = -1;
186 }
187
188 if (!verbose)
189 goto out;
190
191 pr_info("Maps only in vmlinux:\n");
192
193 for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
194 struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
195 /*
196 * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
197 * the kernel will have the path for the vmlinux file being used,
198 * so use the short name, less descriptive but the same ("[kernel]" in
199 * both cases.
200 */
201 pair = map_groups__find_by_name(&kallsyms.kmaps, type,
202 (pos->dso->kernel ?
203 pos->dso->short_name :
204 pos->dso->name));
205 if (pair)
206 pair->priv = 1;
207 else
208 map__fprintf(pos, stderr);
209 }
210
211 pr_info("Maps in vmlinux with a different name in kallsyms:\n");
212
213 for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
214 struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
215
216 pair = map_groups__find(&kallsyms.kmaps, type, pos->start);
217 if (pair == NULL || pair->priv)
218 continue;
219
220 if (pair->start == pos->start) {
221 pair->priv = 1;
222 pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
223 pos->start, pos->end, pos->pgoff, pos->dso->name);
224 if (pos->pgoff != pair->pgoff || pos->end != pair->end)
225 pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "",
226 pair->start, pair->end, pair->pgoff);
227 pr_info(" %s\n", pair->dso->name);
228 pair->priv = 1;
229 }
230 }
231
232 pr_info("Maps only in kallsyms:\n");
233
234 for (nd = rb_first(&kallsyms.kmaps.maps[type]);
235 nd; nd = rb_next(nd)) {
236 struct map *pos = rb_entry(nd, struct map, rb_node);
237
238 if (!pos->priv)
239 map__fprintf(pos, stderr);
240 }
241out:
242 return err;
243}
244
245#include "util/cpumap.h"
246#include "util/evsel.h"
247#include <sys/types.h>
248
249static int trace_event__id(const char *evname)
250{
251 char *filename;
252 int err = -1, fd;
253
254 if (asprintf(&filename,
255 "%s/syscalls/%s/id",
256 tracing_events_path, evname) < 0)
257 return -1;
258
259 fd = open(filename, O_RDONLY);
260 if (fd >= 0) {
261 char id[16];
262 if (read(fd, id, sizeof(id)) > 0)
263 err = atoi(id);
264 close(fd);
265 }
266
267 free(filename);
268 return err;
269}
270
271static int test__open_syscall_event(void)
272{
273 int err = -1, fd;
274 struct thread_map *threads;
275 struct perf_evsel *evsel;
276 struct perf_event_attr attr;
277 unsigned int nr_open_calls = 111, i;
278 int id = trace_event__id("sys_enter_open");
279
280 if (id < 0) {
281 pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
282 return -1;
283 }
284
285 threads = thread_map__new(-1, getpid(), UINT_MAX);
286 if (threads == NULL) {
287 pr_debug("thread_map__new\n");
288 return -1;
289 }
290
291 memset(&attr, 0, sizeof(attr));
292 attr.type = PERF_TYPE_TRACEPOINT;
293 attr.config = id;
294 evsel = perf_evsel__new(&attr, 0);
295 if (evsel == NULL) {
296 pr_debug("perf_evsel__new\n");
297 goto out_thread_map_delete;
298 }
299
300 if (perf_evsel__open_per_thread(evsel, threads) < 0) {
301 pr_debug("failed to open counter: %s, "
302 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
303 strerror(errno));
304 goto out_evsel_delete;
305 }
306
307 for (i = 0; i < nr_open_calls; ++i) {
308 fd = open("/etc/passwd", O_RDONLY);
309 close(fd);
310 }
311
312 if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
313 pr_debug("perf_evsel__read_on_cpu\n");
314 goto out_close_fd;
315 }
316
317 if (evsel->counts->cpu[0].val != nr_open_calls) {
318 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
319 nr_open_calls, evsel->counts->cpu[0].val);
320 goto out_close_fd;
321 }
322
323 err = 0;
324out_close_fd:
325 perf_evsel__close_fd(evsel, 1, threads->nr);
326out_evsel_delete:
327 perf_evsel__delete(evsel);
328out_thread_map_delete:
329 thread_map__delete(threads);
330 return err;
331}
332
333#include <sched.h>
334
335static int test__open_syscall_event_on_all_cpus(void)
336{
337 int err = -1, fd, cpu;
338 struct thread_map *threads;
339 struct cpu_map *cpus;
340 struct perf_evsel *evsel;
341 struct perf_event_attr attr;
342 unsigned int nr_open_calls = 111, i;
343 cpu_set_t cpu_set;
344 int id = trace_event__id("sys_enter_open");
345
346 if (id < 0) {
347 pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
348 return -1;
349 }
350
351 threads = thread_map__new(-1, getpid(), UINT_MAX);
352 if (threads == NULL) {
353 pr_debug("thread_map__new\n");
354 return -1;
355 }
356
357 cpus = cpu_map__new(NULL);
358 if (cpus == NULL) {
359 pr_debug("cpu_map__new\n");
360 goto out_thread_map_delete;
361 }
362
363
364 CPU_ZERO(&cpu_set);
365
366 memset(&attr, 0, sizeof(attr));
367 attr.type = PERF_TYPE_TRACEPOINT;
368 attr.config = id;
369 evsel = perf_evsel__new(&attr, 0);
370 if (evsel == NULL) {
371 pr_debug("perf_evsel__new\n");
372 goto out_thread_map_delete;
373 }
374
375 if (perf_evsel__open(evsel, cpus, threads) < 0) {
376 pr_debug("failed to open counter: %s, "
377 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
378 strerror(errno));
379 goto out_evsel_delete;
380 }
381
382 for (cpu = 0; cpu < cpus->nr; ++cpu) {
383 unsigned int ncalls = nr_open_calls + cpu;
384 /*
385 * XXX eventually lift this restriction in a way that
386 * keeps perf building on older glibc installations
387 * without CPU_ALLOC. 1024 cpus in 2010 still seems
388 * a reasonable upper limit tho :-)
389 */
390 if (cpus->map[cpu] >= CPU_SETSIZE) {
391 pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
392 continue;
393 }
394
395 CPU_SET(cpus->map[cpu], &cpu_set);
396 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
397 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
398 cpus->map[cpu],
399 strerror(errno));
400 goto out_close_fd;
401 }
402 for (i = 0; i < ncalls; ++i) {
403 fd = open("/etc/passwd", O_RDONLY);
404 close(fd);
405 }
406 CPU_CLR(cpus->map[cpu], &cpu_set);
407 }
408
409 /*
410 * Here we need to explicitely preallocate the counts, as if
411 * we use the auto allocation it will allocate just for 1 cpu,
412 * as we start by cpu 0.
413 */
414 if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
415 pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
416 goto out_close_fd;
417 }
418
419 err = 0;
420
421 for (cpu = 0; cpu < cpus->nr; ++cpu) {
422 unsigned int expected;
423
424 if (cpus->map[cpu] >= CPU_SETSIZE)
425 continue;
426
427 if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
428 pr_debug("perf_evsel__read_on_cpu\n");
429 err = -1;
430 break;
431 }
432
433 expected = nr_open_calls + cpu;
434 if (evsel->counts->cpu[cpu].val != expected) {
435 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
436 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
437 err = -1;
438 }
439 }
440
441out_close_fd:
442 perf_evsel__close_fd(evsel, 1, threads->nr);
443out_evsel_delete:
444 perf_evsel__delete(evsel);
445out_thread_map_delete:
446 thread_map__delete(threads);
447 return err;
448}
449
450/*
451 * This test will generate random numbers of calls to some getpid syscalls,
452 * then establish an mmap for a group of events that are created to monitor
453 * the syscalls.
454 *
455 * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
456 * sample.id field to map back to its respective perf_evsel instance.
457 *
458 * Then it checks if the number of syscalls reported as perf events by
459 * the kernel corresponds to the number of syscalls made.
460 */
461static int test__basic_mmap(void)
462{
463 int err = -1;
464 union perf_event *event;
465 struct thread_map *threads;
466 struct cpu_map *cpus;
467 struct perf_evlist *evlist;
468 struct perf_event_attr attr = {
469 .type = PERF_TYPE_TRACEPOINT,
470 .read_format = PERF_FORMAT_ID,
471 .sample_type = PERF_SAMPLE_ID,
472 .watermark = 0,
473 };
474 cpu_set_t cpu_set;
475 const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
476 "getpgid", };
477 pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
478 (void*)getpgid };
479#define nsyscalls ARRAY_SIZE(syscall_names)
480 int ids[nsyscalls];
481 unsigned int nr_events[nsyscalls],
482 expected_nr_events[nsyscalls], i, j;
483 struct perf_evsel *evsels[nsyscalls], *evsel;
484
485 for (i = 0; i < nsyscalls; ++i) {
486 char name[64];
487
488 snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
489 ids[i] = trace_event__id(name);
490 if (ids[i] < 0) {
491 pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
492 return -1;
493 }
494 nr_events[i] = 0;
495 expected_nr_events[i] = random() % 257;
496 }
497
498 threads = thread_map__new(-1, getpid(), UINT_MAX);
499 if (threads == NULL) {
500 pr_debug("thread_map__new\n");
501 return -1;
502 }
503
504 cpus = cpu_map__new(NULL);
505 if (cpus == NULL) {
506 pr_debug("cpu_map__new\n");
507 goto out_free_threads;
508 }
509
510 CPU_ZERO(&cpu_set);
511 CPU_SET(cpus->map[0], &cpu_set);
512 sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
513 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
514 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
515 cpus->map[0], strerror(errno));
516 goto out_free_cpus;
517 }
518
519 evlist = perf_evlist__new(cpus, threads);
520 if (evlist == NULL) {
521 pr_debug("perf_evlist__new\n");
522 goto out_free_cpus;
523 }
524
525 /* anonymous union fields, can't be initialized above */
526 attr.wakeup_events = 1;
527 attr.sample_period = 1;
528
529 for (i = 0; i < nsyscalls; ++i) {
530 attr.config = ids[i];
531 evsels[i] = perf_evsel__new(&attr, i);
532 if (evsels[i] == NULL) {
533 pr_debug("perf_evsel__new\n");
534 goto out_free_evlist;
535 }
536
537 perf_evlist__add(evlist, evsels[i]);
538
539 if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
540 pr_debug("failed to open counter: %s, "
541 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
542 strerror(errno));
543 goto out_close_fd;
544 }
545 }
546
547 if (perf_evlist__mmap(evlist, 128, true) < 0) {
548 pr_debug("failed to mmap events: %d (%s)\n", errno,
549 strerror(errno));
550 goto out_close_fd;
551 }
552
553 for (i = 0; i < nsyscalls; ++i)
554 for (j = 0; j < expected_nr_events[i]; ++j) {
555 int foo = syscalls[i]();
556 ++foo;
557 }
558
559 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
560 struct perf_sample sample;
561
562 if (event->header.type != PERF_RECORD_SAMPLE) {
563 pr_debug("unexpected %s event\n",
564 perf_event__name(event->header.type));
565 goto out_munmap;
566 }
567
568 err = perf_evlist__parse_sample(evlist, event, &sample);
569 if (err) {
570 pr_err("Can't parse sample, err = %d\n", err);
571 goto out_munmap;
572 }
573
574 evsel = perf_evlist__id2evsel(evlist, sample.id);
575 if (evsel == NULL) {
576 pr_debug("event with id %" PRIu64
577 " doesn't map to an evsel\n", sample.id);
578 goto out_munmap;
579 }
580 nr_events[evsel->idx]++;
581 }
582
583 list_for_each_entry(evsel, &evlist->entries, node) {
584 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
585 pr_debug("expected %d %s events, got %d\n",
586 expected_nr_events[evsel->idx],
587 perf_evsel__name(evsel), nr_events[evsel->idx]);
588 goto out_munmap;
589 }
590 }
591
592 err = 0;
593out_munmap:
594 perf_evlist__munmap(evlist);
595out_close_fd:
596 for (i = 0; i < nsyscalls; ++i)
597 perf_evsel__close_fd(evsels[i], 1, threads->nr);
598out_free_evlist:
599 perf_evlist__delete(evlist);
600out_free_cpus:
601 cpu_map__delete(cpus);
602out_free_threads:
603 thread_map__delete(threads);
604 return err;
605#undef nsyscalls
606}
607
608static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
609{
610 int i, cpu = -1, nrcpus = 1024;
611realloc:
612 CPU_ZERO(maskp);
613
614 if (sched_getaffinity(pid, sizeof(*maskp), maskp) == -1) {
615 if (errno == EINVAL && nrcpus < (1024 << 8)) {
616 nrcpus = nrcpus << 2;
617 goto realloc;
618 }
619 perror("sched_getaffinity");
620 return -1;
621 }
622
623 for (i = 0; i < nrcpus; i++) {
624 if (CPU_ISSET(i, maskp)) {
625 if (cpu == -1)
626 cpu = i;
627 else
628 CPU_CLR(i, maskp);
629 }
630 }
631
632 return cpu;
633}
634
635static int test__PERF_RECORD(void)
636{
637 struct perf_record_opts opts = {
638 .target = {
639 .uid = UINT_MAX,
640 .uses_mmap = true,
641 },
642 .no_delay = true,
643 .freq = 10,
644 .mmap_pages = 256,
645 };
646 cpu_set_t cpu_mask;
647 size_t cpu_mask_size = sizeof(cpu_mask);
648 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
649 struct perf_evsel *evsel;
650 struct perf_sample sample;
651 const char *cmd = "sleep";
652 const char *argv[] = { cmd, "1", NULL, };
653 char *bname;
654 u64 prev_time = 0;
655 bool found_cmd_mmap = false,
656 found_libc_mmap = false,
657 found_vdso_mmap = false,
658 found_ld_mmap = false;
659 int err = -1, errs = 0, i, wakeups = 0;
660 u32 cpu;
661 int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, };
662
663 if (evlist == NULL || argv == NULL) {
664 pr_debug("Not enough memory to create evlist\n");
665 goto out;
666 }
667
668 /*
669 * We need at least one evsel in the evlist, use the default
670 * one: "cycles".
671 */
672 err = perf_evlist__add_default(evlist);
673 if (err < 0) {
674 pr_debug("Not enough memory to create evsel\n");
675 goto out_delete_evlist;
676 }
677
678 /*
679 * Create maps of threads and cpus to monitor. In this case
680 * we start with all threads and cpus (-1, -1) but then in
681 * perf_evlist__prepare_workload we'll fill in the only thread
682 * we're monitoring, the one forked there.
683 */
684 err = perf_evlist__create_maps(evlist, &opts.target);
685 if (err < 0) {
686 pr_debug("Not enough memory to create thread/cpu maps\n");
687 goto out_delete_evlist;
688 }
689
690 /*
691 * Prepare the workload in argv[] to run, it'll fork it, and then wait
692 * for perf_evlist__start_workload() to exec it. This is done this way
693 * so that we have time to open the evlist (calling sys_perf_event_open
694 * on all the fds) and then mmap them.
695 */
696 err = perf_evlist__prepare_workload(evlist, &opts, argv);
697 if (err < 0) {
698 pr_debug("Couldn't run the workload!\n");
699 goto out_delete_evlist;
700 }
701
702 /*
703 * Config the evsels, setting attr->comm on the first one, etc.
704 */
705 evsel = perf_evlist__first(evlist);
706 evsel->attr.sample_type |= PERF_SAMPLE_CPU;
707 evsel->attr.sample_type |= PERF_SAMPLE_TID;
708 evsel->attr.sample_type |= PERF_SAMPLE_TIME;
709 perf_evlist__config_attrs(evlist, &opts);
710
711 err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
712 if (err < 0) {
713 pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno));
714 goto out_delete_evlist;
715 }
716
717 cpu = err;
718
719 /*
720 * So that we can check perf_sample.cpu on all the samples.
721 */
722 if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {
723 pr_debug("sched_setaffinity: %s\n", strerror(errno));
724 goto out_delete_evlist;
725 }
726
727 /*
728 * Call sys_perf_event_open on all the fds on all the evsels,
729 * grouping them if asked to.
730 */
731 err = perf_evlist__open(evlist);
732 if (err < 0) {
733 pr_debug("perf_evlist__open: %s\n", strerror(errno));
734 goto out_delete_evlist;
735 }
736
737 /*
738 * mmap the first fd on a given CPU and ask for events for the other
739 * fds in the same CPU to be injected in the same mmap ring buffer
740 * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)).
741 */
742 err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
743 if (err < 0) {
744 pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
745 goto out_delete_evlist;
746 }
747
748 /*
749 * Now that all is properly set up, enable the events, they will
750 * count just on workload.pid, which will start...
751 */
752 perf_evlist__enable(evlist);
753
754 /*
755 * Now!
756 */
757 perf_evlist__start_workload(evlist);
758
759 while (1) {
760 int before = total_events;
761
762 for (i = 0; i < evlist->nr_mmaps; i++) {
763 union perf_event *event;
764
765 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
766 const u32 type = event->header.type;
767 const char *name = perf_event__name(type);
768
769 ++total_events;
770 if (type < PERF_RECORD_MAX)
771 nr_events[type]++;
772
773 err = perf_evlist__parse_sample(evlist, event, &sample);
774 if (err < 0) {
775 if (verbose)
776 perf_event__fprintf(event, stderr);
777 pr_debug("Couldn't parse sample\n");
778 goto out_err;
779 }
780
781 if (verbose) {
782 pr_info("%" PRIu64" %d ", sample.time, sample.cpu);
783 perf_event__fprintf(event, stderr);
784 }
785
786 if (prev_time > sample.time) {
787 pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n",
788 name, prev_time, sample.time);
789 ++errs;
790 }
791
792 prev_time = sample.time;
793
794 if (sample.cpu != cpu) {
795 pr_debug("%s with unexpected cpu, expected %d, got %d\n",
796 name, cpu, sample.cpu);
797 ++errs;
798 }
799
800 if ((pid_t)sample.pid != evlist->workload.pid) {
801 pr_debug("%s with unexpected pid, expected %d, got %d\n",
802 name, evlist->workload.pid, sample.pid);
803 ++errs;
804 }
805
806 if ((pid_t)sample.tid != evlist->workload.pid) {
807 pr_debug("%s with unexpected tid, expected %d, got %d\n",
808 name, evlist->workload.pid, sample.tid);
809 ++errs;
810 }
811
812 if ((type == PERF_RECORD_COMM ||
813 type == PERF_RECORD_MMAP ||
814 type == PERF_RECORD_FORK ||
815 type == PERF_RECORD_EXIT) &&
816 (pid_t)event->comm.pid != evlist->workload.pid) {
817 pr_debug("%s with unexpected pid/tid\n", name);
818 ++errs;
819 }
820
821 if ((type == PERF_RECORD_COMM ||
822 type == PERF_RECORD_MMAP) &&
823 event->comm.pid != event->comm.tid) {
824 pr_debug("%s with different pid/tid!\n", name);
825 ++errs;
826 }
827
828 switch (type) {
829 case PERF_RECORD_COMM:
830 if (strcmp(event->comm.comm, cmd)) {
831 pr_debug("%s with unexpected comm!\n", name);
832 ++errs;
833 }
834 break;
835 case PERF_RECORD_EXIT:
836 goto found_exit;
837 case PERF_RECORD_MMAP:
838 bname = strrchr(event->mmap.filename, '/');
839 if (bname != NULL) {
840 if (!found_cmd_mmap)
841 found_cmd_mmap = !strcmp(bname + 1, cmd);
842 if (!found_libc_mmap)
843 found_libc_mmap = !strncmp(bname + 1, "libc", 4);
844 if (!found_ld_mmap)
845 found_ld_mmap = !strncmp(bname + 1, "ld", 2);
846 } else if (!found_vdso_mmap)
847 found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]");
848 break;
849
850 case PERF_RECORD_SAMPLE:
851 /* Just ignore samples for now */
852 break;
853 default:
854 pr_debug("Unexpected perf_event->header.type %d!\n",
855 type);
856 ++errs;
857 }
858 }
859 }
860
861 /*
862 * We don't use poll here because at least at 3.1 times the
863 * PERF_RECORD_{!SAMPLE} events don't honour
864 * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does.
865 */
866 if (total_events == before && false)
867 poll(evlist->pollfd, evlist->nr_fds, -1);
868
869 sleep(1);
870 if (++wakeups > 5) {
871 pr_debug("No PERF_RECORD_EXIT event!\n");
872 break;
873 }
874 }
875
876found_exit:
877 if (nr_events[PERF_RECORD_COMM] > 1) {
878 pr_debug("Excessive number of PERF_RECORD_COMM events!\n");
879 ++errs;
880 }
881
882 if (nr_events[PERF_RECORD_COMM] == 0) {
883 pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd);
884 ++errs;
885 }
886
887 if (!found_cmd_mmap) {
888 pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd);
889 ++errs;
890 }
891
892 if (!found_libc_mmap) {
893 pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc");
894 ++errs;
895 }
896
897 if (!found_ld_mmap) {
898 pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld");
899 ++errs;
900 }
901
902 if (!found_vdso_mmap) {
903 pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]");
904 ++errs;
905 }
906out_err:
907 perf_evlist__munmap(evlist);
908out_delete_evlist:
909 perf_evlist__delete(evlist);
910out:
911 return (err < 0 || errs > 0) ? -1 : 0;
912}
913
914
915#if defined(__x86_64__) || defined(__i386__)
916
917#define barrier() asm volatile("" ::: "memory")
918
919static u64 rdpmc(unsigned int counter)
920{
921 unsigned int low, high;
922
923 asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter));
924
925 return low | ((u64)high) << 32;
926}
927
928static u64 rdtsc(void)
929{
930 unsigned int low, high;
931
932 asm volatile("rdtsc" : "=a" (low), "=d" (high));
933
934 return low | ((u64)high) << 32;
935}
936
937static u64 mmap_read_self(void *addr)
938{
939 struct perf_event_mmap_page *pc = addr;
940 u32 seq, idx, time_mult = 0, time_shift = 0;
941 u64 count, cyc = 0, time_offset = 0, enabled, running, delta;
942
943 do {
944 seq = pc->lock;
945 barrier();
946
947 enabled = pc->time_enabled;
948 running = pc->time_running;
949
950 if (enabled != running) {
951 cyc = rdtsc();
952 time_mult = pc->time_mult;
953 time_shift = pc->time_shift;
954 time_offset = pc->time_offset;
955 }
956
957 idx = pc->index;
958 count = pc->offset;
959 if (idx)
960 count += rdpmc(idx - 1);
961
962 barrier();
963 } while (pc->lock != seq);
964
965 if (enabled != running) {
966 u64 quot, rem;
967
968 quot = (cyc >> time_shift);
969 rem = cyc & ((1 << time_shift) - 1);
970 delta = time_offset + quot * time_mult +
971 ((rem * time_mult) >> time_shift);
972
973 enabled += delta;
974 if (idx)
975 running += delta;
976
977 quot = count / running;
978 rem = count % running;
979 count = quot * enabled + (rem * enabled) / running;
980 }
981
982 return count;
983}
984
985/*
986 * If the RDPMC instruction faults then signal this back to the test parent task:
987 */
988static void segfault_handler(int sig __maybe_unused,
989 siginfo_t *info __maybe_unused,
990 void *uc __maybe_unused)
991{
992 exit(-1);
993}
994
995static int __test__rdpmc(void)
996{
997 volatile int tmp = 0;
998 u64 i, loops = 1000;
999 int n;
1000 int fd;
1001 void *addr;
1002 struct perf_event_attr attr = {
1003 .type = PERF_TYPE_HARDWARE,
1004 .config = PERF_COUNT_HW_INSTRUCTIONS,
1005 .exclude_kernel = 1,
1006 };
1007 u64 delta_sum = 0;
1008 struct sigaction sa;
1009
1010 sigfillset(&sa.sa_mask);
1011 sa.sa_sigaction = segfault_handler;
1012 sigaction(SIGSEGV, &sa, NULL);
1013
1014 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
1015 if (fd < 0) {
1016 pr_err("Error: sys_perf_event_open() syscall returned "
1017 "with %d (%s)\n", fd, strerror(errno));
1018 return -1;
1019 }
1020
1021 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
1022 if (addr == (void *)(-1)) {
1023 pr_err("Error: mmap() syscall returned with (%s)\n",
1024 strerror(errno));
1025 goto out_close;
1026 }
1027
1028 for (n = 0; n < 6; n++) {
1029 u64 stamp, now, delta;
1030
1031 stamp = mmap_read_self(addr);
1032
1033 for (i = 0; i < loops; i++)
1034 tmp++;
1035
1036 now = mmap_read_self(addr);
1037 loops *= 10;
1038
1039 delta = now - stamp;
1040 pr_debug("%14d: %14Lu\n", n, (long long)delta);
1041
1042 delta_sum += delta;
1043 }
1044
1045 munmap(addr, page_size);
1046 pr_debug(" ");
1047out_close:
1048 close(fd);
1049
1050 if (!delta_sum)
1051 return -1;
1052
1053 return 0;
1054}
1055
1056static int test__rdpmc(void)
1057{
1058 int status = 0;
1059 int wret = 0;
1060 int ret;
1061 int pid;
1062
1063 pid = fork();
1064 if (pid < 0)
1065 return -1;
1066
1067 if (!pid) {
1068 ret = __test__rdpmc();
1069
1070 exit(ret);
1071 }
1072
1073 wret = waitpid(pid, &status, 0);
1074 if (wret < 0 || status)
1075 return -1;
1076
1077 return 0;
1078}
1079
1080#endif
1081
1082static int test__perf_pmu(void)
1083{
1084 return perf_pmu__test();
1085}
1086
1087static int perf_evsel__roundtrip_cache_name_test(void)
1088{
1089 char name[128];
1090 int type, op, err = 0, ret = 0, i, idx;
1091 struct perf_evsel *evsel;
1092 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
1093
1094 if (evlist == NULL)
1095 return -ENOMEM;
1096
1097 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
1098 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
1099 /* skip invalid cache type */
1100 if (!perf_evsel__is_cache_op_valid(type, op))
1101 continue;
1102
1103 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
1104 __perf_evsel__hw_cache_type_op_res_name(type, op, i,
1105 name, sizeof(name));
1106 err = parse_events(evlist, name, 0);
1107 if (err)
1108 ret = err;
1109 }
1110 }
1111 }
1112
1113 idx = 0;
1114 evsel = perf_evlist__first(evlist);
1115
1116 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
1117 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
1118 /* skip invalid cache type */
1119 if (!perf_evsel__is_cache_op_valid(type, op))
1120 continue;
1121
1122 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
1123 __perf_evsel__hw_cache_type_op_res_name(type, op, i,
1124 name, sizeof(name));
1125 if (evsel->idx != idx)
1126 continue;
1127
1128 ++idx;
1129
1130 if (strcmp(perf_evsel__name(evsel), name)) {
1131 pr_debug("%s != %s\n", perf_evsel__name(evsel), name);
1132 ret = -1;
1133 }
1134
1135 evsel = perf_evsel__next(evsel);
1136 }
1137 }
1138 }
1139
1140 perf_evlist__delete(evlist);
1141 return ret;
1142}
1143
1144static int __perf_evsel__name_array_test(const char *names[], int nr_names)
1145{
1146 int i, err;
1147 struct perf_evsel *evsel;
1148 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
1149
1150 if (evlist == NULL)
1151 return -ENOMEM;
1152
1153 for (i = 0; i < nr_names; ++i) {
1154 err = parse_events(evlist, names[i], 0);
1155 if (err) {
1156 pr_debug("failed to parse event '%s', err %d\n",
1157 names[i], err);
1158 goto out_delete_evlist;
1159 }
1160 }
1161
1162 err = 0;
1163 list_for_each_entry(evsel, &evlist->entries, node) {
1164 if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
1165 --err;
1166 pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
1167 }
1168 }
1169
1170out_delete_evlist:
1171 perf_evlist__delete(evlist);
1172 return err;
1173}
1174
1175#define perf_evsel__name_array_test(names) \
1176 __perf_evsel__name_array_test(names, ARRAY_SIZE(names))
1177
1178static int perf_evsel__roundtrip_name_test(void)
1179{
1180 int err = 0, ret = 0;
1181
1182 err = perf_evsel__name_array_test(perf_evsel__hw_names);
1183 if (err)
1184 ret = err;
1185
1186 err = perf_evsel__name_array_test(perf_evsel__sw_names);
1187 if (err)
1188 ret = err;
1189
1190 err = perf_evsel__roundtrip_cache_name_test();
1191 if (err)
1192 ret = err;
1193
1194 return ret;
1195}
1196
1197static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name,
1198 int size, bool should_be_signed)
1199{
1200 struct format_field *field = perf_evsel__field(evsel, name);
1201 int is_signed;
1202 int ret = 0;
1203
1204 if (field == NULL) {
1205 pr_debug("%s: \"%s\" field not found!\n", evsel->name, name);
1206 return -1;
1207 }
1208
1209 is_signed = !!(field->flags | FIELD_IS_SIGNED);
1210 if (should_be_signed && !is_signed) {
1211 pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n",
1212 evsel->name, name, is_signed, should_be_signed);
1213 ret = -1;
1214 }
1215
1216 if (field->size != size) {
1217 pr_debug("%s: \"%s\" size (%d) should be %d!\n",
1218 evsel->name, name, field->size, size);
1219 ret = -1;
1220 }
1221
1222 return ret;
1223}
1224
1225static int perf_evsel__tp_sched_test(void)
1226{
1227 struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0);
1228 int ret = 0;
1229
1230 if (evsel == NULL) {
1231 pr_debug("perf_evsel__new\n");
1232 return -1;
1233 }
1234
1235 if (perf_evsel__test_field(evsel, "prev_comm", 16, true))
1236 ret = -1;
1237
1238 if (perf_evsel__test_field(evsel, "prev_pid", 4, true))
1239 ret = -1;
1240
1241 if (perf_evsel__test_field(evsel, "prev_prio", 4, true))
1242 ret = -1;
1243
1244 if (perf_evsel__test_field(evsel, "prev_state", 8, true))
1245 ret = -1;
1246
1247 if (perf_evsel__test_field(evsel, "next_comm", 16, true))
1248 ret = -1;
1249
1250 if (perf_evsel__test_field(evsel, "next_pid", 4, true))
1251 ret = -1;
1252
1253 if (perf_evsel__test_field(evsel, "next_prio", 4, true))
1254 ret = -1;
1255
1256 perf_evsel__delete(evsel);
1257
1258 evsel = perf_evsel__newtp("sched", "sched_wakeup", 0);
1259
1260 if (perf_evsel__test_field(evsel, "comm", 16, true))
1261 ret = -1;
1262
1263 if (perf_evsel__test_field(evsel, "pid", 4, true))
1264 ret = -1;
1265
1266 if (perf_evsel__test_field(evsel, "prio", 4, true))
1267 ret = -1;
1268
1269 if (perf_evsel__test_field(evsel, "success", 4, true))
1270 ret = -1;
1271
1272 if (perf_evsel__test_field(evsel, "target_cpu", 4, true))
1273 ret = -1;
1274
1275 return ret;
1276}
1277
1278static int test__syscall_open_tp_fields(void)
1279{
1280 struct perf_record_opts opts = {
1281 .target = {
1282 .uid = UINT_MAX,
1283 .uses_mmap = true,
1284 },
1285 .no_delay = true,
1286 .freq = 1,
1287 .mmap_pages = 256,
1288 .raw_samples = true,
1289 };
1290 const char *filename = "/etc/passwd";
1291 int flags = O_RDONLY | O_DIRECTORY;
1292 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
1293 struct perf_evsel *evsel;
1294 int err = -1, i, nr_events = 0, nr_polls = 0;
1295
1296 if (evlist == NULL) {
1297 pr_debug("%s: perf_evlist__new\n", __func__);
1298 goto out;
1299 }
1300
1301 evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
1302 if (evsel == NULL) {
1303 pr_debug("%s: perf_evsel__newtp\n", __func__);
1304 goto out_delete_evlist;
1305 }
1306
1307 perf_evlist__add(evlist, evsel);
1308
1309 err = perf_evlist__create_maps(evlist, &opts.target);
1310 if (err < 0) {
1311 pr_debug("%s: perf_evlist__create_maps\n", __func__);
1312 goto out_delete_evlist;
1313 }
1314
1315 perf_evsel__config(evsel, &opts, evsel);
1316
1317 evlist->threads->map[0] = getpid();
1318
1319 err = perf_evlist__open(evlist);
1320 if (err < 0) {
1321 pr_debug("perf_evlist__open: %s\n", strerror(errno));
1322 goto out_delete_evlist;
1323 }
1324
1325 err = perf_evlist__mmap(evlist, UINT_MAX, false);
1326 if (err < 0) {
1327 pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
1328 goto out_delete_evlist;
1329 }
1330
1331 perf_evlist__enable(evlist);
1332
1333 /*
1334 * Generate the event:
1335 */
1336 open(filename, flags);
1337
1338 while (1) {
1339 int before = nr_events;
1340
1341 for (i = 0; i < evlist->nr_mmaps; i++) {
1342 union perf_event *event;
1343
1344 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
1345 const u32 type = event->header.type;
1346 int tp_flags;
1347 struct perf_sample sample;
1348
1349 ++nr_events;
1350
1351 if (type != PERF_RECORD_SAMPLE)
1352 continue;
1353
1354 err = perf_evsel__parse_sample(evsel, event, &sample);
1355 if (err) {
1356 pr_err("Can't parse sample, err = %d\n", err);
1357 goto out_munmap;
1358 }
1359
1360 tp_flags = perf_evsel__intval(evsel, &sample, "flags");
1361
1362 if (flags != tp_flags) {
1363 pr_debug("%s: Expected flags=%#x, got %#x\n",
1364 __func__, flags, tp_flags);
1365 goto out_munmap;
1366 }
1367
1368 goto out_ok;
1369 }
1370 }
1371
1372 if (nr_events == before)
1373 poll(evlist->pollfd, evlist->nr_fds, 10);
1374
1375 if (++nr_polls > 5) {
1376 pr_debug("%s: no events!\n", __func__);
1377 goto out_munmap;
1378 }
1379 }
1380out_ok:
1381 err = 0;
1382out_munmap:
1383 perf_evlist__munmap(evlist);
1384out_delete_evlist:
1385 perf_evlist__delete(evlist);
1386out:
1387 return err;
1388}
1389
1390static struct test {
1391 const char *desc;
1392 int (*func)(void);
1393} tests[] = {
1394 {
1395 .desc = "vmlinux symtab matches kallsyms",
1396 .func = test__vmlinux_matches_kallsyms,
1397 },
1398 {
1399 .desc = "detect open syscall event",
1400 .func = test__open_syscall_event,
1401 },
1402 {
1403 .desc = "detect open syscall event on all cpus",
1404 .func = test__open_syscall_event_on_all_cpus,
1405 },
1406 {
1407 .desc = "read samples using the mmap interface",
1408 .func = test__basic_mmap,
1409 },
1410 {
1411 .desc = "parse events tests",
1412 .func = parse_events__test,
1413 },
1414#if defined(__x86_64__) || defined(__i386__)
1415 {
1416 .desc = "x86 rdpmc test",
1417 .func = test__rdpmc,
1418 },
1419#endif
1420 {
1421 .desc = "Validate PERF_RECORD_* events & perf_sample fields",
1422 .func = test__PERF_RECORD,
1423 },
1424 {
1425 .desc = "Test perf pmu format parsing",
1426 .func = test__perf_pmu,
1427 },
1428 {
1429 .desc = "Test dso data interface",
1430 .func = dso__test_data,
1431 },
1432 {
1433 .desc = "roundtrip evsel->name check",
1434 .func = perf_evsel__roundtrip_name_test,
1435 },
1436 {
1437 .desc = "Check parsing of sched tracepoints fields",
1438 .func = perf_evsel__tp_sched_test,
1439 },
1440 {
1441 .desc = "Generate and check syscalls:sys_enter_open event fields",
1442 .func = test__syscall_open_tp_fields,
1443 },
1444 {
1445 .desc = "struct perf_event_attr setup",
1446 .func = test_attr__run,
1447 },
1448 {
1449 .func = NULL,
1450 },
1451};
1452
1453static bool perf_test__matches(int curr, int argc, const char *argv[])
1454{
1455 int i;
1456
1457 if (argc == 0)
1458 return true;
1459
1460 for (i = 0; i < argc; ++i) {
1461 char *end;
1462 long nr = strtoul(argv[i], &end, 10);
1463
1464 if (*end == '\0') {
1465 if (nr == curr + 1)
1466 return true;
1467 continue;
1468 }
1469
1470 if (strstr(tests[curr].desc, argv[i]))
1471 return true;
1472 }
1473
1474 return false;
1475}
1476
1477static int __cmd_test(int argc, const char *argv[])
1478{
1479 int i = 0;
1480 int width = 0;
1481
1482 while (tests[i].func) {
1483 int len = strlen(tests[i].desc);
1484
1485 if (width < len)
1486 width = len;
1487 ++i;
1488 }
1489
1490 i = 0;
1491 while (tests[i].func) {
1492 int curr = i++, err;
1493
1494 if (!perf_test__matches(curr, argc, argv))
1495 continue;
1496
1497 pr_info("%2d: %-*s:", i, width, tests[curr].desc);
1498 pr_debug("\n--- start ---\n");
1499 err = tests[curr].func();
1500 pr_debug("---- end ----\n%s:", tests[curr].desc);
1501 if (err)
1502 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
1503 else
1504 pr_info(" Ok\n");
1505 }
1506
1507 return 0;
1508}
1509
1510static int perf_test__list(int argc, const char **argv)
1511{
1512 int i = 0;
1513
1514 while (tests[i].func) {
1515 int curr = i++;
1516
1517 if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
1518 continue;
1519
1520 pr_info("%2d: %s\n", i, tests[curr].desc);
1521 }
1522
1523 return 0;
1524}
1525
1526int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
1527{
1528 const char * const test_usage[] = {
1529 "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
1530 NULL,
1531 };
1532 const struct option test_options[] = {
1533 OPT_INCR('v', "verbose", &verbose,
1534 "be more verbose (show symbol address, etc)"),
1535 OPT_END()
1536 };
1537
1538 argc = parse_options(argc, argv, test_options, test_usage, 0);
1539 if (argc >= 1 && !strcmp(argv[0], "list"))
1540 return perf_test__list(argc, argv);
1541
1542 symbol_conf.priv_size = sizeof(int);
1543 symbol_conf.sort_by_name = true;
1544 symbol_conf.try_vmlinux_path = true;
1545
1546 if (symbol__init() < 0)
1547 return -1;
1548
1549 return __cmd_test(argc, argv);
1550}
diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c
new file mode 100644
index 000000000000..0cd42fc9bc13
--- /dev/null
+++ b/tools/perf/tests/dso-data.c
@@ -0,0 +1,154 @@
1#include "util.h"
2
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <string.h>
8
9#include "machine.h"
10#include "symbol.h"
11
12#define TEST_ASSERT_VAL(text, cond) \
13do { \
14 if (!(cond)) { \
15 pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
16 return -1; \
17 } \
18} while (0)
19
20static char *test_file(int size)
21{
22 static char buf_templ[] = "/tmp/test-XXXXXX";
23 char *templ = buf_templ;
24 int fd, i;
25 unsigned char *buf;
26
27 fd = mkstemp(templ);
28
29 buf = malloc(size);
30 if (!buf) {
31 close(fd);
32 return NULL;
33 }
34
35 for (i = 0; i < size; i++)
36 buf[i] = (unsigned char) ((int) i % 10);
37
38 if (size != write(fd, buf, size))
39 templ = NULL;
40
41 close(fd);
42 return templ;
43}
44
45#define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20)
46
47struct test_data_offset {
48 off_t offset;
49 u8 data[10];
50 int size;
51};
52
53struct test_data_offset offsets[] = {
54 /* Fill first cache page. */
55 {
56 .offset = 10,
57 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
58 .size = 10,
59 },
60 /* Read first cache page. */
61 {
62 .offset = 10,
63 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
64 .size = 10,
65 },
66 /* Fill cache boundary pages. */
67 {
68 .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
69 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
70 .size = 10,
71 },
72 /* Read cache boundary pages. */
73 {
74 .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
75 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
76 .size = 10,
77 },
78 /* Fill final cache page. */
79 {
80 .offset = TEST_FILE_SIZE - 10,
81 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
82 .size = 10,
83 },
84 /* Read final cache page. */
85 {
86 .offset = TEST_FILE_SIZE - 10,
87 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
88 .size = 10,
89 },
90 /* Read final cache page. */
91 {
92 .offset = TEST_FILE_SIZE - 3,
93 .data = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 },
94 .size = 3,
95 },
96};
97
98int dso__test_data(void)
99{
100 struct machine machine;
101 struct dso *dso;
102 char *file = test_file(TEST_FILE_SIZE);
103 size_t i;
104
105 TEST_ASSERT_VAL("No test file", file);
106
107 memset(&machine, 0, sizeof(machine));
108
109 dso = dso__new((const char *)file);
110
111 /* Basic 10 bytes tests. */
112 for (i = 0; i < ARRAY_SIZE(offsets); i++) {
113 struct test_data_offset *data = &offsets[i];
114 ssize_t size;
115 u8 buf[10];
116
117 memset(buf, 0, 10);
118 size = dso__data_read_offset(dso, &machine, data->offset,
119 buf, 10);
120
121 TEST_ASSERT_VAL("Wrong size", size == data->size);
122 TEST_ASSERT_VAL("Wrong data", !memcmp(buf, data->data, 10));
123 }
124
125 /* Read cross multiple cache pages. */
126 {
127 ssize_t size;
128 int c;
129 u8 *buf;
130
131 buf = malloc(TEST_FILE_SIZE);
132 TEST_ASSERT_VAL("ENOMEM\n", buf);
133
134 /* First iteration to fill caches, second one to read them. */
135 for (c = 0; c < 2; c++) {
136 memset(buf, 0, TEST_FILE_SIZE);
137 size = dso__data_read_offset(dso, &machine, 10,
138 buf, TEST_FILE_SIZE);
139
140 TEST_ASSERT_VAL("Wrong size",
141 size == (TEST_FILE_SIZE - 10));
142
143 for (i = 0; i < (size_t)size; i++)
144 TEST_ASSERT_VAL("Wrong data",
145 buf[i] == (i % 10));
146 }
147
148 free(buf);
149 }
150
151 dso__delete(dso);
152 unlink(file);
153 return 0;
154}
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
new file mode 100644
index 000000000000..b49c2eebff33
--- /dev/null
+++ b/tools/perf/tests/parse-events.c
@@ -0,0 +1,1116 @@
1
2#include "parse-events.h"
3#include "evsel.h"
4#include "evlist.h"
5#include "sysfs.h"
6#include "../../../include/linux/hw_breakpoint.h"
7
8#define TEST_ASSERT_VAL(text, cond) \
9do { \
10 if (!(cond)) { \
11 pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
12 return -1; \
13 } \
14} while (0)
15
16#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \
17 PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
18
19static int test__checkevent_tracepoint(struct perf_evlist *evlist)
20{
21 struct perf_evsel *evsel = perf_evlist__first(evlist);
22
23 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
24 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
25 TEST_ASSERT_VAL("wrong sample_type",
26 PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
27 TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
28 return 0;
29}
30
31static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
32{
33 struct perf_evsel *evsel;
34
35 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
36
37 list_for_each_entry(evsel, &evlist->entries, node) {
38 TEST_ASSERT_VAL("wrong type",
39 PERF_TYPE_TRACEPOINT == evsel->attr.type);
40 TEST_ASSERT_VAL("wrong sample_type",
41 PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
42 TEST_ASSERT_VAL("wrong sample_period",
43 1 == evsel->attr.sample_period);
44 }
45 return 0;
46}
47
48static int test__checkevent_raw(struct perf_evlist *evlist)
49{
50 struct perf_evsel *evsel = perf_evlist__first(evlist);
51
52 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
53 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
54 TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config);
55 return 0;
56}
57
58static int test__checkevent_numeric(struct perf_evlist *evlist)
59{
60 struct perf_evsel *evsel = perf_evlist__first(evlist);
61
62 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
63 TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
64 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
65 return 0;
66}
67
68static int test__checkevent_symbolic_name(struct perf_evlist *evlist)
69{
70 struct perf_evsel *evsel = perf_evlist__first(evlist);
71
72 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
73 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
74 TEST_ASSERT_VAL("wrong config",
75 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
76 return 0;
77}
78
79static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist)
80{
81 struct perf_evsel *evsel = perf_evlist__first(evlist);
82
83 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
84 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
85 TEST_ASSERT_VAL("wrong config",
86 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
87 TEST_ASSERT_VAL("wrong period",
88 100000 == evsel->attr.sample_period);
89 TEST_ASSERT_VAL("wrong config1",
90 0 == evsel->attr.config1);
91 TEST_ASSERT_VAL("wrong config2",
92 1 == evsel->attr.config2);
93 return 0;
94}
95
96static int test__checkevent_symbolic_alias(struct perf_evlist *evlist)
97{
98 struct perf_evsel *evsel = perf_evlist__first(evlist);
99
100 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
101 TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
102 TEST_ASSERT_VAL("wrong config",
103 PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
104 return 0;
105}
106
107static int test__checkevent_genhw(struct perf_evlist *evlist)
108{
109 struct perf_evsel *evsel = perf_evlist__first(evlist);
110
111 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
112 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type);
113 TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config);
114 return 0;
115}
116
117static int test__checkevent_breakpoint(struct perf_evlist *evlist)
118{
119 struct perf_evsel *evsel = perf_evlist__first(evlist);
120
121 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
122 TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
123 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
124 TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) ==
125 evsel->attr.bp_type);
126 TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 ==
127 evsel->attr.bp_len);
128 return 0;
129}
130
131static int test__checkevent_breakpoint_x(struct perf_evlist *evlist)
132{
133 struct perf_evsel *evsel = perf_evlist__first(evlist);
134
135 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
136 TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
137 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
138 TEST_ASSERT_VAL("wrong bp_type",
139 HW_BREAKPOINT_X == evsel->attr.bp_type);
140 TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len);
141 return 0;
142}
143
144static int test__checkevent_breakpoint_r(struct perf_evlist *evlist)
145{
146 struct perf_evsel *evsel = perf_evlist__first(evlist);
147
148 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
149 TEST_ASSERT_VAL("wrong type",
150 PERF_TYPE_BREAKPOINT == evsel->attr.type);
151 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
152 TEST_ASSERT_VAL("wrong bp_type",
153 HW_BREAKPOINT_R == evsel->attr.bp_type);
154 TEST_ASSERT_VAL("wrong bp_len",
155 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
156 return 0;
157}
158
159static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
160{
161 struct perf_evsel *evsel = perf_evlist__first(evlist);
162
163 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
164 TEST_ASSERT_VAL("wrong type",
165 PERF_TYPE_BREAKPOINT == evsel->attr.type);
166 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
167 TEST_ASSERT_VAL("wrong bp_type",
168 HW_BREAKPOINT_W == evsel->attr.bp_type);
169 TEST_ASSERT_VAL("wrong bp_len",
170 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
171 return 0;
172}
173
174static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist)
175{
176 struct perf_evsel *evsel = perf_evlist__first(evlist);
177
178 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
179 TEST_ASSERT_VAL("wrong type",
180 PERF_TYPE_BREAKPOINT == evsel->attr.type);
181 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
182 TEST_ASSERT_VAL("wrong bp_type",
183 (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type);
184 TEST_ASSERT_VAL("wrong bp_len",
185 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
186 return 0;
187}
188
189static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist)
190{
191 struct perf_evsel *evsel = perf_evlist__first(evlist);
192
193 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
194 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
195 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
196 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
197
198 return test__checkevent_tracepoint(evlist);
199}
200
201static int
202test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)
203{
204 struct perf_evsel *evsel;
205
206 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
207
208 list_for_each_entry(evsel, &evlist->entries, node) {
209 TEST_ASSERT_VAL("wrong exclude_user",
210 !evsel->attr.exclude_user);
211 TEST_ASSERT_VAL("wrong exclude_kernel",
212 evsel->attr.exclude_kernel);
213 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
214 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
215 }
216
217 return test__checkevent_tracepoint_multi(evlist);
218}
219
220static int test__checkevent_raw_modifier(struct perf_evlist *evlist)
221{
222 struct perf_evsel *evsel = perf_evlist__first(evlist);
223
224 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
225 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
226 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
227 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
228
229 return test__checkevent_raw(evlist);
230}
231
232static int test__checkevent_numeric_modifier(struct perf_evlist *evlist)
233{
234 struct perf_evsel *evsel = perf_evlist__first(evlist);
235
236 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
237 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
238 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
239 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
240
241 return test__checkevent_numeric(evlist);
242}
243
244static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist)
245{
246 struct perf_evsel *evsel = perf_evlist__first(evlist);
247
248 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
249 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
250 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
251 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
252
253 return test__checkevent_symbolic_name(evlist);
254}
255
256static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist)
257{
258 struct perf_evsel *evsel = perf_evlist__first(evlist);
259
260 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
261 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
262
263 return test__checkevent_symbolic_name(evlist);
264}
265
266static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist)
267{
268 struct perf_evsel *evsel = perf_evlist__first(evlist);
269
270 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
271 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
272
273 return test__checkevent_symbolic_name(evlist);
274}
275
276static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist)
277{
278 struct perf_evsel *evsel = perf_evlist__first(evlist);
279
280 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
281 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
282 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
283 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
284
285 return test__checkevent_symbolic_alias(evlist);
286}
287
288static int test__checkevent_genhw_modifier(struct perf_evlist *evlist)
289{
290 struct perf_evsel *evsel = perf_evlist__first(evlist);
291
292 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
293 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
294 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
295 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
296
297 return test__checkevent_genhw(evlist);
298}
299
300static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist)
301{
302 struct perf_evsel *evsel = perf_evlist__first(evlist);
303
304
305 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
306 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
307 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
308 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
309 TEST_ASSERT_VAL("wrong name",
310 !strcmp(perf_evsel__name(evsel), "mem:0:u"));
311
312 return test__checkevent_breakpoint(evlist);
313}
314
315static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist)
316{
317 struct perf_evsel *evsel = perf_evlist__first(evlist);
318
319 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
320 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
321 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
322 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
323 TEST_ASSERT_VAL("wrong name",
324 !strcmp(perf_evsel__name(evsel), "mem:0:x:k"));
325
326 return test__checkevent_breakpoint_x(evlist);
327}
328
329static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist)
330{
331 struct perf_evsel *evsel = perf_evlist__first(evlist);
332
333 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
334 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
335 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
336 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
337 TEST_ASSERT_VAL("wrong name",
338 !strcmp(perf_evsel__name(evsel), "mem:0:r:hp"));
339
340 return test__checkevent_breakpoint_r(evlist);
341}
342
343static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist)
344{
345 struct perf_evsel *evsel = perf_evlist__first(evlist);
346
347 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
348 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
349 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
350 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
351 TEST_ASSERT_VAL("wrong name",
352 !strcmp(perf_evsel__name(evsel), "mem:0:w:up"));
353
354 return test__checkevent_breakpoint_w(evlist);
355}
356
357static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist)
358{
359 struct perf_evsel *evsel = perf_evlist__first(evlist);
360
361 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
362 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
363 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
364 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
365 TEST_ASSERT_VAL("wrong name",
366 !strcmp(perf_evsel__name(evsel), "mem:0:rw:kp"));
367
368 return test__checkevent_breakpoint_rw(evlist);
369}
370
371static int test__checkevent_pmu(struct perf_evlist *evlist)
372{
373
374 struct perf_evsel *evsel = perf_evlist__first(evlist);
375
376 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
377 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
378 TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config);
379 TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1);
380 TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2);
381 TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period);
382
383 return 0;
384}
385
386static int test__checkevent_list(struct perf_evlist *evlist)
387{
388 struct perf_evsel *evsel = perf_evlist__first(evlist);
389
390 TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries);
391
392 /* r1 */
393 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
394 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
395 TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1);
396 TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2);
397 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
398 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
399 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
400 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
401
402 /* syscalls:sys_enter_open:k */
403 evsel = perf_evsel__next(evsel);
404 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
405 TEST_ASSERT_VAL("wrong sample_type",
406 PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
407 TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
408 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
409 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
410 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
411 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
412
413 /* 1:1:hp */
414 evsel = perf_evsel__next(evsel);
415 TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
416 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
417 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
418 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
419 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
420 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
421
422 return 0;
423}
424
425static int test__checkevent_pmu_name(struct perf_evlist *evlist)
426{
427 struct perf_evsel *evsel = perf_evlist__first(evlist);
428
429 /* cpu/config=1,name=krava/u */
430 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
431 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
432 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
433 TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava"));
434
435 /* cpu/config=2/u" */
436 evsel = perf_evsel__next(evsel);
437 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
438 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
439 TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config);
440 TEST_ASSERT_VAL("wrong name",
441 !strcmp(perf_evsel__name(evsel), "cpu/config=2/u"));
442
443 return 0;
444}
445
446static int test__checkevent_pmu_events(struct perf_evlist *evlist)
447{
448 struct perf_evsel *evsel;
449
450 evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
451 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
452 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
453 TEST_ASSERT_VAL("wrong exclude_user",
454 !evsel->attr.exclude_user);
455 TEST_ASSERT_VAL("wrong exclude_kernel",
456 evsel->attr.exclude_kernel);
457 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
458 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
459
460 return 0;
461}
462
463static int test__checkterms_simple(struct list_head *terms)
464{
465 struct parse_events__term *term;
466
467 /* config=10 */
468 term = list_entry(terms->next, struct parse_events__term, list);
469 TEST_ASSERT_VAL("wrong type term",
470 term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG);
471 TEST_ASSERT_VAL("wrong type val",
472 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
473 TEST_ASSERT_VAL("wrong val", term->val.num == 10);
474 TEST_ASSERT_VAL("wrong config", !term->config);
475
476 /* config1 */
477 term = list_entry(term->list.next, struct parse_events__term, list);
478 TEST_ASSERT_VAL("wrong type term",
479 term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1);
480 TEST_ASSERT_VAL("wrong type val",
481 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
482 TEST_ASSERT_VAL("wrong val", term->val.num == 1);
483 TEST_ASSERT_VAL("wrong config", !term->config);
484
485 /* config2=3 */
486 term = list_entry(term->list.next, struct parse_events__term, list);
487 TEST_ASSERT_VAL("wrong type term",
488 term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2);
489 TEST_ASSERT_VAL("wrong type val",
490 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
491 TEST_ASSERT_VAL("wrong val", term->val.num == 3);
492 TEST_ASSERT_VAL("wrong config", !term->config);
493
494 /* umask=1*/
495 term = list_entry(term->list.next, struct parse_events__term, list);
496 TEST_ASSERT_VAL("wrong type term",
497 term->type_term == PARSE_EVENTS__TERM_TYPE_USER);
498 TEST_ASSERT_VAL("wrong type val",
499 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
500 TEST_ASSERT_VAL("wrong val", term->val.num == 1);
501 TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask"));
502
503 return 0;
504}
505
506static int test__group1(struct perf_evlist *evlist)
507{
508 struct perf_evsel *evsel, *leader;
509
510 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
511
512 /* instructions:k */
513 evsel = leader = perf_evlist__first(evlist);
514 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
515 TEST_ASSERT_VAL("wrong config",
516 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
517 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
518 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
519 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
520 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
521 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
522 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
523 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
524
525 /* cycles:upp */
526 evsel = perf_evsel__next(evsel);
527 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
528 TEST_ASSERT_VAL("wrong config",
529 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
530 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
531 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
532 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
533 /* use of precise requires exclude_guest */
534 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
535 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
536 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
537 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
538
539 return 0;
540}
541
542static int test__group2(struct perf_evlist *evlist)
543{
544 struct perf_evsel *evsel, *leader;
545
546 TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries);
547
548 /* faults + :ku modifier */
549 evsel = leader = perf_evlist__first(evlist);
550 TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
551 TEST_ASSERT_VAL("wrong config",
552 PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
553 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
554 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
555 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
556 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
557 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
558 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
559 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
560
561 /* cache-references + :u modifier */
562 evsel = perf_evsel__next(evsel);
563 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
564 TEST_ASSERT_VAL("wrong config",
565 PERF_COUNT_HW_CACHE_REFERENCES == evsel->attr.config);
566 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
567 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
568 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
569 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
570 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
571 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
572 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
573
574 /* cycles:k */
575 evsel = perf_evsel__next(evsel);
576 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
577 TEST_ASSERT_VAL("wrong config",
578 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
579 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
580 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
581 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
582 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
583 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
584 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
585 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
586
587 return 0;
588}
589
590static int test__group3(struct perf_evlist *evlist __maybe_unused)
591{
592 struct perf_evsel *evsel, *leader;
593
594 TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries);
595
596 /* group1 syscalls:sys_enter_open:H */
597 evsel = leader = perf_evlist__first(evlist);
598 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
599 TEST_ASSERT_VAL("wrong sample_type",
600 PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
601 TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
602 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
603 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
604 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
605 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
606 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
607 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
608 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
609 TEST_ASSERT_VAL("wrong group name",
610 !strcmp(leader->group_name, "group1"));
611
612 /* group1 cycles:kppp */
613 evsel = perf_evsel__next(evsel);
614 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
615 TEST_ASSERT_VAL("wrong config",
616 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
617 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
618 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
619 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
620 /* use of precise requires exclude_guest */
621 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
622 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
623 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3);
624 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
625 TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
626
627 /* group2 cycles + G modifier */
628 evsel = leader = perf_evsel__next(evsel);
629 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
630 TEST_ASSERT_VAL("wrong config",
631 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
632 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
633 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
634 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
635 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
636 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
637 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
638 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
639 TEST_ASSERT_VAL("wrong group name",
640 !strcmp(leader->group_name, "group2"));
641
642 /* group2 1:3 + G modifier */
643 evsel = perf_evsel__next(evsel);
644 TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
645 TEST_ASSERT_VAL("wrong config", 3 == evsel->attr.config);
646 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
647 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
648 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
649 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
650 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
651 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
652 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
653
654 /* instructions:u */
655 evsel = perf_evsel__next(evsel);
656 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
657 TEST_ASSERT_VAL("wrong config",
658 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
659 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
660 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
661 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
662 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
663 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
664 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
665 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
666
667 return 0;
668}
669
670static int test__group4(struct perf_evlist *evlist __maybe_unused)
671{
672 struct perf_evsel *evsel, *leader;
673
674 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
675
676 /* cycles:u + p */
677 evsel = leader = perf_evlist__first(evlist);
678 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
679 TEST_ASSERT_VAL("wrong config",
680 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
681 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
682 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
683 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
684 /* use of precise requires exclude_guest */
685 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
686 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
687 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1);
688 TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
689 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
690
691 /* instructions:kp + p */
692 evsel = perf_evsel__next(evsel);
693 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
694 TEST_ASSERT_VAL("wrong config",
695 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
696 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
697 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
698 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
699 /* use of precise requires exclude_guest */
700 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
701 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
702 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
703 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
704
705 return 0;
706}
707
708static int test__group5(struct perf_evlist *evlist __maybe_unused)
709{
710 struct perf_evsel *evsel, *leader;
711
712 TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries);
713
714 /* cycles + G */
715 evsel = leader = perf_evlist__first(evlist);
716 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
717 TEST_ASSERT_VAL("wrong config",
718 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
719 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
720 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
721 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
722 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
723 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
724 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
725 TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
726 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
727
728 /* instructions + G */
729 evsel = perf_evsel__next(evsel);
730 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
731 TEST_ASSERT_VAL("wrong config",
732 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
733 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
734 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
735 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
736 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
737 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
738 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
739 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
740
741 /* cycles:G */
742 evsel = leader = perf_evsel__next(evsel);
743 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
744 TEST_ASSERT_VAL("wrong config",
745 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
746 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
747 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
748 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
749 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
750 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
751 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
752 TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
753 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
754
755 /* instructions:G */
756 evsel = perf_evsel__next(evsel);
757 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
758 TEST_ASSERT_VAL("wrong config",
759 PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
760 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
761 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
762 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
763 TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
764 TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
765 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
766 TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
767
768 /* cycles */
769 evsel = perf_evsel__next(evsel);
770 TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
771 TEST_ASSERT_VAL("wrong config",
772 PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
773 TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
774 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
775 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
776 TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
777 TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
778 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
779 TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
780
781 return 0;
782}
783
784struct test__event_st {
785 const char *name;
786 __u32 type;
787 int (*check)(struct perf_evlist *evlist);
788};
789
790static struct test__event_st test__events[] = {
791 [0] = {
792 .name = "syscalls:sys_enter_open",
793 .check = test__checkevent_tracepoint,
794 },
795 [1] = {
796 .name = "syscalls:*",
797 .check = test__checkevent_tracepoint_multi,
798 },
799 [2] = {
800 .name = "r1a",
801 .check = test__checkevent_raw,
802 },
803 [3] = {
804 .name = "1:1",
805 .check = test__checkevent_numeric,
806 },
807 [4] = {
808 .name = "instructions",
809 .check = test__checkevent_symbolic_name,
810 },
811 [5] = {
812 .name = "cycles/period=100000,config2/",
813 .check = test__checkevent_symbolic_name_config,
814 },
815 [6] = {
816 .name = "faults",
817 .check = test__checkevent_symbolic_alias,
818 },
819 [7] = {
820 .name = "L1-dcache-load-miss",
821 .check = test__checkevent_genhw,
822 },
823 [8] = {
824 .name = "mem:0",
825 .check = test__checkevent_breakpoint,
826 },
827 [9] = {
828 .name = "mem:0:x",
829 .check = test__checkevent_breakpoint_x,
830 },
831 [10] = {
832 .name = "mem:0:r",
833 .check = test__checkevent_breakpoint_r,
834 },
835 [11] = {
836 .name = "mem:0:w",
837 .check = test__checkevent_breakpoint_w,
838 },
839 [12] = {
840 .name = "syscalls:sys_enter_open:k",
841 .check = test__checkevent_tracepoint_modifier,
842 },
843 [13] = {
844 .name = "syscalls:*:u",
845 .check = test__checkevent_tracepoint_multi_modifier,
846 },
847 [14] = {
848 .name = "r1a:kp",
849 .check = test__checkevent_raw_modifier,
850 },
851 [15] = {
852 .name = "1:1:hp",
853 .check = test__checkevent_numeric_modifier,
854 },
855 [16] = {
856 .name = "instructions:h",
857 .check = test__checkevent_symbolic_name_modifier,
858 },
859 [17] = {
860 .name = "faults:u",
861 .check = test__checkevent_symbolic_alias_modifier,
862 },
863 [18] = {
864 .name = "L1-dcache-load-miss:kp",
865 .check = test__checkevent_genhw_modifier,
866 },
867 [19] = {
868 .name = "mem:0:u",
869 .check = test__checkevent_breakpoint_modifier,
870 },
871 [20] = {
872 .name = "mem:0:x:k",
873 .check = test__checkevent_breakpoint_x_modifier,
874 },
875 [21] = {
876 .name = "mem:0:r:hp",
877 .check = test__checkevent_breakpoint_r_modifier,
878 },
879 [22] = {
880 .name = "mem:0:w:up",
881 .check = test__checkevent_breakpoint_w_modifier,
882 },
883 [23] = {
884 .name = "r1,syscalls:sys_enter_open:k,1:1:hp",
885 .check = test__checkevent_list,
886 },
887 [24] = {
888 .name = "instructions:G",
889 .check = test__checkevent_exclude_host_modifier,
890 },
891 [25] = {
892 .name = "instructions:H",
893 .check = test__checkevent_exclude_guest_modifier,
894 },
895 [26] = {
896 .name = "mem:0:rw",
897 .check = test__checkevent_breakpoint_rw,
898 },
899 [27] = {
900 .name = "mem:0:rw:kp",
901 .check = test__checkevent_breakpoint_rw_modifier,
902 },
903 [28] = {
904 .name = "{instructions:k,cycles:upp}",
905 .check = test__group1,
906 },
907 [29] = {
908 .name = "{faults:k,cache-references}:u,cycles:k",
909 .check = test__group2,
910 },
911 [30] = {
912 .name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u",
913 .check = test__group3,
914 },
915 [31] = {
916 .name = "{cycles:u,instructions:kp}:p",
917 .check = test__group4,
918 },
919 [32] = {
920 .name = "{cycles,instructions}:G,{cycles:G,instructions:G},cycles",
921 .check = test__group5,
922 },
923};
924
925static struct test__event_st test__events_pmu[] = {
926 [0] = {
927 .name = "cpu/config=10,config1,config2=3,period=1000/u",
928 .check = test__checkevent_pmu,
929 },
930 [1] = {
931 .name = "cpu/config=1,name=krava/u,cpu/config=2/u",
932 .check = test__checkevent_pmu_name,
933 },
934};
935
936struct test__term {
937 const char *str;
938 __u32 type;
939 int (*check)(struct list_head *terms);
940};
941
942static struct test__term test__terms[] = {
943 [0] = {
944 .str = "config=10,config1,config2=3,umask=1",
945 .check = test__checkterms_simple,
946 },
947};
948
949static int test_event(struct test__event_st *e)
950{
951 struct perf_evlist *evlist;
952 int ret;
953
954 evlist = perf_evlist__new(NULL, NULL);
955 if (evlist == NULL)
956 return -ENOMEM;
957
958 ret = parse_events(evlist, e->name, 0);
959 if (ret) {
960 pr_debug("failed to parse event '%s', err %d\n",
961 e->name, ret);
962 return ret;
963 }
964
965 ret = e->check(evlist);
966 perf_evlist__delete(evlist);
967
968 return ret;
969}
970
971static int test_events(struct test__event_st *events, unsigned cnt)
972{
973 int ret1, ret2 = 0;
974 unsigned i;
975
976 for (i = 0; i < cnt; i++) {
977 struct test__event_st *e = &events[i];
978
979 pr_debug("running test %d '%s'\n", i, e->name);
980 ret1 = test_event(e);
981 if (ret1)
982 ret2 = ret1;
983 }
984
985 return ret2;
986}
987
988static int test_term(struct test__term *t)
989{
990 struct list_head *terms;
991 int ret;
992
993 terms = malloc(sizeof(*terms));
994 if (!terms)
995 return -ENOMEM;
996
997 INIT_LIST_HEAD(terms);
998
999 ret = parse_events_terms(terms, t->str);
1000 if (ret) {
1001 pr_debug("failed to parse terms '%s', err %d\n",
1002 t->str , ret);
1003 return ret;
1004 }
1005
1006 ret = t->check(terms);
1007 parse_events__free_terms(terms);
1008
1009 return ret;
1010}
1011
1012static int test_terms(struct test__term *terms, unsigned cnt)
1013{
1014 int ret = 0;
1015 unsigned i;
1016
1017 for (i = 0; i < cnt; i++) {
1018 struct test__term *t = &terms[i];
1019
1020 pr_debug("running test %d '%s'\n", i, t->str);
1021 ret = test_term(t);
1022 if (ret)
1023 break;
1024 }
1025
1026 return ret;
1027}
1028
1029static int test_pmu(void)
1030{
1031 struct stat st;
1032 char path[PATH_MAX];
1033 int ret;
1034
1035 snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/",
1036 sysfs_find_mountpoint());
1037
1038 ret = stat(path, &st);
1039 if (ret)
1040 pr_debug("omitting PMU cpu tests\n");
1041 return !ret;
1042}
1043
1044static int test_pmu_events(void)
1045{
1046 struct stat st;
1047 char path[PATH_MAX];
1048 struct dirent *ent;
1049 DIR *dir;
1050 int ret;
1051
1052 snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/",
1053 sysfs_find_mountpoint());
1054
1055 ret = stat(path, &st);
1056 if (ret) {
1057 pr_debug("ommiting PMU cpu events tests\n");
1058 return 0;
1059 }
1060
1061 dir = opendir(path);
1062 if (!dir) {
1063 pr_debug("can't open pmu event dir");
1064 return -1;
1065 }
1066
1067 while (!ret && (ent = readdir(dir))) {
1068#define MAX_NAME 100
1069 struct test__event_st e;
1070 char name[MAX_NAME];
1071
1072 if (!strcmp(ent->d_name, ".") ||
1073 !strcmp(ent->d_name, ".."))
1074 continue;
1075
1076 snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name);
1077
1078 e.name = name;
1079 e.check = test__checkevent_pmu_events;
1080
1081 ret = test_event(&e);
1082#undef MAX_NAME
1083 }
1084
1085 closedir(dir);
1086 return ret;
1087}
1088
1089int parse_events__test(void)
1090{
1091 int ret1, ret2 = 0;
1092
1093#define TEST_EVENTS(tests) \
1094do { \
1095 ret1 = test_events(tests, ARRAY_SIZE(tests)); \
1096 if (!ret2) \
1097 ret2 = ret1; \
1098} while (0)
1099
1100 TEST_EVENTS(test__events);
1101
1102 if (test_pmu())
1103 TEST_EVENTS(test__events_pmu);
1104
1105 if (test_pmu()) {
1106 int ret = test_pmu_events();
1107 if (ret)
1108 return ret;
1109 }
1110
1111 ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms));
1112 if (!ret2)
1113 ret2 = ret1;
1114
1115 return ret2;
1116}