1 #include <linux/err.h> 2 #include "perf.h" 3 #include "evlist.h" 4 #include "evsel.h" 5 #include "thread_map.h" 6 #include "tests.h" 7 #include "debug.h" 8 9 #ifndef O_DIRECTORY 10 #define O_DIRECTORY 00200000 11 #endif 12 #ifndef AT_FDCWD 13 #define AT_FDCWD -100 14 #endif 15 16 int test__syscall_openat_tp_fields(int subtest __maybe_unused) 17 { 18 struct record_opts opts = { 19 .target = { 20 .uid = UINT_MAX, 21 .uses_mmap = true, 22 }, 23 .no_buffering = true, 24 .freq = 1, 25 .mmap_pages = 256, 26 .raw_samples = true, 27 }; 28 const char *filename = "/etc/passwd"; 29 int flags = O_RDONLY | O_DIRECTORY; 30 struct perf_evlist *evlist = perf_evlist__new(); 31 struct perf_evsel *evsel; 32 int err = -1, i, nr_events = 0, nr_polls = 0; 33 char sbuf[STRERR_BUFSIZE]; 34 35 if (evlist == NULL) { 36 pr_debug("%s: perf_evlist__new\n", __func__); 37 goto out; 38 } 39 40 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); 41 if (IS_ERR(evsel)) { 42 pr_debug("%s: perf_evsel__newtp\n", __func__); 43 goto out_delete_evlist; 44 } 45 46 perf_evlist__add(evlist, evsel); 47 48 err = perf_evlist__create_maps(evlist, &opts.target); 49 if (err < 0) { 50 pr_debug("%s: perf_evlist__create_maps\n", __func__); 51 goto out_delete_evlist; 52 } 53 54 perf_evsel__config(evsel, &opts, NULL); 55 56 thread_map__set_pid(evlist->threads, 0, getpid()); 57 58 err = perf_evlist__open(evlist); 59 if (err < 0) { 60 pr_debug("perf_evlist__open: %s\n", 61 str_error_r(errno, sbuf, sizeof(sbuf))); 62 goto out_delete_evlist; 63 } 64 65 err = perf_evlist__mmap(evlist, UINT_MAX, false); 66 if (err < 0) { 67 pr_debug("perf_evlist__mmap: %s\n", 68 str_error_r(errno, sbuf, sizeof(sbuf))); 69 goto out_delete_evlist; 70 } 71 72 perf_evlist__enable(evlist); 73 74 /* 75 * Generate the event: 76 */ 77 openat(AT_FDCWD, filename, flags); 78 79 while (1) { 80 int before = nr_events; 81 82 for (i = 0; i < evlist->nr_mmaps; i++) { 83 union perf_event *event; 84 85 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { 86 const u32 type = event->header.type; 87 int tp_flags; 88 struct perf_sample sample; 89 90 ++nr_events; 91 92 if (type != PERF_RECORD_SAMPLE) { 93 perf_evlist__mmap_consume(evlist, i); 94 continue; 95 } 96 97 err = perf_evsel__parse_sample(evsel, event, &sample); 98 if (err) { 99 pr_debug("Can't parse sample, err = %d\n", err); 100 goto out_delete_evlist; 101 } 102 103 tp_flags = perf_evsel__intval(evsel, &sample, "flags"); 104 105 if (flags != tp_flags) { 106 pr_debug("%s: Expected flags=%#x, got %#x\n", 107 __func__, flags, tp_flags); 108 goto out_delete_evlist; 109 } 110 111 goto out_ok; 112 } 113 } 114 115 if (nr_events == before) 116 perf_evlist__poll(evlist, 10); 117 118 if (++nr_polls > 5) { 119 pr_debug("%s: no events!\n", __func__); 120 goto out_delete_evlist; 121 } 122 } 123 out_ok: 124 err = 0; 125 out_delete_evlist: 126 perf_evlist__delete(evlist); 127 out: 128 return err; 129 } 130