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