1 // SPDX-License-Identifier: GPL-2.0 2 #include <perf/evlist.h> 3 #include <perf/evsel.h> 4 #include <linux/bitops.h> 5 #include <linux/list.h> 6 #include <linux/hash.h> 7 #include <sys/ioctl.h> 8 #include <internal/evlist.h> 9 #include <internal/evsel.h> 10 #include <internal/xyarray.h> 11 #include <internal/mmap.h> 12 #include <internal/cpumap.h> 13 #include <internal/threadmap.h> 14 #include <internal/lib.h> 15 #include <linux/zalloc.h> 16 #include <stdlib.h> 17 #include <errno.h> 18 #include <unistd.h> 19 #include <fcntl.h> 20 #include <signal.h> 21 #include <poll.h> 22 #include <sys/mman.h> 23 #include <perf/cpumap.h> 24 #include <perf/threadmap.h> 25 #include <api/fd/array.h> 26 #include "internal.h" 27 28 void perf_evlist__init(struct perf_evlist *evlist) 29 { 30 INIT_LIST_HEAD(&evlist->entries); 31 evlist->nr_entries = 0; 32 fdarray__init(&evlist->pollfd, 64); 33 perf_evlist__reset_id_hash(evlist); 34 } 35 36 static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, 37 struct perf_evsel *evsel) 38 { 39 if (perf_cpu_map__is_empty(evsel->cpus)) { 40 if (perf_cpu_map__is_empty(evsel->pmu_cpus)) { 41 /* 42 * Assume the unset PMU cpus were for a system-wide 43 * event, like a software or tracepoint. 44 */ 45 evsel->pmu_cpus = perf_cpu_map__new_online_cpus(); 46 } 47 if (evlist->has_user_cpus && !evsel->system_wide) { 48 /* 49 * Use the user CPUs unless the evsel is set to be 50 * system wide, such as the dummy event. 51 */ 52 evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus); 53 } else { 54 /* 55 * System wide and other modes, assume the cpu map 56 * should be set to all PMU CPUs. 57 */ 58 evsel->cpus = perf_cpu_map__get(evsel->pmu_cpus); 59 } 60 } 61 /* 62 * Avoid "any CPU"(-1) for uncore and PMUs that require a CPU, even if 63 * requested. 64 */ 65 if (evsel->requires_cpu && perf_cpu_map__has_any_cpu(evsel->cpus)) { 66 perf_cpu_map__put(evsel->cpus); 67 evsel->cpus = perf_cpu_map__get(evsel->pmu_cpus); 68 } 69 70 /* 71 * Globally requested CPUs replace user requested unless the evsel is 72 * set to be system wide. 73 */ 74 if (evlist->has_user_cpus && !evsel->system_wide) { 75 assert(!perf_cpu_map__has_any_cpu(evlist->user_requested_cpus)); 76 if (!perf_cpu_map__equal(evsel->cpus, evlist->user_requested_cpus)) { 77 perf_cpu_map__put(evsel->cpus); 78 evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus); 79 } 80 } 81 82 /* Ensure cpus only references valid PMU CPUs. */ 83 if (!perf_cpu_map__has_any_cpu(evsel->cpus) && 84 !perf_cpu_map__is_subset(evsel->pmu_cpus, evsel->cpus)) { 85 struct perf_cpu_map *tmp = perf_cpu_map__intersect(evsel->pmu_cpus, evsel->cpus); 86 87 perf_cpu_map__put(evsel->cpus); 88 evsel->cpus = tmp; 89 } 90 91 /* 92 * Was event requested on all the PMU's CPUs but the user requested is 93 * any CPU (-1)? If so switch to using any CPU (-1) to reduce the number 94 * of events. 95 */ 96 if (!evsel->system_wide && 97 !evsel->requires_cpu && 98 perf_cpu_map__equal(evsel->cpus, evsel->pmu_cpus) && 99 perf_cpu_map__has_any_cpu(evlist->user_requested_cpus)) { 100 perf_cpu_map__put(evsel->cpus); 101 evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus); 102 } 103 104 /* 105 * Tool events may only read on the first CPU index to avoid double 106 * counting things like duration_time. Make the evsel->cpus contain just 107 * that single entry otherwise we may spend time changing affinity to 108 * CPUs that just have tool events, etc. 109 */ 110 if (evsel->reads_only_on_cpu_idx0 && perf_cpu_map__nr(evsel->cpus) > 0) { 111 struct perf_cpu_map *srcs[3] = { 112 evlist->all_cpus, 113 evlist->user_requested_cpus, 114 evsel->pmu_cpus, 115 }; 116 for (size_t i = 0; i < ARRAY_SIZE(srcs); i++) { 117 if (!srcs[i]) 118 continue; 119 120 perf_cpu_map__put(evsel->cpus); 121 evsel->cpus = perf_cpu_map__new_int(perf_cpu_map__cpu(srcs[i], 0).cpu); 122 break; 123 } 124 } 125 126 /* Sanity check assert before the evsel is potentially removed. */ 127 assert(!evsel->requires_cpu || !perf_cpu_map__has_any_cpu(evsel->cpus)); 128 129 /* 130 * Empty cpu lists would eventually get opened as "any" so remove 131 * genuinely empty ones before they're opened in the wrong place. 132 */ 133 if (perf_cpu_map__is_empty(evsel->cpus)) { 134 struct perf_evsel *next = perf_evlist__next(evlist, evsel); 135 136 perf_evlist__remove(evlist, evsel); 137 /* Keep idx contiguous */ 138 if (next) 139 list_for_each_entry_from(next, &evlist->entries, node) 140 next->idx--; 141 142 return; 143 } 144 145 if (evsel->system_wide) { 146 perf_thread_map__put(evsel->threads); 147 evsel->threads = perf_thread_map__new_dummy(); 148 } else { 149 perf_thread_map__put(evsel->threads); 150 evsel->threads = perf_thread_map__get(evlist->threads); 151 } 152 153 perf_cpu_map__merge(&evlist->all_cpus, evsel->cpus); 154 } 155 156 static void perf_evlist__propagate_maps(struct perf_evlist *evlist) 157 { 158 evlist->needs_map_propagation = true; 159 160 /* Clear the all_cpus set which will be merged into during propagation. */ 161 perf_cpu_map__put(evlist->all_cpus); 162 evlist->all_cpus = NULL; 163 164 /* 2 rounds so that reads_only_on_cpu_idx0 benefit from knowing the other CPU maps. */ 165 for (int round = 0; round < 2; round++) { 166 struct perf_evsel *evsel, *n; 167 168 list_for_each_entry_safe(evsel, n, &evlist->entries, node) { 169 if ((!evsel->reads_only_on_cpu_idx0 && round == 0) || 170 (evsel->reads_only_on_cpu_idx0 && round == 1)) 171 __perf_evlist__propagate_maps(evlist, evsel); 172 } 173 } 174 } 175 176 void perf_evlist__add(struct perf_evlist *evlist, 177 struct perf_evsel *evsel) 178 { 179 evsel->idx = evlist->nr_entries; 180 list_add_tail(&evsel->node, &evlist->entries); 181 evlist->nr_entries += 1; 182 183 if (evlist->needs_map_propagation) 184 __perf_evlist__propagate_maps(evlist, evsel); 185 } 186 187 void perf_evlist__remove(struct perf_evlist *evlist, 188 struct perf_evsel *evsel) 189 { 190 list_del_init(&evsel->node); 191 evlist->nr_entries -= 1; 192 } 193 194 struct perf_evlist *perf_evlist__new(void) 195 { 196 struct perf_evlist *evlist = zalloc(sizeof(*evlist)); 197 198 if (evlist != NULL) 199 perf_evlist__init(evlist); 200 201 return evlist; 202 } 203 204 struct perf_evsel * 205 perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *prev) 206 { 207 struct perf_evsel *next; 208 209 if (!prev) { 210 next = list_first_entry(&evlist->entries, 211 struct perf_evsel, 212 node); 213 } else { 214 next = list_next_entry(prev, node); 215 } 216 217 /* Empty list is noticed here so don't need checking on entry. */ 218 if (&next->node == &evlist->entries) 219 return NULL; 220 221 return next; 222 } 223 224 static void perf_evlist__purge(struct perf_evlist *evlist) 225 { 226 struct perf_evsel *pos, *n; 227 228 perf_evlist__for_each_entry_safe(evlist, n, pos) { 229 list_del_init(&pos->node); 230 perf_evsel__delete(pos); 231 } 232 233 evlist->nr_entries = 0; 234 } 235 236 void perf_evlist__exit(struct perf_evlist *evlist) 237 { 238 perf_cpu_map__put(evlist->user_requested_cpus); 239 perf_cpu_map__put(evlist->all_cpus); 240 perf_thread_map__put(evlist->threads); 241 evlist->user_requested_cpus = NULL; 242 evlist->all_cpus = NULL; 243 evlist->threads = NULL; 244 fdarray__exit(&evlist->pollfd); 245 } 246 247 void perf_evlist__delete(struct perf_evlist *evlist) 248 { 249 if (evlist == NULL) 250 return; 251 252 perf_evlist__munmap(evlist); 253 perf_evlist__close(evlist); 254 perf_evlist__purge(evlist); 255 perf_evlist__exit(evlist); 256 free(evlist); 257 } 258 259 void perf_evlist__set_maps(struct perf_evlist *evlist, 260 struct perf_cpu_map *cpus, 261 struct perf_thread_map *threads) 262 { 263 /* 264 * Allow for the possibility that one or another of the maps isn't being 265 * changed i.e. don't put it. Note we are assuming the maps that are 266 * being applied are brand new and evlist is taking ownership of the 267 * original reference count of 1. If that is not the case it is up to 268 * the caller to increase the reference count. 269 */ 270 if (cpus != evlist->user_requested_cpus) { 271 perf_cpu_map__put(evlist->user_requested_cpus); 272 evlist->user_requested_cpus = perf_cpu_map__get(cpus); 273 } 274 275 if (threads != evlist->threads) { 276 perf_thread_map__put(evlist->threads); 277 evlist->threads = perf_thread_map__get(threads); 278 } 279 280 perf_evlist__propagate_maps(evlist); 281 } 282 283 int perf_evlist__open(struct perf_evlist *evlist) 284 { 285 struct perf_evsel *evsel; 286 int err; 287 288 perf_evlist__for_each_entry(evlist, evsel) { 289 err = perf_evsel__open(evsel, evsel->cpus, evsel->threads); 290 if (err < 0) 291 goto out_err; 292 } 293 294 return 0; 295 296 out_err: 297 perf_evlist__close(evlist); 298 return err; 299 } 300 301 void perf_evlist__close(struct perf_evlist *evlist) 302 { 303 struct perf_evsel *evsel; 304 305 perf_evlist__for_each_entry_reverse(evlist, evsel) 306 perf_evsel__close(evsel); 307 } 308 309 void perf_evlist__enable(struct perf_evlist *evlist) 310 { 311 struct perf_evsel *evsel; 312 313 perf_evlist__for_each_entry(evlist, evsel) 314 perf_evsel__enable(evsel); 315 } 316 317 void perf_evlist__disable(struct perf_evlist *evlist) 318 { 319 struct perf_evsel *evsel; 320 321 perf_evlist__for_each_entry(evlist, evsel) 322 perf_evsel__disable(evsel); 323 } 324 325 u64 perf_evlist__read_format(struct perf_evlist *evlist) 326 { 327 struct perf_evsel *first = perf_evlist__first(evlist); 328 329 return first->attr.read_format; 330 } 331 332 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 333 334 static void perf_evlist__id_hash(struct perf_evlist *evlist, 335 struct perf_evsel *evsel, 336 int cpu_map_idx, int thread, u64 id) 337 { 338 int hash; 339 struct perf_sample_id *sid = SID(evsel, cpu_map_idx, thread); 340 341 sid->id = id; 342 sid->evsel = evsel; 343 hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); 344 hlist_add_head(&sid->node, &evlist->heads[hash]); 345 } 346 347 void perf_evlist__reset_id_hash(struct perf_evlist *evlist) 348 { 349 int i; 350 351 for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) 352 INIT_HLIST_HEAD(&evlist->heads[i]); 353 } 354 355 void perf_evlist__id_add(struct perf_evlist *evlist, 356 struct perf_evsel *evsel, 357 int cpu_map_idx, int thread, u64 id) 358 { 359 if (!SID(evsel, cpu_map_idx, thread)) 360 return; 361 362 perf_evlist__id_hash(evlist, evsel, cpu_map_idx, thread, id); 363 evsel->id[evsel->ids++] = id; 364 } 365 366 int perf_evlist__id_add_fd(struct perf_evlist *evlist, 367 struct perf_evsel *evsel, 368 int cpu_map_idx, int thread, int fd) 369 { 370 u64 read_data[4] = { 0, }; 371 int id_idx = 1; /* The first entry is the counter value */ 372 u64 id; 373 int ret; 374 375 if (!SID(evsel, cpu_map_idx, thread)) 376 return -1; 377 378 ret = ioctl(fd, PERF_EVENT_IOC_ID, &id); 379 if (!ret) 380 goto add; 381 382 if (errno != ENOTTY) 383 return -1; 384 385 /* Legacy way to get event id.. All hail to old kernels! */ 386 387 /* 388 * This way does not work with group format read, so bail 389 * out in that case. 390 */ 391 if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) 392 return -1; 393 394 if (!(evsel->attr.read_format & PERF_FORMAT_ID) || 395 read(fd, &read_data, sizeof(read_data)) == -1) 396 return -1; 397 398 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 399 ++id_idx; 400 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 401 ++id_idx; 402 403 id = read_data[id_idx]; 404 405 add: 406 perf_evlist__id_add(evlist, evsel, cpu_map_idx, thread, id); 407 return 0; 408 } 409 410 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) 411 { 412 int nr_cpus = perf_cpu_map__nr(evlist->all_cpus); 413 int nr_threads = perf_thread_map__nr(evlist->threads); 414 int nfds = 0; 415 struct perf_evsel *evsel; 416 417 perf_evlist__for_each_entry(evlist, evsel) { 418 if (evsel->system_wide) 419 nfds += nr_cpus; 420 else 421 nfds += nr_cpus * nr_threads; 422 } 423 424 if (fdarray__available_entries(&evlist->pollfd) < nfds && 425 fdarray__grow(&evlist->pollfd, nfds) < 0) 426 return -ENOMEM; 427 428 return 0; 429 } 430 431 int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, 432 void *ptr, short revent, enum fdarray_flags flags) 433 { 434 int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP, flags); 435 436 if (pos >= 0) { 437 evlist->pollfd.priv[pos].ptr = ptr; 438 fcntl(fd, F_SETFL, O_NONBLOCK); 439 } 440 441 return pos; 442 } 443 444 static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, 445 void *arg __maybe_unused) 446 { 447 struct perf_mmap *map = fda->priv[fd].ptr; 448 449 if (map) 450 perf_mmap__put(map); 451 } 452 453 int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) 454 { 455 return fdarray__filter(&evlist->pollfd, revents_and_mask, 456 perf_evlist__munmap_filtered, NULL); 457 } 458 459 int perf_evlist__poll(struct perf_evlist *evlist, int timeout) 460 { 461 return fdarray__poll(&evlist->pollfd, timeout); 462 } 463 464 static struct perf_mmap* perf_evlist__alloc_mmap(struct perf_evlist *evlist, bool overwrite) 465 { 466 int i; 467 struct perf_mmap *map; 468 469 map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 470 if (!map) 471 return NULL; 472 473 for (i = 0; i < evlist->nr_mmaps; i++) { 474 struct perf_mmap *prev = i ? &map[i - 1] : NULL; 475 476 /* 477 * When the perf_mmap() call is made we grab one refcount, plus 478 * one extra to let perf_mmap__consume() get the last 479 * events after all real references (perf_mmap__get()) are 480 * dropped. 481 * 482 * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and 483 * thus does perf_mmap__get() on it. 484 */ 485 perf_mmap__init(&map[i], prev, overwrite, NULL); 486 } 487 488 return map; 489 } 490 491 static void perf_evsel__set_sid_idx(struct perf_evsel *evsel, int idx, int cpu, int thread) 492 { 493 struct perf_sample_id *sid = SID(evsel, cpu, thread); 494 495 sid->idx = idx; 496 sid->cpu = perf_cpu_map__cpu(evsel->cpus, cpu); 497 sid->tid = perf_thread_map__pid(evsel->threads, thread); 498 } 499 500 static struct perf_mmap* 501 perf_evlist__mmap_cb_get(struct perf_evlist *evlist, bool overwrite, int idx) 502 { 503 struct perf_mmap *maps; 504 505 maps = overwrite ? evlist->mmap_ovw : evlist->mmap; 506 507 if (!maps) { 508 maps = perf_evlist__alloc_mmap(evlist, overwrite); 509 if (!maps) 510 return NULL; 511 512 if (overwrite) 513 evlist->mmap_ovw = maps; 514 else 515 evlist->mmap = maps; 516 } 517 518 return &maps[idx]; 519 } 520 521 #define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y)) 522 523 static int 524 perf_evlist__mmap_cb_mmap(struct perf_mmap *map, struct perf_mmap_param *mp, 525 int output, struct perf_cpu cpu) 526 { 527 return perf_mmap__mmap(map, mp, output, cpu); 528 } 529 530 static void perf_evlist__set_mmap_first(struct perf_evlist *evlist, struct perf_mmap *map, 531 bool overwrite) 532 { 533 if (overwrite) 534 evlist->mmap_ovw_first = map; 535 else 536 evlist->mmap_first = map; 537 } 538 539 static int 540 mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, 541 int idx, struct perf_mmap_param *mp, int cpu_idx, 542 int thread, int *_output, int *_output_overwrite, int *nr_mmaps) 543 { 544 struct perf_cpu evlist_cpu = perf_cpu_map__cpu(evlist->all_cpus, cpu_idx); 545 struct perf_evsel *evsel; 546 int revent; 547 548 perf_evlist__for_each_entry(evlist, evsel) { 549 bool overwrite = evsel->attr.write_backward; 550 enum fdarray_flags flgs; 551 struct perf_mmap *map; 552 int *output, fd, cpu; 553 554 if (evsel->system_wide && thread) 555 continue; 556 557 cpu = perf_cpu_map__idx(evsel->cpus, evlist_cpu); 558 if (cpu == -1) 559 continue; 560 561 map = ops->get(evlist, overwrite, idx); 562 if (map == NULL) 563 return -ENOMEM; 564 565 if (overwrite) { 566 mp->prot = PROT_READ; 567 output = _output_overwrite; 568 } else { 569 mp->prot = PROT_READ | PROT_WRITE; 570 output = _output; 571 } 572 573 fd = FD(evsel, cpu, thread); 574 575 if (*output == -1) { 576 *output = fd; 577 578 /* 579 * The last one will be done at perf_mmap__consume(), so that we 580 * make sure we don't prevent tools from consuming every last event in 581 * the ring buffer. 582 * 583 * I.e. we can get the POLLHUP meaning that the fd doesn't exist 584 * anymore, but the last events for it are still in the ring buffer, 585 * waiting to be consumed. 586 * 587 * Tools can chose to ignore this at their own discretion, but the 588 * evlist layer can't just drop it when filtering events in 589 * perf_evlist__filter_pollfd(). 590 */ 591 refcount_set(&map->refcnt, 2); 592 593 if (ops->idx) 594 ops->idx(evlist, evsel, mp, idx); 595 596 /* Debug message used by test scripts */ 597 pr_debug("idx %d: mmapping fd %d\n", idx, *output); 598 if (ops->mmap(map, mp, *output, evlist_cpu) < 0) 599 return -1; 600 601 *nr_mmaps += 1; 602 603 if (!idx) 604 perf_evlist__set_mmap_first(evlist, map, overwrite); 605 } else { 606 /* Debug message used by test scripts */ 607 pr_debug("idx %d: set output fd %d -> %d\n", idx, fd, *output); 608 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) 609 return -1; 610 611 perf_mmap__get(map); 612 } 613 614 revent = !overwrite ? POLLIN : 0; 615 616 flgs = evsel->system_wide ? fdarray_flag__nonfilterable : fdarray_flag__default; 617 if (perf_evlist__add_pollfd(evlist, fd, map, revent, flgs) < 0) { 618 perf_mmap__put(map); 619 return -1; 620 } 621 622 if (evsel->attr.read_format & PERF_FORMAT_ID) { 623 if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, 624 fd) < 0) 625 return -1; 626 perf_evsel__set_sid_idx(evsel, idx, cpu, thread); 627 } 628 } 629 630 return 0; 631 } 632 633 static int 634 mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, 635 struct perf_mmap_param *mp) 636 { 637 int nr_threads = perf_thread_map__nr(evlist->threads); 638 int nr_cpus = perf_cpu_map__nr(evlist->all_cpus); 639 int cpu, thread, idx = 0; 640 int nr_mmaps = 0; 641 642 pr_debug("%s: nr cpu values (may include -1) %d nr threads %d\n", 643 __func__, nr_cpus, nr_threads); 644 645 /* per-thread mmaps */ 646 for (thread = 0; thread < nr_threads; thread++, idx++) { 647 int output = -1; 648 int output_overwrite = -1; 649 650 if (mmap_per_evsel(evlist, ops, idx, mp, 0, thread, &output, 651 &output_overwrite, &nr_mmaps)) 652 goto out_unmap; 653 } 654 655 /* system-wide mmaps i.e. per-cpu */ 656 for (cpu = 1; cpu < nr_cpus; cpu++, idx++) { 657 int output = -1; 658 int output_overwrite = -1; 659 660 if (mmap_per_evsel(evlist, ops, idx, mp, cpu, 0, &output, 661 &output_overwrite, &nr_mmaps)) 662 goto out_unmap; 663 } 664 665 if (nr_mmaps != evlist->nr_mmaps) 666 pr_err("Miscounted nr_mmaps %d vs %d\n", nr_mmaps, evlist->nr_mmaps); 667 668 return 0; 669 670 out_unmap: 671 perf_evlist__munmap(evlist); 672 return -1; 673 } 674 675 static int 676 mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops, 677 struct perf_mmap_param *mp) 678 { 679 int nr_threads = perf_thread_map__nr(evlist->threads); 680 int nr_cpus = perf_cpu_map__nr(evlist->all_cpus); 681 int nr_mmaps = 0; 682 int cpu, thread; 683 684 pr_debug("%s: nr cpu values %d nr threads %d\n", __func__, nr_cpus, nr_threads); 685 686 for (cpu = 0; cpu < nr_cpus; cpu++) { 687 int output = -1; 688 int output_overwrite = -1; 689 690 for (thread = 0; thread < nr_threads; thread++) { 691 if (mmap_per_evsel(evlist, ops, cpu, mp, cpu, 692 thread, &output, &output_overwrite, &nr_mmaps)) 693 goto out_unmap; 694 } 695 } 696 697 if (nr_mmaps != evlist->nr_mmaps) 698 pr_err("Miscounted nr_mmaps %d vs %d\n", nr_mmaps, evlist->nr_mmaps); 699 700 return 0; 701 702 out_unmap: 703 perf_evlist__munmap(evlist); 704 return -1; 705 } 706 707 static int perf_evlist__nr_mmaps(struct perf_evlist *evlist) 708 { 709 int nr_mmaps; 710 711 /* One for each CPU */ 712 nr_mmaps = perf_cpu_map__nr(evlist->all_cpus); 713 if (perf_cpu_map__has_any_cpu_or_is_empty(evlist->all_cpus)) { 714 /* Plus one for each thread */ 715 nr_mmaps += perf_thread_map__nr(evlist->threads); 716 /* Minus the per-thread CPU (-1) */ 717 nr_mmaps -= 1; 718 } 719 720 return nr_mmaps; 721 } 722 723 int perf_evlist__mmap_ops(struct perf_evlist *evlist, 724 struct perf_evlist_mmap_ops *ops, 725 struct perf_mmap_param *mp) 726 { 727 const struct perf_cpu_map *cpus = evlist->all_cpus; 728 struct perf_evsel *evsel; 729 730 if (!ops || !ops->get || !ops->mmap) 731 return -EINVAL; 732 733 mp->mask = evlist->mmap_len - page_size - 1; 734 735 evlist->nr_mmaps = perf_evlist__nr_mmaps(evlist); 736 737 perf_evlist__for_each_entry(evlist, evsel) { 738 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 739 evsel->sample_id == NULL && 740 perf_evsel__alloc_id(evsel, evsel->fd->max_x, evsel->fd->max_y) < 0) 741 return -ENOMEM; 742 } 743 744 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 745 return -ENOMEM; 746 747 if (perf_cpu_map__has_any_cpu_or_is_empty(cpus)) 748 return mmap_per_thread(evlist, ops, mp); 749 750 return mmap_per_cpu(evlist, ops, mp); 751 } 752 753 int perf_evlist__mmap(struct perf_evlist *evlist, int pages) 754 { 755 struct perf_mmap_param mp; 756 struct perf_evlist_mmap_ops ops = { 757 .get = perf_evlist__mmap_cb_get, 758 .mmap = perf_evlist__mmap_cb_mmap, 759 }; 760 761 evlist->mmap_len = (pages + 1) * page_size; 762 763 return perf_evlist__mmap_ops(evlist, &ops, &mp); 764 } 765 766 void perf_evlist__munmap(struct perf_evlist *evlist) 767 { 768 int i; 769 770 if (evlist->mmap) { 771 for (i = 0; i < evlist->nr_mmaps; i++) 772 perf_mmap__munmap(&evlist->mmap[i]); 773 } 774 775 if (evlist->mmap_ovw) { 776 for (i = 0; i < evlist->nr_mmaps; i++) 777 perf_mmap__munmap(&evlist->mmap_ovw[i]); 778 } 779 780 zfree(&evlist->mmap); 781 zfree(&evlist->mmap_ovw); 782 } 783 784 struct perf_mmap* 785 perf_evlist__next_mmap(struct perf_evlist *evlist, struct perf_mmap *map, 786 bool overwrite) 787 { 788 if (map) 789 return map->next; 790 791 return overwrite ? evlist->mmap_ovw_first : evlist->mmap_first; 792 } 793 794 void __perf_evlist__set_leader(struct list_head *list, struct perf_evsel *leader) 795 { 796 struct perf_evsel *evsel; 797 int n = 0; 798 799 __perf_evlist__for_each_entry(list, evsel) { 800 evsel->leader = leader; 801 n++; 802 } 803 leader->nr_members = n; 804 } 805 806 void perf_evlist__set_leader(struct perf_evlist *evlist) 807 { 808 if (evlist->nr_entries) { 809 struct perf_evsel *first = list_entry(evlist->entries.next, 810 struct perf_evsel, node); 811 812 __perf_evlist__set_leader(&evlist->entries, first); 813 } 814 } 815 816 int perf_evlist__nr_groups(struct perf_evlist *evlist) 817 { 818 struct perf_evsel *evsel; 819 int nr_groups = 0; 820 821 perf_evlist__for_each_evsel(evlist, evsel) { 822 /* 823 * evsels by default have a nr_members of 1, and they are their 824 * own leader. If the nr_members is >1 then this is an 825 * indication of a group. 826 */ 827 if (evsel->leader == evsel && evsel->nr_members > 1) 828 nr_groups++; 829 } 830 return nr_groups; 831 } 832 833 void perf_evlist__go_system_wide(struct perf_evlist *evlist, struct perf_evsel *evsel) 834 { 835 if (!evsel->system_wide) { 836 evsel->system_wide = true; 837 if (evlist->needs_map_propagation) 838 __perf_evlist__propagate_maps(evlist, evsel); 839 } 840 } 841