bpf.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include <stdio.h>
  2. #include <sys/epoll.h>
  3. #include <util/bpf-loader.h>
  4. #include <util/evlist.h>
  5. #include "tests.h"
  6. #include "llvm.h"
  7. #include "debug.h"
  8. #define NR_ITERS 111
  9. #ifdef HAVE_LIBBPF_SUPPORT
  10. static int epoll_pwait_loop(void)
  11. {
  12. int i;
  13. /* Should fail NR_ITERS times */
  14. for (i = 0; i < NR_ITERS; i++)
  15. epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
  16. return 0;
  17. }
  18. #ifdef HAVE_BPF_PROLOGUE
  19. static int llseek_loop(void)
  20. {
  21. int fds[2], i;
  22. fds[0] = open("/dev/null", O_RDONLY);
  23. fds[1] = open("/dev/null", O_RDWR);
  24. if (fds[0] < 0 || fds[1] < 0)
  25. return -1;
  26. for (i = 0; i < NR_ITERS; i++) {
  27. lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
  28. lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
  29. }
  30. close(fds[0]);
  31. close(fds[1]);
  32. return 0;
  33. }
  34. #endif
  35. static struct {
  36. enum test_llvm__testcase prog_id;
  37. const char *desc;
  38. const char *name;
  39. const char *msg_compile_fail;
  40. const char *msg_load_fail;
  41. int (*target_func)(void);
  42. int expect_result;
  43. } bpf_testcase_table[] = {
  44. {
  45. LLVM_TESTCASE_BASE,
  46. "Test basic BPF filtering",
  47. "[basic_bpf_test]",
  48. "fix 'perf test LLVM' first",
  49. "load bpf object failed",
  50. &epoll_pwait_loop,
  51. (NR_ITERS + 1) / 2,
  52. },
  53. #ifdef HAVE_BPF_PROLOGUE
  54. {
  55. LLVM_TESTCASE_BPF_PROLOGUE,
  56. "Test BPF prologue generation",
  57. "[bpf_prologue_test]",
  58. "fix kbuild first",
  59. "check your vmlinux setting?",
  60. &llseek_loop,
  61. (NR_ITERS + 1) / 4,
  62. },
  63. #endif
  64. };
  65. static int do_test(struct bpf_object *obj, int (*func)(void),
  66. int expect)
  67. {
  68. struct record_opts opts = {
  69. .target = {
  70. .uid = UINT_MAX,
  71. .uses_mmap = true,
  72. },
  73. .freq = 0,
  74. .mmap_pages = 256,
  75. .default_interval = 1,
  76. };
  77. char pid[16];
  78. char sbuf[STRERR_BUFSIZE];
  79. struct perf_evlist *evlist;
  80. int i, ret = TEST_FAIL, err = 0, count = 0;
  81. struct parse_events_evlist parse_evlist;
  82. struct parse_events_error parse_error;
  83. bzero(&parse_error, sizeof(parse_error));
  84. bzero(&parse_evlist, sizeof(parse_evlist));
  85. parse_evlist.error = &parse_error;
  86. INIT_LIST_HEAD(&parse_evlist.list);
  87. err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj);
  88. if (err || list_empty(&parse_evlist.list)) {
  89. pr_debug("Failed to add events selected by BPF\n");
  90. return TEST_FAIL;
  91. }
  92. snprintf(pid, sizeof(pid), "%d", getpid());
  93. pid[sizeof(pid) - 1] = '\0';
  94. opts.target.tid = opts.target.pid = pid;
  95. /* Instead of perf_evlist__new_default, don't add default events */
  96. evlist = perf_evlist__new();
  97. if (!evlist) {
  98. pr_debug("No ehough memory to create evlist\n");
  99. return TEST_FAIL;
  100. }
  101. err = perf_evlist__create_maps(evlist, &opts.target);
  102. if (err < 0) {
  103. pr_debug("Not enough memory to create thread/cpu maps\n");
  104. goto out_delete_evlist;
  105. }
  106. perf_evlist__splice_list_tail(evlist, &parse_evlist.list);
  107. evlist->nr_groups = parse_evlist.nr_groups;
  108. perf_evlist__config(evlist, &opts);
  109. err = perf_evlist__open(evlist);
  110. if (err < 0) {
  111. pr_debug("perf_evlist__open: %s\n",
  112. strerror_r(errno, sbuf, sizeof(sbuf)));
  113. goto out_delete_evlist;
  114. }
  115. err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
  116. if (err < 0) {
  117. pr_debug("perf_evlist__mmap: %s\n",
  118. strerror_r(errno, sbuf, sizeof(sbuf)));
  119. goto out_delete_evlist;
  120. }
  121. perf_evlist__enable(evlist);
  122. (*func)();
  123. perf_evlist__disable(evlist);
  124. for (i = 0; i < evlist->nr_mmaps; i++) {
  125. union perf_event *event;
  126. while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
  127. const u32 type = event->header.type;
  128. if (type == PERF_RECORD_SAMPLE)
  129. count ++;
  130. }
  131. }
  132. if (count != expect) {
  133. pr_debug("BPF filter result incorrect\n");
  134. goto out_delete_evlist;
  135. }
  136. ret = TEST_OK;
  137. out_delete_evlist:
  138. perf_evlist__delete(evlist);
  139. return ret;
  140. }
  141. static struct bpf_object *
  142. prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name)
  143. {
  144. struct bpf_object *obj;
  145. obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name);
  146. if (IS_ERR(obj)) {
  147. pr_debug("Compile BPF program failed.\n");
  148. return NULL;
  149. }
  150. return obj;
  151. }
  152. static int __test__bpf(int idx)
  153. {
  154. int ret;
  155. void *obj_buf;
  156. size_t obj_buf_sz;
  157. struct bpf_object *obj;
  158. ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
  159. bpf_testcase_table[idx].prog_id,
  160. true);
  161. if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
  162. pr_debug("Unable to get BPF object, %s\n",
  163. bpf_testcase_table[idx].msg_compile_fail);
  164. if (idx == 0)
  165. return TEST_SKIP;
  166. else
  167. return TEST_FAIL;
  168. }
  169. obj = prepare_bpf(obj_buf, obj_buf_sz,
  170. bpf_testcase_table[idx].name);
  171. if (!obj) {
  172. ret = TEST_FAIL;
  173. goto out;
  174. }
  175. ret = do_test(obj,
  176. bpf_testcase_table[idx].target_func,
  177. bpf_testcase_table[idx].expect_result);
  178. out:
  179. bpf__clear();
  180. return ret;
  181. }
  182. int test__bpf_subtest_get_nr(void)
  183. {
  184. return (int)ARRAY_SIZE(bpf_testcase_table);
  185. }
  186. const char *test__bpf_subtest_get_desc(int i)
  187. {
  188. if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
  189. return NULL;
  190. return bpf_testcase_table[i].desc;
  191. }
  192. int test__bpf(int i)
  193. {
  194. int err;
  195. if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
  196. return TEST_FAIL;
  197. if (geteuid() != 0) {
  198. pr_debug("Only root can run BPF test\n");
  199. return TEST_SKIP;
  200. }
  201. err = __test__bpf(i);
  202. return err;
  203. }
  204. #else
  205. int test__bpf_subtest_get_nr(void)
  206. {
  207. return 0;
  208. }
  209. const char *test__bpf_subtest_get_desc(int i __maybe_unused)
  210. {
  211. return NULL;
  212. }
  213. int test__bpf(int i __maybe_unused)
  214. {
  215. pr_debug("Skip BPF test because BPF support is not compiled\n");
  216. return TEST_SKIP;
  217. }
  218. #endif