| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | 2 | #include <errno.h> |
|---|
| 3 | 3 | #include <inttypes.h> |
|---|
| 4 | +#include <linux/string.h> |
|---|
| 4 | 5 | /* For the CLR_() macros */ |
|---|
| 5 | 6 | #include <pthread.h> |
|---|
| 6 | 7 | |
|---|
| 7 | 8 | #include <sched.h> |
|---|
| 9 | +#include <perf/mmap.h> |
|---|
| 8 | 10 | #include "evlist.h" |
|---|
| 9 | 11 | #include "evsel.h" |
|---|
| 10 | | -#include "perf.h" |
|---|
| 11 | 12 | #include "debug.h" |
|---|
| 13 | +#include "record.h" |
|---|
| 12 | 14 | #include "tests.h" |
|---|
| 15 | +#include "util/mmap.h" |
|---|
| 13 | 16 | |
|---|
| 14 | 17 | static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) |
|---|
| 15 | 18 | { |
|---|
| .. | .. |
|---|
| 50 | 53 | }; |
|---|
| 51 | 54 | cpu_set_t cpu_mask; |
|---|
| 52 | 55 | size_t cpu_mask_size = sizeof(cpu_mask); |
|---|
| 53 | | - struct perf_evlist *evlist = perf_evlist__new_dummy(); |
|---|
| 54 | | - struct perf_evsel *evsel; |
|---|
| 56 | + struct evlist *evlist = perf_evlist__new_dummy(); |
|---|
| 57 | + struct evsel *evsel; |
|---|
| 55 | 58 | struct perf_sample sample; |
|---|
| 56 | 59 | const char *cmd = "sleep"; |
|---|
| 57 | 60 | const char *argv[] = { cmd, "1", NULL, }; |
|---|
| 58 | 61 | char *bname, *mmap_filename; |
|---|
| 59 | 62 | u64 prev_time = 0; |
|---|
| 60 | 63 | bool found_cmd_mmap = false, |
|---|
| 64 | + found_coreutils_mmap = false, |
|---|
| 61 | 65 | found_libc_mmap = false, |
|---|
| 62 | 66 | found_vdso_mmap = false, |
|---|
| 63 | 67 | found_ld_mmap = false; |
|---|
| .. | .. |
|---|
| 101 | 105 | /* |
|---|
| 102 | 106 | * Config the evsels, setting attr->comm on the first one, etc. |
|---|
| 103 | 107 | */ |
|---|
| 104 | | - evsel = perf_evlist__first(evlist); |
|---|
| 105 | | - perf_evsel__set_sample_bit(evsel, CPU); |
|---|
| 106 | | - perf_evsel__set_sample_bit(evsel, TID); |
|---|
| 107 | | - perf_evsel__set_sample_bit(evsel, TIME); |
|---|
| 108 | + evsel = evlist__first(evlist); |
|---|
| 109 | + evsel__set_sample_bit(evsel, CPU); |
|---|
| 110 | + evsel__set_sample_bit(evsel, TID); |
|---|
| 111 | + evsel__set_sample_bit(evsel, TIME); |
|---|
| 108 | 112 | perf_evlist__config(evlist, &opts, NULL); |
|---|
| 109 | 113 | |
|---|
| 110 | 114 | err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); |
|---|
| .. | .. |
|---|
| 129 | 133 | * Call sys_perf_event_open on all the fds on all the evsels, |
|---|
| 130 | 134 | * grouping them if asked to. |
|---|
| 131 | 135 | */ |
|---|
| 132 | | - err = perf_evlist__open(evlist); |
|---|
| 136 | + err = evlist__open(evlist); |
|---|
| 133 | 137 | if (err < 0) { |
|---|
| 134 | 138 | pr_debug("perf_evlist__open: %s\n", |
|---|
| 135 | 139 | str_error_r(errno, sbuf, sizeof(sbuf))); |
|---|
| .. | .. |
|---|
| 141 | 145 | * fds in the same CPU to be injected in the same mmap ring buffer |
|---|
| 142 | 146 | * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). |
|---|
| 143 | 147 | */ |
|---|
| 144 | | - err = perf_evlist__mmap(evlist, opts.mmap_pages); |
|---|
| 148 | + err = evlist__mmap(evlist, opts.mmap_pages); |
|---|
| 145 | 149 | if (err < 0) { |
|---|
| 146 | | - pr_debug("perf_evlist__mmap: %s\n", |
|---|
| 150 | + pr_debug("evlist__mmap: %s\n", |
|---|
| 147 | 151 | str_error_r(errno, sbuf, sizeof(sbuf))); |
|---|
| 148 | 152 | goto out_delete_evlist; |
|---|
| 149 | 153 | } |
|---|
| .. | .. |
|---|
| 152 | 156 | * Now that all is properly set up, enable the events, they will |
|---|
| 153 | 157 | * count just on workload.pid, which will start... |
|---|
| 154 | 158 | */ |
|---|
| 155 | | - perf_evlist__enable(evlist); |
|---|
| 159 | + evlist__enable(evlist); |
|---|
| 156 | 160 | |
|---|
| 157 | 161 | /* |
|---|
| 158 | 162 | * Now! |
|---|
| .. | .. |
|---|
| 162 | 166 | while (1) { |
|---|
| 163 | 167 | int before = total_events; |
|---|
| 164 | 168 | |
|---|
| 165 | | - for (i = 0; i < evlist->nr_mmaps; i++) { |
|---|
| 169 | + for (i = 0; i < evlist->core.nr_mmaps; i++) { |
|---|
| 166 | 170 | union perf_event *event; |
|---|
| 167 | | - struct perf_mmap *md; |
|---|
| 171 | + struct mmap *md; |
|---|
| 168 | 172 | |
|---|
| 169 | 173 | md = &evlist->mmap[i]; |
|---|
| 170 | | - if (perf_mmap__read_init(md) < 0) |
|---|
| 174 | + if (perf_mmap__read_init(&md->core) < 0) |
|---|
| 171 | 175 | continue; |
|---|
| 172 | 176 | |
|---|
| 173 | | - while ((event = perf_mmap__read_event(md)) != NULL) { |
|---|
| 177 | + while ((event = perf_mmap__read_event(&md->core)) != NULL) { |
|---|
| 174 | 178 | const u32 type = event->header.type; |
|---|
| 175 | 179 | const char *name = perf_event__name(type); |
|---|
| 176 | 180 | |
|---|
| .. | .. |
|---|
| 181 | 185 | err = perf_evlist__parse_sample(evlist, event, &sample); |
|---|
| 182 | 186 | if (err < 0) { |
|---|
| 183 | 187 | if (verbose > 0) |
|---|
| 184 | | - perf_event__fprintf(event, stderr); |
|---|
| 188 | + perf_event__fprintf(event, NULL, stderr); |
|---|
| 185 | 189 | pr_debug("Couldn't parse sample\n"); |
|---|
| 186 | 190 | goto out_delete_evlist; |
|---|
| 187 | 191 | } |
|---|
| 188 | 192 | |
|---|
| 189 | 193 | if (verbose > 0) { |
|---|
| 190 | 194 | pr_info("%" PRIu64" %d ", sample.time, sample.cpu); |
|---|
| 191 | | - perf_event__fprintf(event, stderr); |
|---|
| 195 | + perf_event__fprintf(event, NULL, stderr); |
|---|
| 192 | 196 | } |
|---|
| 193 | 197 | |
|---|
| 194 | 198 | if (prev_time > sample.time) { |
|---|
| .. | .. |
|---|
| 254 | 258 | if (bname != NULL) { |
|---|
| 255 | 259 | if (!found_cmd_mmap) |
|---|
| 256 | 260 | found_cmd_mmap = !strcmp(bname + 1, cmd); |
|---|
| 261 | + if (!found_coreutils_mmap) |
|---|
| 262 | + found_coreutils_mmap = !strcmp(bname + 1, "coreutils"); |
|---|
| 257 | 263 | if (!found_libc_mmap) |
|---|
| 258 | 264 | found_libc_mmap = !strncmp(bname + 1, "libc", 4); |
|---|
| 259 | 265 | if (!found_ld_mmap) |
|---|
| .. | .. |
|---|
| 271 | 277 | ++errs; |
|---|
| 272 | 278 | } |
|---|
| 273 | 279 | |
|---|
| 274 | | - perf_mmap__consume(md); |
|---|
| 280 | + perf_mmap__consume(&md->core); |
|---|
| 275 | 281 | } |
|---|
| 276 | | - perf_mmap__read_done(md); |
|---|
| 282 | + perf_mmap__read_done(&md->core); |
|---|
| 277 | 283 | } |
|---|
| 278 | 284 | |
|---|
| 279 | 285 | /* |
|---|
| .. | .. |
|---|
| 282 | 288 | * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does. |
|---|
| 283 | 289 | */ |
|---|
| 284 | 290 | if (total_events == before && false) |
|---|
| 285 | | - perf_evlist__poll(evlist, -1); |
|---|
| 291 | + evlist__poll(evlist, -1); |
|---|
| 286 | 292 | |
|---|
| 287 | 293 | sleep(1); |
|---|
| 288 | 294 | if (++wakeups > 5) { |
|---|
| .. | .. |
|---|
| 292 | 298 | } |
|---|
| 293 | 299 | |
|---|
| 294 | 300 | found_exit: |
|---|
| 295 | | - if (nr_events[PERF_RECORD_COMM] > 1) { |
|---|
| 301 | + if (nr_events[PERF_RECORD_COMM] > 1 + !!found_coreutils_mmap) { |
|---|
| 296 | 302 | pr_debug("Excessive number of PERF_RECORD_COMM events!\n"); |
|---|
| 297 | 303 | ++errs; |
|---|
| 298 | 304 | } |
|---|
| .. | .. |
|---|
| 302 | 308 | ++errs; |
|---|
| 303 | 309 | } |
|---|
| 304 | 310 | |
|---|
| 305 | | - if (!found_cmd_mmap) { |
|---|
| 311 | + if (!found_cmd_mmap && !found_coreutils_mmap) { |
|---|
| 306 | 312 | pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd); |
|---|
| 307 | 313 | ++errs; |
|---|
| 308 | 314 | } |
|---|
| .. | .. |
|---|
| 322 | 328 | ++errs; |
|---|
| 323 | 329 | } |
|---|
| 324 | 330 | out_delete_evlist: |
|---|
| 325 | | - perf_evlist__delete(evlist); |
|---|
| 331 | + evlist__delete(evlist); |
|---|
| 326 | 332 | out: |
|---|
| 327 | 333 | return (err < 0 || errs > 0) ? -1 : 0; |
|---|
| 328 | 334 | } |
|---|