diff options
-rw-r--r-- | tools/perf/tests/Build | 1 | ||||
-rw-r--r-- | tools/perf/tests/backward-ring-buffer.c | 151 | ||||
-rw-r--r-- | tools/perf/tests/builtin-test.c | 4 | ||||
-rw-r--r-- | tools/perf/tests/tests.h | 1 |
4 files changed, 157 insertions, 0 deletions
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 449fe97a555f..66a28982547b 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build | |||
@@ -38,6 +38,7 @@ perf-y += cpumap.o | |||
38 | perf-y += stat.o | 38 | perf-y += stat.o |
39 | perf-y += event_update.o | 39 | perf-y += event_update.o |
40 | perf-y += event-times.o | 40 | perf-y += event-times.o |
41 | perf-y += backward-ring-buffer.o | ||
41 | 42 | ||
42 | $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build | 43 | $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build |
43 | $(call rule_mkdir) | 44 | $(call rule_mkdir) |
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c new file mode 100644 index 000000000000..d9ba991a9a30 --- /dev/null +++ b/tools/perf/tests/backward-ring-buffer.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Test backward bit in event attribute, read ring buffer from end to | ||
3 | * beginning | ||
4 | */ | ||
5 | |||
6 | #include <perf.h> | ||
7 | #include <evlist.h> | ||
8 | #include <sys/prctl.h> | ||
9 | #include "tests.h" | ||
10 | #include "debug.h" | ||
11 | |||
12 | #define NR_ITERS 111 | ||
13 | |||
14 | static void testcase(void) | ||
15 | { | ||
16 | int i; | ||
17 | |||
18 | for (i = 0; i < NR_ITERS; i++) { | ||
19 | char proc_name[10]; | ||
20 | |||
21 | snprintf(proc_name, sizeof(proc_name), "p:%d\n", i); | ||
22 | prctl(PR_SET_NAME, proc_name); | ||
23 | } | ||
24 | } | ||
25 | |||
26 | static int count_samples(struct perf_evlist *evlist, int *sample_count, | ||
27 | int *comm_count) | ||
28 | { | ||
29 | int i; | ||
30 | |||
31 | for (i = 0; i < evlist->nr_mmaps; i++) { | ||
32 | union perf_event *event; | ||
33 | |||
34 | perf_evlist__mmap_read_catchup(evlist, i); | ||
35 | while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) { | ||
36 | const u32 type = event->header.type; | ||
37 | |||
38 | switch (type) { | ||
39 | case PERF_RECORD_SAMPLE: | ||
40 | (*sample_count)++; | ||
41 | break; | ||
42 | case PERF_RECORD_COMM: | ||
43 | (*comm_count)++; | ||
44 | break; | ||
45 | default: | ||
46 | pr_err("Unexpected record of type %d\n", type); | ||
47 | return TEST_FAIL; | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | return TEST_OK; | ||
52 | } | ||
53 | |||
54 | static int do_test(struct perf_evlist *evlist, int mmap_pages, | ||
55 | int *sample_count, int *comm_count) | ||
56 | { | ||
57 | int err; | ||
58 | char sbuf[STRERR_BUFSIZE]; | ||
59 | |||
60 | err = perf_evlist__mmap(evlist, mmap_pages, true); | ||
61 | if (err < 0) { | ||
62 | pr_debug("perf_evlist__mmap: %s\n", | ||
63 | strerror_r(errno, sbuf, sizeof(sbuf))); | ||
64 | return TEST_FAIL; | ||
65 | } | ||
66 | |||
67 | perf_evlist__enable(evlist); | ||
68 | testcase(); | ||
69 | perf_evlist__disable(evlist); | ||
70 | |||
71 | err = count_samples(evlist, sample_count, comm_count); | ||
72 | perf_evlist__munmap(evlist); | ||
73 | return err; | ||
74 | } | ||
75 | |||
76 | |||
77 | int test__backward_ring_buffer(int subtest __maybe_unused) | ||
78 | { | ||
79 | int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; | ||
80 | char pid[16], sbuf[STRERR_BUFSIZE]; | ||
81 | struct perf_evlist *evlist; | ||
82 | struct perf_evsel *evsel __maybe_unused; | ||
83 | struct parse_events_error parse_error; | ||
84 | struct record_opts opts = { | ||
85 | .target = { | ||
86 | .uid = UINT_MAX, | ||
87 | .uses_mmap = true, | ||
88 | }, | ||
89 | .freq = 0, | ||
90 | .mmap_pages = 256, | ||
91 | .default_interval = 1, | ||
92 | }; | ||
93 | |||
94 | snprintf(pid, sizeof(pid), "%d", getpid()); | ||
95 | pid[sizeof(pid) - 1] = '\0'; | ||
96 | opts.target.tid = opts.target.pid = pid; | ||
97 | |||
98 | evlist = perf_evlist__new(); | ||
99 | if (!evlist) { | ||
100 | pr_debug("No ehough memory to create evlist\n"); | ||
101 | return TEST_FAIL; | ||
102 | } | ||
103 | |||
104 | err = perf_evlist__create_maps(evlist, &opts.target); | ||
105 | if (err < 0) { | ||
106 | pr_debug("Not enough memory to create thread/cpu maps\n"); | ||
107 | goto out_delete_evlist; | ||
108 | } | ||
109 | |||
110 | bzero(&parse_error, sizeof(parse_error)); | ||
111 | err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error); | ||
112 | if (err) { | ||
113 | pr_debug("Failed to parse tracepoint event, try use root\n"); | ||
114 | ret = TEST_SKIP; | ||
115 | goto out_delete_evlist; | ||
116 | } | ||
117 | |||
118 | perf_evlist__config(evlist, &opts, NULL); | ||
119 | |||
120 | /* Set backward bit, ring buffer should be writing from end */ | ||
121 | evlist__for_each(evlist, evsel) | ||
122 | evsel->attr.write_backward = 1; | ||
123 | |||
124 | err = perf_evlist__open(evlist); | ||
125 | if (err < 0) { | ||
126 | pr_debug("perf_evlist__open: %s\n", | ||
127 | strerror_r(errno, sbuf, sizeof(sbuf))); | ||
128 | goto out_delete_evlist; | ||
129 | } | ||
130 | |||
131 | ret = TEST_FAIL; | ||
132 | err = do_test(evlist, opts.mmap_pages, &sample_count, | ||
133 | &comm_count); | ||
134 | if (err != TEST_OK) | ||
135 | goto out_delete_evlist; | ||
136 | |||
137 | if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) { | ||
138 | pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n", | ||
139 | sample_count, comm_count); | ||
140 | goto out_delete_evlist; | ||
141 | } | ||
142 | |||
143 | err = do_test(evlist, 1, &sample_count, &comm_count); | ||
144 | if (err != TEST_OK) | ||
145 | goto out_delete_evlist; | ||
146 | |||
147 | ret = TEST_OK; | ||
148 | out_delete_evlist: | ||
149 | perf_evlist__delete(evlist); | ||
150 | return ret; | ||
151 | } | ||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 93c467015e71..0e95c20ecf6e 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
@@ -208,6 +208,10 @@ static struct test generic_tests[] = { | |||
208 | .func = test__event_times, | 208 | .func = test__event_times, |
209 | }, | 209 | }, |
210 | { | 210 | { |
211 | .desc = "Test backward reading from ring buffer", | ||
212 | .func = test__backward_ring_buffer, | ||
213 | }, | ||
214 | { | ||
211 | .func = NULL, | 215 | .func = NULL, |
212 | }, | 216 | }, |
213 | }; | 217 | }; |
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 0fc946989cf0..c57e72c826d2 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h | |||
@@ -86,6 +86,7 @@ int test__synthesize_stat(int subtest); | |||
86 | int test__synthesize_stat_round(int subtest); | 86 | int test__synthesize_stat_round(int subtest); |
87 | int test__event_update(int subtest); | 87 | int test__event_update(int subtest); |
88 | int test__event_times(int subtest); | 88 | int test__event_times(int subtest); |
89 | int test__backward_ring_buffer(int subtest); | ||
89 | 90 | ||
90 | #if defined(__arm__) || defined(__aarch64__) | 91 | #if defined(__arm__) || defined(__aarch64__) |
91 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | 92 | #ifdef HAVE_DWARF_UNWIND_SUPPORT |