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