blob: b78fbd611a7c568be74e3770cdf154eb9fe19692 [file] [log] [blame]
Arnaldo Carvalho de Meloa43783a2017-04-18 10:46:11 -03001#include <errno.h>
Wang Nanba1fae42015-11-06 13:49:43 +00002#include <stdio.h>
3#include <sys/epoll.h>
Wang Nan6a7d5502016-01-25 09:55:53 +00004#include <util/util.h>
Wang Nanba1fae42015-11-06 13:49:43 +00005#include <util/bpf-loader.h>
6#include <util/evlist.h>
Wang Nan6a7d5502016-01-25 09:55:53 +00007#include <linux/bpf.h>
8#include <linux/filter.h>
Arnaldo Carvalho de Melo877a7a12017-04-17 11:39:06 -03009#include <linux/kernel.h>
Joe Stringera2630532017-01-26 13:20:01 -080010#include <api/fs/fs.h>
Wang Nan6a7d5502016-01-25 09:55:53 +000011#include <bpf/bpf.h>
Wang Nanba1fae42015-11-06 13:49:43 +000012#include "tests.h"
13#include "llvm.h"
14#include "debug.h"
15#define NR_ITERS 111
Joe Stringera2630532017-01-26 13:20:01 -080016#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
Wang Nanba1fae42015-11-06 13:49:43 +000017
18#ifdef HAVE_LIBBPF_SUPPORT
19
Arnaldo Carvalho de Melo4ffde492016-07-11 23:22:30 -030020static int epoll_wait_loop(void)
Wang Nanba1fae42015-11-06 13:49:43 +000021{
22 int i;
23
24 /* Should fail NR_ITERS times */
25 for (i = 0; i < NR_ITERS; i++)
Arnaldo Carvalho de Melo4ffde492016-07-11 23:22:30 -030026 epoll_wait(-(i + 1), NULL, 0, 0);
Wang Nanba1fae42015-11-06 13:49:43 +000027 return 0;
28}
29
Wang Nanbbb7d492015-11-16 12:10:14 +000030#ifdef HAVE_BPF_PROLOGUE
31
32static int llseek_loop(void)
33{
34 int fds[2], i;
35
36 fds[0] = open("/dev/null", O_RDONLY);
37 fds[1] = open("/dev/null", O_RDWR);
38
39 if (fds[0] < 0 || fds[1] < 0)
40 return -1;
41
42 for (i = 0; i < NR_ITERS; i++) {
43 lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
44 lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
45 }
46 close(fds[0]);
47 close(fds[1]);
48 return 0;
49}
50
51#endif
52
Wang Nanba1fae42015-11-06 13:49:43 +000053static struct {
54 enum test_llvm__testcase prog_id;
55 const char *desc;
56 const char *name;
57 const char *msg_compile_fail;
58 const char *msg_load_fail;
59 int (*target_func)(void);
60 int expect_result;
Joe Stringera2630532017-01-26 13:20:01 -080061 bool pin;
Wang Nanba1fae42015-11-06 13:49:43 +000062} bpf_testcase_table[] = {
63 {
64 LLVM_TESTCASE_BASE,
Arnaldo Carvalho de Melo030910c2016-11-29 12:38:14 -030065 "Basic BPF filtering",
Wang Nanba1fae42015-11-06 13:49:43 +000066 "[basic_bpf_test]",
67 "fix 'perf test LLVM' first",
68 "load bpf object failed",
Arnaldo Carvalho de Melo4ffde492016-07-11 23:22:30 -030069 &epoll_wait_loop,
Wang Nanba1fae42015-11-06 13:49:43 +000070 (NR_ITERS + 1) / 2,
Joe Stringera2630532017-01-26 13:20:01 -080071 false,
72 },
73 {
74 LLVM_TESTCASE_BASE,
75 "BPF pinning",
76 "[bpf_pinning]",
77 "fix kbuild first",
78 "check your vmlinux setting?",
79 &epoll_wait_loop,
80 (NR_ITERS + 1) / 2,
81 true,
Wang Nanba1fae42015-11-06 13:49:43 +000082 },
Wang Nanbbb7d492015-11-16 12:10:14 +000083#ifdef HAVE_BPF_PROLOGUE
84 {
85 LLVM_TESTCASE_BPF_PROLOGUE,
Arnaldo Carvalho de Melo030910c2016-11-29 12:38:14 -030086 "BPF prologue generation",
Wang Nanbbb7d492015-11-16 12:10:14 +000087 "[bpf_prologue_test]",
88 "fix kbuild first",
89 "check your vmlinux setting?",
90 &llseek_loop,
91 (NR_ITERS + 1) / 4,
Joe Stringera2630532017-01-26 13:20:01 -080092 false,
Wang Nanbbb7d492015-11-16 12:10:14 +000093 },
94#endif
Wang Nan7b6982c2016-01-25 09:55:48 +000095 {
96 LLVM_TESTCASE_BPF_RELOCATION,
Arnaldo Carvalho de Melo030910c2016-11-29 12:38:14 -030097 "BPF relocation checker",
Wang Nan7b6982c2016-01-25 09:55:48 +000098 "[bpf_relocation_test]",
99 "fix 'perf test LLVM' first",
100 "libbpf error when dealing with relocation",
101 NULL,
102 0,
Joe Stringera2630532017-01-26 13:20:01 -0800103 false,
Wang Nan7b6982c2016-01-25 09:55:48 +0000104 },
Wang Nanba1fae42015-11-06 13:49:43 +0000105};
106
107static int do_test(struct bpf_object *obj, int (*func)(void),
108 int expect)
109{
110 struct record_opts opts = {
111 .target = {
112 .uid = UINT_MAX,
113 .uses_mmap = true,
114 },
115 .freq = 0,
116 .mmap_pages = 256,
117 .default_interval = 1,
118 };
119
120 char pid[16];
121 char sbuf[STRERR_BUFSIZE];
122 struct perf_evlist *evlist;
123 int i, ret = TEST_FAIL, err = 0, count = 0;
124
125 struct parse_events_evlist parse_evlist;
126 struct parse_events_error parse_error;
127
128 bzero(&parse_error, sizeof(parse_error));
129 bzero(&parse_evlist, sizeof(parse_evlist));
130 parse_evlist.error = &parse_error;
131 INIT_LIST_HEAD(&parse_evlist.list);
132
Wang Nan95088a52016-02-22 09:10:36 +0000133 err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj, NULL);
Wang Nanba1fae42015-11-06 13:49:43 +0000134 if (err || list_empty(&parse_evlist.list)) {
135 pr_debug("Failed to add events selected by BPF\n");
Wang Nanad0dd7a2015-11-17 08:32:46 +0000136 return TEST_FAIL;
Wang Nanba1fae42015-11-06 13:49:43 +0000137 }
138
139 snprintf(pid, sizeof(pid), "%d", getpid());
140 pid[sizeof(pid) - 1] = '\0';
141 opts.target.tid = opts.target.pid = pid;
142
143 /* Instead of perf_evlist__new_default, don't add default events */
144 evlist = perf_evlist__new();
145 if (!evlist) {
Alexander Alemayhu042cfb52016-10-13 18:18:11 +0200146 pr_debug("Not enough memory to create evlist\n");
Wang Nanba1fae42015-11-06 13:49:43 +0000147 return TEST_FAIL;
148 }
149
150 err = perf_evlist__create_maps(evlist, &opts.target);
151 if (err < 0) {
152 pr_debug("Not enough memory to create thread/cpu maps\n");
153 goto out_delete_evlist;
154 }
155
156 perf_evlist__splice_list_tail(evlist, &parse_evlist.list);
157 evlist->nr_groups = parse_evlist.nr_groups;
158
Arnaldo Carvalho de Meloe68ae9c2016-04-11 18:15:29 -0300159 perf_evlist__config(evlist, &opts, NULL);
Wang Nanba1fae42015-11-06 13:49:43 +0000160
161 err = perf_evlist__open(evlist);
162 if (err < 0) {
163 pr_debug("perf_evlist__open: %s\n",
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300164 str_error_r(errno, sbuf, sizeof(sbuf)));
Wang Nanba1fae42015-11-06 13:49:43 +0000165 goto out_delete_evlist;
166 }
167
168 err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
169 if (err < 0) {
170 pr_debug("perf_evlist__mmap: %s\n",
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300171 str_error_r(errno, sbuf, sizeof(sbuf)));
Wang Nanba1fae42015-11-06 13:49:43 +0000172 goto out_delete_evlist;
173 }
174
175 perf_evlist__enable(evlist);
176 (*func)();
177 perf_evlist__disable(evlist);
178
179 for (i = 0; i < evlist->nr_mmaps; i++) {
180 union perf_event *event;
181
182 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
183 const u32 type = event->header.type;
184
185 if (type == PERF_RECORD_SAMPLE)
186 count ++;
187 }
188 }
189
Wang Nanad0dd7a2015-11-17 08:32:46 +0000190 if (count != expect) {
Wang Nanba1fae42015-11-06 13:49:43 +0000191 pr_debug("BPF filter result incorrect\n");
Wang Nanad0dd7a2015-11-17 08:32:46 +0000192 goto out_delete_evlist;
193 }
Wang Nanba1fae42015-11-06 13:49:43 +0000194
195 ret = TEST_OK;
196
197out_delete_evlist:
198 perf_evlist__delete(evlist);
199 return ret;
200}
201
202static struct bpf_object *
203prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name)
204{
205 struct bpf_object *obj;
206
207 obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name);
208 if (IS_ERR(obj)) {
209 pr_debug("Compile BPF program failed.\n");
210 return NULL;
211 }
212 return obj;
213}
214
Arnaldo Carvalho de Melo916d4092015-11-18 17:38:49 -0300215static int __test__bpf(int idx)
Wang Nanba1fae42015-11-06 13:49:43 +0000216{
217 int ret;
218 void *obj_buf;
219 size_t obj_buf_sz;
220 struct bpf_object *obj;
221
222 ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
Arnaldo Carvalho de Melo916d4092015-11-18 17:38:49 -0300223 bpf_testcase_table[idx].prog_id,
Wang Nan7b6982c2016-01-25 09:55:48 +0000224 true, NULL);
Wang Nanba1fae42015-11-06 13:49:43 +0000225 if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
226 pr_debug("Unable to get BPF object, %s\n",
Arnaldo Carvalho de Melo916d4092015-11-18 17:38:49 -0300227 bpf_testcase_table[idx].msg_compile_fail);
228 if (idx == 0)
Wang Nanba1fae42015-11-06 13:49:43 +0000229 return TEST_SKIP;
230 else
231 return TEST_FAIL;
232 }
233
234 obj = prepare_bpf(obj_buf, obj_buf_sz,
Arnaldo Carvalho de Melo916d4092015-11-18 17:38:49 -0300235 bpf_testcase_table[idx].name);
Wang Nan7b6982c2016-01-25 09:55:48 +0000236 if ((!!bpf_testcase_table[idx].target_func) != (!!obj)) {
237 if (!obj)
238 pr_debug("Fail to load BPF object: %s\n",
239 bpf_testcase_table[idx].msg_load_fail);
240 else
241 pr_debug("Success unexpectedly: %s\n",
242 bpf_testcase_table[idx].msg_load_fail);
Wang Nanba1fae42015-11-06 13:49:43 +0000243 ret = TEST_FAIL;
244 goto out;
245 }
246
Joe Stringera2630532017-01-26 13:20:01 -0800247 if (obj) {
Wang Nan7b6982c2016-01-25 09:55:48 +0000248 ret = do_test(obj,
249 bpf_testcase_table[idx].target_func,
250 bpf_testcase_table[idx].expect_result);
Joe Stringera2630532017-01-26 13:20:01 -0800251 if (ret != TEST_OK)
252 goto out;
253 if (bpf_testcase_table[idx].pin) {
254 int err;
255
256 if (!bpf_fs__mount()) {
257 pr_debug("BPF filesystem not mounted\n");
258 ret = TEST_FAIL;
259 goto out;
260 }
261 err = mkdir(PERF_TEST_BPF_PATH, 0777);
262 if (err && errno != EEXIST) {
263 pr_debug("Failed to make perf_test dir: %s\n",
264 strerror(errno));
265 ret = TEST_FAIL;
266 goto out;
267 }
268 if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
269 ret = TEST_FAIL;
270 if (rm_rf(PERF_TEST_BPF_PATH))
271 ret = TEST_FAIL;
272 }
273 }
274
Wang Nanba1fae42015-11-06 13:49:43 +0000275out:
276 bpf__clear();
277 return ret;
278}
279
Wang Nan77a0cf62015-11-17 08:32:49 +0000280int test__bpf_subtest_get_nr(void)
Wang Nanba1fae42015-11-06 13:49:43 +0000281{
Wang Nan77a0cf62015-11-17 08:32:49 +0000282 return (int)ARRAY_SIZE(bpf_testcase_table);
283}
284
285const char *test__bpf_subtest_get_desc(int i)
286{
287 if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
288 return NULL;
289 return bpf_testcase_table[i].desc;
290}
291
Wang Nan6a7d5502016-01-25 09:55:53 +0000292static int check_env(void)
293{
294 int err;
295 unsigned int kver_int;
296 char license[] = "GPL";
297
298 struct bpf_insn insns[] = {
299 BPF_MOV64_IMM(BPF_REG_0, 1),
300 BPF_EXIT_INSN(),
301 };
302
303 err = fetch_kernel_version(&kver_int, NULL, 0);
304 if (err) {
305 pr_debug("Unable to get kernel version\n");
306 return err;
307 }
308
309 err = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
310 sizeof(insns) / sizeof(insns[0]),
311 license, kver_int, NULL, 0);
312 if (err < 0) {
313 pr_err("Missing basic BPF support, skip this test: %s\n",
314 strerror(errno));
315 return err;
316 }
317 close(err);
318
319 return 0;
320}
321
Wang Nan77a0cf62015-11-17 08:32:49 +0000322int test__bpf(int i)
323{
Wang Nanba1fae42015-11-06 13:49:43 +0000324 int err;
325
Wang Nan77a0cf62015-11-17 08:32:49 +0000326 if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
327 return TEST_FAIL;
328
Wang Nanba1fae42015-11-06 13:49:43 +0000329 if (geteuid() != 0) {
330 pr_debug("Only root can run BPF test\n");
331 return TEST_SKIP;
332 }
333
Wang Nan6a7d5502016-01-25 09:55:53 +0000334 if (check_env())
335 return TEST_SKIP;
336
Wang Nan77a0cf62015-11-17 08:32:49 +0000337 err = __test__bpf(i);
338 return err;
Wang Nanba1fae42015-11-06 13:49:43 +0000339}
340
341#else
Wang Nan77a0cf62015-11-17 08:32:49 +0000342int test__bpf_subtest_get_nr(void)
343{
344 return 0;
345}
346
347const char *test__bpf_subtest_get_desc(int i __maybe_unused)
348{
349 return NULL;
350}
351
352int test__bpf(int i __maybe_unused)
Wang Nanba1fae42015-11-06 13:49:43 +0000353{
354 pr_debug("Skip BPF test because BPF support is not compiled\n");
355 return TEST_SKIP;
356}
357#endif