|
30 | 30 | #include <sched.h>
|
31 | 31 |
|
32 | 32 |
|
33 |
| -/* |
34 |
| - * This test will generate random numbers of calls to some getpid syscalls, |
35 |
| - * then establish an mmap for a group of events that are created to monitor |
36 |
| - * the syscalls. |
37 |
| - * |
38 |
| - * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated |
39 |
| - * sample.id field to map back to its respective perf_evsel instance. |
40 |
| - * |
41 |
| - * Then it checks if the number of syscalls reported as perf events by |
42 |
| - * the kernel corresponds to the number of syscalls made. |
43 |
| - */ |
44 |
| -static int test__basic_mmap(void) |
45 |
| -{ |
46 |
| - int err = -1; |
47 |
| - union perf_event *event; |
48 |
| - struct thread_map *threads; |
49 |
| - struct cpu_map *cpus; |
50 |
| - struct perf_evlist *evlist; |
51 |
| - struct perf_event_attr attr = { |
52 |
| - .type = PERF_TYPE_TRACEPOINT, |
53 |
| - .read_format = PERF_FORMAT_ID, |
54 |
| - .sample_type = PERF_SAMPLE_ID, |
55 |
| - .watermark = 0, |
56 |
| - }; |
57 |
| - cpu_set_t cpu_set; |
58 |
| - const char *syscall_names[] = { "getsid", "getppid", "getpgrp", |
59 |
| - "getpgid", }; |
60 |
| - pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, |
61 |
| - (void*)getpgid }; |
62 |
| -#define nsyscalls ARRAY_SIZE(syscall_names) |
63 |
| - int ids[nsyscalls]; |
64 |
| - unsigned int nr_events[nsyscalls], |
65 |
| - expected_nr_events[nsyscalls], i, j; |
66 |
| - struct perf_evsel *evsels[nsyscalls], *evsel; |
67 |
| - |
68 |
| - for (i = 0; i < nsyscalls; ++i) { |
69 |
| - char name[64]; |
70 |
| - |
71 |
| - snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]); |
72 |
| - ids[i] = trace_event__id(name); |
73 |
| - if (ids[i] < 0) { |
74 |
| - pr_debug("Is debugfs mounted on /sys/kernel/debug?\n"); |
75 |
| - return -1; |
76 |
| - } |
77 |
| - nr_events[i] = 0; |
78 |
| - expected_nr_events[i] = random() % 257; |
79 |
| - } |
80 |
| - |
81 |
| - threads = thread_map__new(-1, getpid(), UINT_MAX); |
82 |
| - if (threads == NULL) { |
83 |
| - pr_debug("thread_map__new\n"); |
84 |
| - return -1; |
85 |
| - } |
86 |
| - |
87 |
| - cpus = cpu_map__new(NULL); |
88 |
| - if (cpus == NULL) { |
89 |
| - pr_debug("cpu_map__new\n"); |
90 |
| - goto out_free_threads; |
91 |
| - } |
92 |
| - |
93 |
| - CPU_ZERO(&cpu_set); |
94 |
| - CPU_SET(cpus->map[0], &cpu_set); |
95 |
| - sched_setaffinity(0, sizeof(cpu_set), &cpu_set); |
96 |
| - if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { |
97 |
| - pr_debug("sched_setaffinity() failed on CPU %d: %s ", |
98 |
| - cpus->map[0], strerror(errno)); |
99 |
| - goto out_free_cpus; |
100 |
| - } |
101 |
| - |
102 |
| - evlist = perf_evlist__new(cpus, threads); |
103 |
| - if (evlist == NULL) { |
104 |
| - pr_debug("perf_evlist__new\n"); |
105 |
| - goto out_free_cpus; |
106 |
| - } |
107 |
| - |
108 |
| - /* anonymous union fields, can't be initialized above */ |
109 |
| - attr.wakeup_events = 1; |
110 |
| - attr.sample_period = 1; |
111 |
| - |
112 |
| - for (i = 0; i < nsyscalls; ++i) { |
113 |
| - attr.config = ids[i]; |
114 |
| - evsels[i] = perf_evsel__new(&attr, i); |
115 |
| - if (evsels[i] == NULL) { |
116 |
| - pr_debug("perf_evsel__new\n"); |
117 |
| - goto out_free_evlist; |
118 |
| - } |
119 |
| - |
120 |
| - perf_evlist__add(evlist, evsels[i]); |
121 |
| - |
122 |
| - if (perf_evsel__open(evsels[i], cpus, threads) < 0) { |
123 |
| - pr_debug("failed to open counter: %s, " |
124 |
| - "tweak /proc/sys/kernel/perf_event_paranoid?\n", |
125 |
| - strerror(errno)); |
126 |
| - goto out_close_fd; |
127 |
| - } |
128 |
| - } |
129 |
| - |
130 |
| - if (perf_evlist__mmap(evlist, 128, true) < 0) { |
131 |
| - pr_debug("failed to mmap events: %d (%s)\n", errno, |
132 |
| - strerror(errno)); |
133 |
| - goto out_close_fd; |
134 |
| - } |
135 |
| - |
136 |
| - for (i = 0; i < nsyscalls; ++i) |
137 |
| - for (j = 0; j < expected_nr_events[i]; ++j) { |
138 |
| - int foo = syscalls[i](); |
139 |
| - ++foo; |
140 |
| - } |
141 |
| - |
142 |
| - while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { |
143 |
| - struct perf_sample sample; |
144 |
| - |
145 |
| - if (event->header.type != PERF_RECORD_SAMPLE) { |
146 |
| - pr_debug("unexpected %s event\n", |
147 |
| - perf_event__name(event->header.type)); |
148 |
| - goto out_munmap; |
149 |
| - } |
150 |
| - |
151 |
| - err = perf_evlist__parse_sample(evlist, event, &sample); |
152 |
| - if (err) { |
153 |
| - pr_err("Can't parse sample, err = %d\n", err); |
154 |
| - goto out_munmap; |
155 |
| - } |
156 |
| - |
157 |
| - evsel = perf_evlist__id2evsel(evlist, sample.id); |
158 |
| - if (evsel == NULL) { |
159 |
| - pr_debug("event with id %" PRIu64 |
160 |
| - " doesn't map to an evsel\n", sample.id); |
161 |
| - goto out_munmap; |
162 |
| - } |
163 |
| - nr_events[evsel->idx]++; |
164 |
| - } |
165 |
| - |
166 |
| - list_for_each_entry(evsel, &evlist->entries, node) { |
167 |
| - if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { |
168 |
| - pr_debug("expected %d %s events, got %d\n", |
169 |
| - expected_nr_events[evsel->idx], |
170 |
| - perf_evsel__name(evsel), nr_events[evsel->idx]); |
171 |
| - goto out_munmap; |
172 |
| - } |
173 |
| - } |
174 |
| - |
175 |
| - err = 0; |
176 |
| -out_munmap: |
177 |
| - perf_evlist__munmap(evlist); |
178 |
| -out_close_fd: |
179 |
| - for (i = 0; i < nsyscalls; ++i) |
180 |
| - perf_evsel__close_fd(evsels[i], 1, threads->nr); |
181 |
| -out_free_evlist: |
182 |
| - perf_evlist__delete(evlist); |
183 |
| -out_free_cpus: |
184 |
| - cpu_map__delete(cpus); |
185 |
| -out_free_threads: |
186 |
| - thread_map__delete(threads); |
187 |
| - return err; |
188 |
| -#undef nsyscalls |
189 |
| -} |
190 | 33 |
|
191 | 34 | static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
|
192 | 35 | {
|
|
0 commit comments