191007045SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2f8a95309SArnaldo Carvalho de Melo /* 3f8a95309SArnaldo Carvalho de Melo * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 4f8a95309SArnaldo Carvalho de Melo * 5f8a95309SArnaldo Carvalho de Melo * Parts came from builtin-{top,stat,record}.c, see those files for further 6f8a95309SArnaldo Carvalho de Melo * copyright notes. 7f8a95309SArnaldo Carvalho de Melo */ 8956fa571SArnaldo Carvalho de Melo #include <api/fs/fs.h> 9a43783aeSArnaldo Carvalho de Melo #include <errno.h> 10fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 115c581041SArnaldo Carvalho de Melo #include <poll.h> 12f8a95309SArnaldo Carvalho de Melo #include "cpumap.h" 13f8a95309SArnaldo Carvalho de Melo #include "thread_map.h" 1412864b31SNamhyung Kim #include "target.h" 15361c99a6SArnaldo Carvalho de Melo #include "evlist.h" 16361c99a6SArnaldo Carvalho de Melo #include "evsel.h" 17e3e1a54fSAdrian Hunter #include "debug.h" 1858db1d6eSArnaldo Carvalho de Melo #include "units.h" 1954cc54deSWang Nan #include "asm/bug.h" 20657ee553SSong Liu #include "bpf-event.h" 219607ad3aSArnaldo Carvalho de Melo #include <signal.h> 2235b9d88eSArnaldo Carvalho de Melo #include <unistd.h> 23361c99a6SArnaldo Carvalho de Melo 2450d08e47SArnaldo Carvalho de Melo #include "parse-events.h" 254b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 2650d08e47SArnaldo Carvalho de Melo 27bafae98eSArnaldo Carvalho de Melo #include <fcntl.h> 2886a5e0c2SArnaldo Carvalho de Melo #include <sys/ioctl.h> 29f8a95309SArnaldo Carvalho de Melo #include <sys/mman.h> 30f8a95309SArnaldo Carvalho de Melo 3170db7533SArnaldo Carvalho de Melo #include <linux/bitops.h> 3270db7533SArnaldo Carvalho de Melo #include <linux/hash.h> 330389cd1fSArnaldo Carvalho de Melo #include <linux/log2.h> 348dd2a131SJiri Olsa #include <linux/err.h> 357f7c536fSArnaldo Carvalho de Melo #include <linux/zalloc.h> 3670db7533SArnaldo Carvalho de Melo 37748fe088SArnaldo Carvalho de Melo #ifdef LACKS_SIGQUEUE_PROTOTYPE 38748fe088SArnaldo Carvalho de Melo int sigqueue(pid_t pid, int sig, const union sigval value); 39748fe088SArnaldo Carvalho de Melo #endif 40748fe088SArnaldo Carvalho de Melo 41f8a95309SArnaldo Carvalho de Melo #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 42a91e5431SArnaldo Carvalho de Melo #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 43f8a95309SArnaldo Carvalho de Melo 4452c86bcaSJiri Olsa void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, 459749b90eSJiri Olsa struct perf_thread_map *threads) 46361c99a6SArnaldo Carvalho de Melo { 4770db7533SArnaldo Carvalho de Melo int i; 4870db7533SArnaldo Carvalho de Melo 4970db7533SArnaldo Carvalho de Melo for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) 5070db7533SArnaldo Carvalho de Melo INIT_HLIST_HEAD(&evlist->heads[i]); 51ce9036a6SJiri Olsa INIT_LIST_HEAD(&evlist->core.entries); 527e2ed097SArnaldo Carvalho de Melo perf_evlist__set_maps(evlist, cpus, threads); 531b85337dSArnaldo Carvalho de Melo fdarray__init(&evlist->pollfd, 64); 5435b9d88eSArnaldo Carvalho de Melo evlist->workload.pid = -1; 5554cc54deSWang Nan evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; 56361c99a6SArnaldo Carvalho de Melo } 57361c99a6SArnaldo Carvalho de Melo 580f98b11cSJiri Olsa struct evlist *evlist__new(void) 59ef1d1af2SArnaldo Carvalho de Melo { 6063503dbaSJiri Olsa struct evlist *evlist = zalloc(sizeof(*evlist)); 61ef1d1af2SArnaldo Carvalho de Melo 62ef1d1af2SArnaldo Carvalho de Melo if (evlist != NULL) 6352c86bcaSJiri Olsa evlist__init(evlist, NULL, NULL); 64ef1d1af2SArnaldo Carvalho de Melo 65361c99a6SArnaldo Carvalho de Melo return evlist; 66361c99a6SArnaldo Carvalho de Melo } 67361c99a6SArnaldo Carvalho de Melo 6863503dbaSJiri Olsa struct evlist *perf_evlist__new_default(void) 69b22d54b0SJiri Olsa { 700f98b11cSJiri Olsa struct evlist *evlist = evlist__new(); 71b22d54b0SJiri Olsa 72b22d54b0SJiri Olsa if (evlist && perf_evlist__add_default(evlist)) { 73c12995a5SJiri Olsa evlist__delete(evlist); 74b22d54b0SJiri Olsa evlist = NULL; 75b22d54b0SJiri Olsa } 76b22d54b0SJiri Olsa 77b22d54b0SJiri Olsa return evlist; 78b22d54b0SJiri Olsa } 79b22d54b0SJiri Olsa 8063503dbaSJiri Olsa struct evlist *perf_evlist__new_dummy(void) 815bae0250SArnaldo Carvalho de Melo { 820f98b11cSJiri Olsa struct evlist *evlist = evlist__new(); 835bae0250SArnaldo Carvalho de Melo 845bae0250SArnaldo Carvalho de Melo if (evlist && perf_evlist__add_dummy(evlist)) { 85c12995a5SJiri Olsa evlist__delete(evlist); 865bae0250SArnaldo Carvalho de Melo evlist = NULL; 875bae0250SArnaldo Carvalho de Melo } 885bae0250SArnaldo Carvalho de Melo 895bae0250SArnaldo Carvalho de Melo return evlist; 905bae0250SArnaldo Carvalho de Melo } 915bae0250SArnaldo Carvalho de Melo 9275562573SAdrian Hunter /** 9375562573SAdrian Hunter * perf_evlist__set_id_pos - set the positions of event ids. 9475562573SAdrian Hunter * @evlist: selected event list 9575562573SAdrian Hunter * 9675562573SAdrian Hunter * Events with compatible sample types all have the same id_pos 9775562573SAdrian Hunter * and is_pos. For convenience, put a copy on evlist. 9875562573SAdrian Hunter */ 9963503dbaSJiri Olsa void perf_evlist__set_id_pos(struct evlist *evlist) 10075562573SAdrian Hunter { 10132dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 10275562573SAdrian Hunter 10375562573SAdrian Hunter evlist->id_pos = first->id_pos; 10475562573SAdrian Hunter evlist->is_pos = first->is_pos; 10575562573SAdrian Hunter } 10675562573SAdrian Hunter 10763503dbaSJiri Olsa static void perf_evlist__update_id_pos(struct evlist *evlist) 108733cd2feSAdrian Hunter { 10932dcd021SJiri Olsa struct evsel *evsel; 110733cd2feSAdrian Hunter 111e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 112733cd2feSAdrian Hunter perf_evsel__calc_id_pos(evsel); 113733cd2feSAdrian Hunter 114733cd2feSAdrian Hunter perf_evlist__set_id_pos(evlist); 115733cd2feSAdrian Hunter } 116733cd2feSAdrian Hunter 11763503dbaSJiri Olsa static void perf_evlist__purge(struct evlist *evlist) 118361c99a6SArnaldo Carvalho de Melo { 11932dcd021SJiri Olsa struct evsel *pos, *n; 120361c99a6SArnaldo Carvalho de Melo 121e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_safe(evlist, n, pos) { 122b27c4eceSJiri Olsa list_del_init(&pos->core.node); 123d49e4695SArnaldo Carvalho de Melo pos->evlist = NULL; 1245eb2dd2aSJiri Olsa evsel__delete(pos); 125361c99a6SArnaldo Carvalho de Melo } 126361c99a6SArnaldo Carvalho de Melo 127361c99a6SArnaldo Carvalho de Melo evlist->nr_entries = 0; 128361c99a6SArnaldo Carvalho de Melo } 129361c99a6SArnaldo Carvalho de Melo 13063503dbaSJiri Olsa void perf_evlist__exit(struct evlist *evlist) 131ef1d1af2SArnaldo Carvalho de Melo { 13204662523SArnaldo Carvalho de Melo zfree(&evlist->mmap); 1330b72d69aSWang Nan zfree(&evlist->overwrite_mmap); 1341b85337dSArnaldo Carvalho de Melo fdarray__exit(&evlist->pollfd); 135ef1d1af2SArnaldo Carvalho de Melo } 136ef1d1af2SArnaldo Carvalho de Melo 137c12995a5SJiri Olsa void evlist__delete(struct evlist *evlist) 138361c99a6SArnaldo Carvalho de Melo { 1390b04b3dcSArnaldo Carvalho de Melo if (evlist == NULL) 1400b04b3dcSArnaldo Carvalho de Melo return; 1410b04b3dcSArnaldo Carvalho de Melo 142983874d1SArnaldo Carvalho de Melo perf_evlist__munmap(evlist); 143750b4edeSJiri Olsa evlist__close(evlist); 14438f01d8dSJiri Olsa perf_cpu_map__put(evlist->cpus); 1457836e52eSJiri Olsa perf_thread_map__put(evlist->threads); 14603ad9747SArnaldo Carvalho de Melo evlist->cpus = NULL; 14703ad9747SArnaldo Carvalho de Melo evlist->threads = NULL; 148361c99a6SArnaldo Carvalho de Melo perf_evlist__purge(evlist); 149ef1d1af2SArnaldo Carvalho de Melo perf_evlist__exit(evlist); 150361c99a6SArnaldo Carvalho de Melo free(evlist); 151361c99a6SArnaldo Carvalho de Melo } 152361c99a6SArnaldo Carvalho de Melo 15363503dbaSJiri Olsa static void __perf_evlist__propagate_maps(struct evlist *evlist, 15432dcd021SJiri Olsa struct evsel *evsel) 155adc0c3e8SAdrian Hunter { 156adc0c3e8SAdrian Hunter /* 157adc0c3e8SAdrian Hunter * We already have cpus for evsel (via PMU sysfs) so 158adc0c3e8SAdrian Hunter * keep it, if there's no target cpu list defined. 159adc0c3e8SAdrian Hunter */ 160adc0c3e8SAdrian Hunter if (!evsel->own_cpus || evlist->has_user_cpus) { 16138f01d8dSJiri Olsa perf_cpu_map__put(evsel->cpus); 16238f01d8dSJiri Olsa evsel->cpus = perf_cpu_map__get(evlist->cpus); 163adc0c3e8SAdrian Hunter } else if (evsel->cpus != evsel->own_cpus) { 16438f01d8dSJiri Olsa perf_cpu_map__put(evsel->cpus); 16538f01d8dSJiri Olsa evsel->cpus = perf_cpu_map__get(evsel->own_cpus); 166adc0c3e8SAdrian Hunter } 167adc0c3e8SAdrian Hunter 1687836e52eSJiri Olsa perf_thread_map__put(evsel->threads); 1697836e52eSJiri Olsa evsel->threads = perf_thread_map__get(evlist->threads); 170adc0c3e8SAdrian Hunter } 171adc0c3e8SAdrian Hunter 17263503dbaSJiri Olsa static void perf_evlist__propagate_maps(struct evlist *evlist) 173adc0c3e8SAdrian Hunter { 17432dcd021SJiri Olsa struct evsel *evsel; 175adc0c3e8SAdrian Hunter 176e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 177adc0c3e8SAdrian Hunter __perf_evlist__propagate_maps(evlist, evsel); 178adc0c3e8SAdrian Hunter } 179adc0c3e8SAdrian Hunter 180a1cf3a75SJiri Olsa void evlist__add(struct evlist *evlist, struct evsel *entry) 181361c99a6SArnaldo Carvalho de Melo { 182d49e4695SArnaldo Carvalho de Melo entry->evlist = evlist; 183ce9036a6SJiri Olsa list_add_tail(&entry->core.node, &evlist->core.entries); 184ef503831SArnaldo Carvalho de Melo entry->idx = evlist->nr_entries; 18560b0896cSAdrian Hunter entry->tracking = !entry->idx; 186ef503831SArnaldo Carvalho de Melo 18775562573SAdrian Hunter if (!evlist->nr_entries++) 18875562573SAdrian Hunter perf_evlist__set_id_pos(evlist); 18944c42d71SAdrian Hunter 19044c42d71SAdrian Hunter __perf_evlist__propagate_maps(evlist, entry); 191361c99a6SArnaldo Carvalho de Melo } 192361c99a6SArnaldo Carvalho de Melo 19316251027SJiri Olsa void evlist__remove(struct evlist *evlist, struct evsel *evsel) 1944768230aSAdrian Hunter { 1954768230aSAdrian Hunter evsel->evlist = NULL; 196b27c4eceSJiri Olsa list_del_init(&evsel->core.node); 1974768230aSAdrian Hunter evlist->nr_entries -= 1; 1984768230aSAdrian Hunter } 1994768230aSAdrian Hunter 20063503dbaSJiri Olsa void perf_evlist__splice_list_tail(struct evlist *evlist, 201f114d6efSAdrian Hunter struct list_head *list) 20250d08e47SArnaldo Carvalho de Melo { 20332dcd021SJiri Olsa struct evsel *evsel, *temp; 20475562573SAdrian Hunter 205e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry_safe(list, temp, evsel) { 206b27c4eceSJiri Olsa list_del_init(&evsel->core.node); 207a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 208f114d6efSAdrian Hunter } 20950d08e47SArnaldo Carvalho de Melo } 21050d08e47SArnaldo Carvalho de Melo 21163dab225SArnaldo Carvalho de Melo void __perf_evlist__set_leader(struct list_head *list) 21263dab225SArnaldo Carvalho de Melo { 21332dcd021SJiri Olsa struct evsel *evsel, *leader; 21463dab225SArnaldo Carvalho de Melo 215b27c4eceSJiri Olsa leader = list_entry(list->next, struct evsel, core.node); 216b27c4eceSJiri Olsa evsel = list_entry(list->prev, struct evsel, core.node); 21797f63e4aSNamhyung Kim 21897f63e4aSNamhyung Kim leader->nr_members = evsel->idx - leader->idx + 1; 21963dab225SArnaldo Carvalho de Melo 220e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry(list, evsel) { 22163dab225SArnaldo Carvalho de Melo evsel->leader = leader; 22263dab225SArnaldo Carvalho de Melo } 22363dab225SArnaldo Carvalho de Melo } 22463dab225SArnaldo Carvalho de Melo 22563503dbaSJiri Olsa void perf_evlist__set_leader(struct evlist *evlist) 2266a4bb04cSJiri Olsa { 22797f63e4aSNamhyung Kim if (evlist->nr_entries) { 22897f63e4aSNamhyung Kim evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0; 229ce9036a6SJiri Olsa __perf_evlist__set_leader(&evlist->core.entries); 2306a4bb04cSJiri Olsa } 23197f63e4aSNamhyung Kim } 2326a4bb04cSJiri Olsa 23363503dbaSJiri Olsa int __perf_evlist__add_default(struct evlist *evlist, bool precise) 234361c99a6SArnaldo Carvalho de Melo { 23532dcd021SJiri Olsa struct evsel *evsel = perf_evsel__new_cycles(precise); 236361c99a6SArnaldo Carvalho de Melo 237361c99a6SArnaldo Carvalho de Melo if (evsel == NULL) 2387c48dcfdSArnaldo Carvalho de Melo return -ENOMEM; 239361c99a6SArnaldo Carvalho de Melo 240a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 241361c99a6SArnaldo Carvalho de Melo return 0; 242361c99a6SArnaldo Carvalho de Melo } 2435c581041SArnaldo Carvalho de Melo 24463503dbaSJiri Olsa int perf_evlist__add_dummy(struct evlist *evlist) 2455bae0250SArnaldo Carvalho de Melo { 2465bae0250SArnaldo Carvalho de Melo struct perf_event_attr attr = { 2475bae0250SArnaldo Carvalho de Melo .type = PERF_TYPE_SOFTWARE, 2485bae0250SArnaldo Carvalho de Melo .config = PERF_COUNT_SW_DUMMY, 2495bae0250SArnaldo Carvalho de Melo .size = sizeof(attr), /* to capture ABI version */ 2505bae0250SArnaldo Carvalho de Melo }; 25132dcd021SJiri Olsa struct evsel *evsel = perf_evsel__new_idx(&attr, evlist->nr_entries); 2525bae0250SArnaldo Carvalho de Melo 2535bae0250SArnaldo Carvalho de Melo if (evsel == NULL) 2545bae0250SArnaldo Carvalho de Melo return -ENOMEM; 2555bae0250SArnaldo Carvalho de Melo 256a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 2575bae0250SArnaldo Carvalho de Melo return 0; 2585bae0250SArnaldo Carvalho de Melo } 2595bae0250SArnaldo Carvalho de Melo 260a1cf3a75SJiri Olsa static int evlist__add_attrs(struct evlist *evlist, 26150d08e47SArnaldo Carvalho de Melo struct perf_event_attr *attrs, size_t nr_attrs) 26250d08e47SArnaldo Carvalho de Melo { 26332dcd021SJiri Olsa struct evsel *evsel, *n; 26450d08e47SArnaldo Carvalho de Melo LIST_HEAD(head); 26550d08e47SArnaldo Carvalho de Melo size_t i; 26650d08e47SArnaldo Carvalho de Melo 26750d08e47SArnaldo Carvalho de Melo for (i = 0; i < nr_attrs; i++) { 268ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i); 26950d08e47SArnaldo Carvalho de Melo if (evsel == NULL) 27050d08e47SArnaldo Carvalho de Melo goto out_delete_partial_list; 271b27c4eceSJiri Olsa list_add_tail(&evsel->core.node, &head); 27250d08e47SArnaldo Carvalho de Melo } 27350d08e47SArnaldo Carvalho de Melo 274f114d6efSAdrian Hunter perf_evlist__splice_list_tail(evlist, &head); 27550d08e47SArnaldo Carvalho de Melo 27650d08e47SArnaldo Carvalho de Melo return 0; 27750d08e47SArnaldo Carvalho de Melo 27850d08e47SArnaldo Carvalho de Melo out_delete_partial_list: 279e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry_safe(&head, n, evsel) 2805eb2dd2aSJiri Olsa evsel__delete(evsel); 28150d08e47SArnaldo Carvalho de Melo return -1; 28250d08e47SArnaldo Carvalho de Melo } 28350d08e47SArnaldo Carvalho de Melo 28463503dbaSJiri Olsa int __perf_evlist__add_default_attrs(struct evlist *evlist, 28579695e1bSArnaldo Carvalho de Melo struct perf_event_attr *attrs, size_t nr_attrs) 28679695e1bSArnaldo Carvalho de Melo { 28779695e1bSArnaldo Carvalho de Melo size_t i; 28879695e1bSArnaldo Carvalho de Melo 28979695e1bSArnaldo Carvalho de Melo for (i = 0; i < nr_attrs; i++) 29079695e1bSArnaldo Carvalho de Melo event_attr_init(attrs + i); 29179695e1bSArnaldo Carvalho de Melo 292a1cf3a75SJiri Olsa return evlist__add_attrs(evlist, attrs, nr_attrs); 29379695e1bSArnaldo Carvalho de Melo } 29479695e1bSArnaldo Carvalho de Melo 29532dcd021SJiri Olsa struct evsel * 29663503dbaSJiri Olsa perf_evlist__find_tracepoint_by_id(struct evlist *evlist, int id) 297ee29be62SArnaldo Carvalho de Melo { 29832dcd021SJiri Olsa struct evsel *evsel; 299ee29be62SArnaldo Carvalho de Melo 300e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 301ee29be62SArnaldo Carvalho de Melo if (evsel->attr.type == PERF_TYPE_TRACEPOINT && 302ee29be62SArnaldo Carvalho de Melo (int)evsel->attr.config == id) 303ee29be62SArnaldo Carvalho de Melo return evsel; 304ee29be62SArnaldo Carvalho de Melo } 305ee29be62SArnaldo Carvalho de Melo 306ee29be62SArnaldo Carvalho de Melo return NULL; 307ee29be62SArnaldo Carvalho de Melo } 308ee29be62SArnaldo Carvalho de Melo 30932dcd021SJiri Olsa struct evsel * 31063503dbaSJiri Olsa perf_evlist__find_tracepoint_by_name(struct evlist *evlist, 311a2f2804aSDavid Ahern const char *name) 312a2f2804aSDavid Ahern { 31332dcd021SJiri Olsa struct evsel *evsel; 314a2f2804aSDavid Ahern 315e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 316a2f2804aSDavid Ahern if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) && 317a2f2804aSDavid Ahern (strcmp(evsel->name, name) == 0)) 318a2f2804aSDavid Ahern return evsel; 319a2f2804aSDavid Ahern } 320a2f2804aSDavid Ahern 321a2f2804aSDavid Ahern return NULL; 322a2f2804aSDavid Ahern } 323a2f2804aSDavid Ahern 32463503dbaSJiri Olsa int perf_evlist__add_newtp(struct evlist *evlist, 32539876e7dSArnaldo Carvalho de Melo const char *sys, const char *name, void *handler) 32639876e7dSArnaldo Carvalho de Melo { 32732dcd021SJiri Olsa struct evsel *evsel = perf_evsel__newtp(sys, name); 32839876e7dSArnaldo Carvalho de Melo 3298dd2a131SJiri Olsa if (IS_ERR(evsel)) 33039876e7dSArnaldo Carvalho de Melo return -1; 33139876e7dSArnaldo Carvalho de Melo 332744a9719SArnaldo Carvalho de Melo evsel->handler = handler; 333a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 33439876e7dSArnaldo Carvalho de Melo return 0; 33539876e7dSArnaldo Carvalho de Melo } 33639876e7dSArnaldo Carvalho de Melo 33763503dbaSJiri Olsa static int perf_evlist__nr_threads(struct evlist *evlist, 33832dcd021SJiri Olsa struct evsel *evsel) 339bf8e8f4bSAdrian Hunter { 340bf8e8f4bSAdrian Hunter if (evsel->system_wide) 341bf8e8f4bSAdrian Hunter return 1; 342bf8e8f4bSAdrian Hunter else 343bf8e8f4bSAdrian Hunter return thread_map__nr(evlist->threads); 344bf8e8f4bSAdrian Hunter } 345bf8e8f4bSAdrian Hunter 346e74676deSJiri Olsa void evlist__disable(struct evlist *evlist) 3474152ab37SArnaldo Carvalho de Melo { 34832dcd021SJiri Olsa struct evsel *pos; 3494152ab37SArnaldo Carvalho de Melo 350e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 351b7e8452bSArnaldo Carvalho de Melo if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->fd) 3523fe4430dSJiri Olsa continue; 3539a10bb22SJiri Olsa evsel__disable(pos); 3544152ab37SArnaldo Carvalho de Melo } 3552b56bcfbSArnaldo Carvalho de Melo 3562b56bcfbSArnaldo Carvalho de Melo evlist->enabled = false; 3574152ab37SArnaldo Carvalho de Melo } 3584152ab37SArnaldo Carvalho de Melo 3591c87f165SJiri Olsa void evlist__enable(struct evlist *evlist) 360764e16a3SDavid Ahern { 36132dcd021SJiri Olsa struct evsel *pos; 362764e16a3SDavid Ahern 363e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 364395c3070SAdrian Hunter if (!perf_evsel__is_group_leader(pos) || !pos->fd) 3653fe4430dSJiri Olsa continue; 366ec7f24efSJiri Olsa evsel__enable(pos); 367764e16a3SDavid Ahern } 3682b56bcfbSArnaldo Carvalho de Melo 3692b56bcfbSArnaldo Carvalho de Melo evlist->enabled = true; 3702b56bcfbSArnaldo Carvalho de Melo } 3712b56bcfbSArnaldo Carvalho de Melo 37263503dbaSJiri Olsa void perf_evlist__toggle_enable(struct evlist *evlist) 3732b56bcfbSArnaldo Carvalho de Melo { 374e74676deSJiri Olsa (evlist->enabled ? evlist__disable : evlist__enable)(evlist); 375764e16a3SDavid Ahern } 376764e16a3SDavid Ahern 37763503dbaSJiri Olsa static int perf_evlist__enable_event_cpu(struct evlist *evlist, 37832dcd021SJiri Olsa struct evsel *evsel, int cpu) 3791c65056cSAdrian Hunter { 38018ef15c6SArnaldo Carvalho de Melo int thread; 3811c65056cSAdrian Hunter int nr_threads = perf_evlist__nr_threads(evlist, evsel); 3821c65056cSAdrian Hunter 3831c65056cSAdrian Hunter if (!evsel->fd) 3841c65056cSAdrian Hunter return -EINVAL; 3851c65056cSAdrian Hunter 3861c65056cSAdrian Hunter for (thread = 0; thread < nr_threads; thread++) { 38718ef15c6SArnaldo Carvalho de Melo int err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 3881c65056cSAdrian Hunter if (err) 3891c65056cSAdrian Hunter return err; 3901c65056cSAdrian Hunter } 3911c65056cSAdrian Hunter return 0; 3921c65056cSAdrian Hunter } 3931c65056cSAdrian Hunter 39463503dbaSJiri Olsa static int perf_evlist__enable_event_thread(struct evlist *evlist, 39532dcd021SJiri Olsa struct evsel *evsel, 3961c65056cSAdrian Hunter int thread) 3971c65056cSAdrian Hunter { 39818ef15c6SArnaldo Carvalho de Melo int cpu; 3991c65056cSAdrian Hunter int nr_cpus = cpu_map__nr(evlist->cpus); 4001c65056cSAdrian Hunter 4011c65056cSAdrian Hunter if (!evsel->fd) 4021c65056cSAdrian Hunter return -EINVAL; 4031c65056cSAdrian Hunter 4041c65056cSAdrian Hunter for (cpu = 0; cpu < nr_cpus; cpu++) { 40518ef15c6SArnaldo Carvalho de Melo int err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 4061c65056cSAdrian Hunter if (err) 4071c65056cSAdrian Hunter return err; 4081c65056cSAdrian Hunter } 4091c65056cSAdrian Hunter return 0; 4101c65056cSAdrian Hunter } 4111c65056cSAdrian Hunter 41263503dbaSJiri Olsa int perf_evlist__enable_event_idx(struct evlist *evlist, 41332dcd021SJiri Olsa struct evsel *evsel, int idx) 4141c65056cSAdrian Hunter { 4151c65056cSAdrian Hunter bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus); 4161c65056cSAdrian Hunter 4171c65056cSAdrian Hunter if (per_cpu_mmaps) 4181c65056cSAdrian Hunter return perf_evlist__enable_event_cpu(evlist, evsel, idx); 4191c65056cSAdrian Hunter else 4201c65056cSAdrian Hunter return perf_evlist__enable_event_thread(evlist, evsel, idx); 4211c65056cSAdrian Hunter } 4221c65056cSAdrian Hunter 42363503dbaSJiri Olsa int perf_evlist__alloc_pollfd(struct evlist *evlist) 4245c581041SArnaldo Carvalho de Melo { 425b3a319d5SNamhyung Kim int nr_cpus = cpu_map__nr(evlist->cpus); 426b3a319d5SNamhyung Kim int nr_threads = thread_map__nr(evlist->threads); 427bf8e8f4bSAdrian Hunter int nfds = 0; 42832dcd021SJiri Olsa struct evsel *evsel; 429bf8e8f4bSAdrian Hunter 430e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 431bf8e8f4bSAdrian Hunter if (evsel->system_wide) 432bf8e8f4bSAdrian Hunter nfds += nr_cpus; 433bf8e8f4bSAdrian Hunter else 434bf8e8f4bSAdrian Hunter nfds += nr_cpus * nr_threads; 435bf8e8f4bSAdrian Hunter } 436bf8e8f4bSAdrian Hunter 4371b85337dSArnaldo Carvalho de Melo if (fdarray__available_entries(&evlist->pollfd) < nfds && 4381b85337dSArnaldo Carvalho de Melo fdarray__grow(&evlist->pollfd, nfds) < 0) 439ad6765ddSArnaldo Carvalho de Melo return -ENOMEM; 440ad6765ddSArnaldo Carvalho de Melo 441ad6765ddSArnaldo Carvalho de Melo return 0; 4425c581041SArnaldo Carvalho de Melo } 44370082dd9SArnaldo Carvalho de Melo 44463503dbaSJiri Olsa static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, 4454876075bSWang Nan struct perf_mmap *map, short revent) 446e4b356b5SArnaldo Carvalho de Melo { 447f3058a1cSWang Nan int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); 448e4b356b5SArnaldo Carvalho de Melo /* 449e4b356b5SArnaldo Carvalho de Melo * Save the idx so that when we filter out fds POLLHUP'ed we can 450e4b356b5SArnaldo Carvalho de Melo * close the associated evlist->mmap[] entry. 451e4b356b5SArnaldo Carvalho de Melo */ 452e4b356b5SArnaldo Carvalho de Melo if (pos >= 0) { 4534876075bSWang Nan evlist->pollfd.priv[pos].ptr = map; 454e4b356b5SArnaldo Carvalho de Melo 455e4b356b5SArnaldo Carvalho de Melo fcntl(fd, F_SETFL, O_NONBLOCK); 456e4b356b5SArnaldo Carvalho de Melo } 457e4b356b5SArnaldo Carvalho de Melo 458e4b356b5SArnaldo Carvalho de Melo return pos; 459e4b356b5SArnaldo Carvalho de Melo } 460e4b356b5SArnaldo Carvalho de Melo 46163503dbaSJiri Olsa int perf_evlist__add_pollfd(struct evlist *evlist, int fd) 46270082dd9SArnaldo Carvalho de Melo { 4634876075bSWang Nan return __perf_evlist__add_pollfd(evlist, fd, NULL, POLLIN); 464e4b356b5SArnaldo Carvalho de Melo } 4651b85337dSArnaldo Carvalho de Melo 466258e4bfcSWang Nan static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, 467258e4bfcSWang Nan void *arg __maybe_unused) 468e4b356b5SArnaldo Carvalho de Melo { 4694876075bSWang Nan struct perf_mmap *map = fda->priv[fd].ptr; 470e4b356b5SArnaldo Carvalho de Melo 4714876075bSWang Nan if (map) 4724876075bSWang Nan perf_mmap__put(map); 47370082dd9SArnaldo Carvalho de Melo } 47470db7533SArnaldo Carvalho de Melo 47563503dbaSJiri Olsa int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) 4761ddec7f0SArnaldo Carvalho de Melo { 477e4b356b5SArnaldo Carvalho de Melo return fdarray__filter(&evlist->pollfd, revents_and_mask, 478258e4bfcSWang Nan perf_evlist__munmap_filtered, NULL); 4791ddec7f0SArnaldo Carvalho de Melo } 4801ddec7f0SArnaldo Carvalho de Melo 48163503dbaSJiri Olsa int perf_evlist__poll(struct evlist *evlist, int timeout) 482f66a889dSArnaldo Carvalho de Melo { 4831b85337dSArnaldo Carvalho de Melo return fdarray__poll(&evlist->pollfd, timeout); 484f66a889dSArnaldo Carvalho de Melo } 485f66a889dSArnaldo Carvalho de Melo 48663503dbaSJiri Olsa static void perf_evlist__id_hash(struct evlist *evlist, 48732dcd021SJiri Olsa struct evsel *evsel, 4883d3b5e95SArnaldo Carvalho de Melo int cpu, int thread, u64 id) 4893d3b5e95SArnaldo Carvalho de Melo { 4903d3b5e95SArnaldo Carvalho de Melo int hash; 4913d3b5e95SArnaldo Carvalho de Melo struct perf_sample_id *sid = SID(evsel, cpu, thread); 4923d3b5e95SArnaldo Carvalho de Melo 4933d3b5e95SArnaldo Carvalho de Melo sid->id = id; 4943d3b5e95SArnaldo Carvalho de Melo sid->evsel = evsel; 4953d3b5e95SArnaldo Carvalho de Melo hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); 4963d3b5e95SArnaldo Carvalho de Melo hlist_add_head(&sid->node, &evlist->heads[hash]); 4973d3b5e95SArnaldo Carvalho de Melo } 4983d3b5e95SArnaldo Carvalho de Melo 49963503dbaSJiri Olsa void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, 500a91e5431SArnaldo Carvalho de Melo int cpu, int thread, u64 id) 501a91e5431SArnaldo Carvalho de Melo { 502a91e5431SArnaldo Carvalho de Melo perf_evlist__id_hash(evlist, evsel, cpu, thread, id); 503a91e5431SArnaldo Carvalho de Melo evsel->id[evsel->ids++] = id; 504a91e5431SArnaldo Carvalho de Melo } 505a91e5431SArnaldo Carvalho de Melo 50663503dbaSJiri Olsa int perf_evlist__id_add_fd(struct evlist *evlist, 50732dcd021SJiri Olsa struct evsel *evsel, 508f8a95309SArnaldo Carvalho de Melo int cpu, int thread, int fd) 509f8a95309SArnaldo Carvalho de Melo { 510f8a95309SArnaldo Carvalho de Melo u64 read_data[4] = { 0, }; 5113d3b5e95SArnaldo Carvalho de Melo int id_idx = 1; /* The first entry is the counter value */ 512e2b5abe0SJiri Olsa u64 id; 513e2b5abe0SJiri Olsa int ret; 514e2b5abe0SJiri Olsa 515e2b5abe0SJiri Olsa ret = ioctl(fd, PERF_EVENT_IOC_ID, &id); 516e2b5abe0SJiri Olsa if (!ret) 517e2b5abe0SJiri Olsa goto add; 518e2b5abe0SJiri Olsa 519e2b5abe0SJiri Olsa if (errno != ENOTTY) 520e2b5abe0SJiri Olsa return -1; 521e2b5abe0SJiri Olsa 522e2b5abe0SJiri Olsa /* Legacy way to get event id.. All hail to old kernels! */ 523f8a95309SArnaldo Carvalho de Melo 524c4861afeSJiri Olsa /* 525c4861afeSJiri Olsa * This way does not work with group format read, so bail 526c4861afeSJiri Olsa * out in that case. 527c4861afeSJiri Olsa */ 528c4861afeSJiri Olsa if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) 529c4861afeSJiri Olsa return -1; 530c4861afeSJiri Olsa 531f8a95309SArnaldo Carvalho de Melo if (!(evsel->attr.read_format & PERF_FORMAT_ID) || 532f8a95309SArnaldo Carvalho de Melo read(fd, &read_data, sizeof(read_data)) == -1) 533f8a95309SArnaldo Carvalho de Melo return -1; 534f8a95309SArnaldo Carvalho de Melo 535f8a95309SArnaldo Carvalho de Melo if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 536f8a95309SArnaldo Carvalho de Melo ++id_idx; 537f8a95309SArnaldo Carvalho de Melo if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 538f8a95309SArnaldo Carvalho de Melo ++id_idx; 539f8a95309SArnaldo Carvalho de Melo 540e2b5abe0SJiri Olsa id = read_data[id_idx]; 541e2b5abe0SJiri Olsa 542e2b5abe0SJiri Olsa add: 543e2b5abe0SJiri Olsa perf_evlist__id_add(evlist, evsel, cpu, thread, id); 544f8a95309SArnaldo Carvalho de Melo return 0; 545f8a95309SArnaldo Carvalho de Melo } 546f8a95309SArnaldo Carvalho de Melo 54763503dbaSJiri Olsa static void perf_evlist__set_sid_idx(struct evlist *evlist, 54832dcd021SJiri Olsa struct evsel *evsel, int idx, int cpu, 5493c659eedSAdrian Hunter int thread) 5503c659eedSAdrian Hunter { 5513c659eedSAdrian Hunter struct perf_sample_id *sid = SID(evsel, cpu, thread); 5523c659eedSAdrian Hunter sid->idx = idx; 5533c659eedSAdrian Hunter if (evlist->cpus && cpu >= 0) 5543c659eedSAdrian Hunter sid->cpu = evlist->cpus->map[cpu]; 5553c659eedSAdrian Hunter else 5563c659eedSAdrian Hunter sid->cpu = -1; 5573c659eedSAdrian Hunter if (!evsel->system_wide && evlist->threads && thread >= 0) 558e13798c7SJiri Olsa sid->tid = thread_map__pid(evlist->threads, thread); 5593c659eedSAdrian Hunter else 5603c659eedSAdrian Hunter sid->tid = -1; 5613c659eedSAdrian Hunter } 5623c659eedSAdrian Hunter 56363503dbaSJiri Olsa struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id) 56470db7533SArnaldo Carvalho de Melo { 56570db7533SArnaldo Carvalho de Melo struct hlist_head *head; 56670db7533SArnaldo Carvalho de Melo struct perf_sample_id *sid; 56770db7533SArnaldo Carvalho de Melo int hash; 56870db7533SArnaldo Carvalho de Melo 56970db7533SArnaldo Carvalho de Melo hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 57070db7533SArnaldo Carvalho de Melo head = &evlist->heads[hash]; 57170db7533SArnaldo Carvalho de Melo 572b67bfe0dSSasha Levin hlist_for_each_entry(sid, head, node) 57370db7533SArnaldo Carvalho de Melo if (sid->id == id) 574932a3594SJiri Olsa return sid; 575932a3594SJiri Olsa 576932a3594SJiri Olsa return NULL; 577932a3594SJiri Olsa } 578932a3594SJiri Olsa 57963503dbaSJiri Olsa struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) 580932a3594SJiri Olsa { 581932a3594SJiri Olsa struct perf_sample_id *sid; 582932a3594SJiri Olsa 58305169df5SAdrian Hunter if (evlist->nr_entries == 1 || !id) 584932a3594SJiri Olsa return perf_evlist__first(evlist); 585932a3594SJiri Olsa 586932a3594SJiri Olsa sid = perf_evlist__id2sid(evlist, id); 587932a3594SJiri Olsa if (sid) 58870db7533SArnaldo Carvalho de Melo return sid->evsel; 58930e68bccSNamhyung Kim 59030e68bccSNamhyung Kim if (!perf_evlist__sample_id_all(evlist)) 5910c21f736SArnaldo Carvalho de Melo return perf_evlist__first(evlist); 59230e68bccSNamhyung Kim 59370db7533SArnaldo Carvalho de Melo return NULL; 59470db7533SArnaldo Carvalho de Melo } 59504391debSArnaldo Carvalho de Melo 59663503dbaSJiri Olsa struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, 597dddcf6abSAdrian Hunter u64 id) 598dddcf6abSAdrian Hunter { 599dddcf6abSAdrian Hunter struct perf_sample_id *sid; 600dddcf6abSAdrian Hunter 601dddcf6abSAdrian Hunter if (!id) 602dddcf6abSAdrian Hunter return NULL; 603dddcf6abSAdrian Hunter 604dddcf6abSAdrian Hunter sid = perf_evlist__id2sid(evlist, id); 605dddcf6abSAdrian Hunter if (sid) 606dddcf6abSAdrian Hunter return sid->evsel; 607dddcf6abSAdrian Hunter 608dddcf6abSAdrian Hunter return NULL; 609dddcf6abSAdrian Hunter } 610dddcf6abSAdrian Hunter 61163503dbaSJiri Olsa static int perf_evlist__event2id(struct evlist *evlist, 61275562573SAdrian Hunter union perf_event *event, u64 *id) 61375562573SAdrian Hunter { 61475562573SAdrian Hunter const u64 *array = event->sample.array; 61575562573SAdrian Hunter ssize_t n; 61675562573SAdrian Hunter 61775562573SAdrian Hunter n = (event->header.size - sizeof(event->header)) >> 3; 61875562573SAdrian Hunter 61975562573SAdrian Hunter if (event->header.type == PERF_RECORD_SAMPLE) { 62075562573SAdrian Hunter if (evlist->id_pos >= n) 62175562573SAdrian Hunter return -1; 62275562573SAdrian Hunter *id = array[evlist->id_pos]; 62375562573SAdrian Hunter } else { 62475562573SAdrian Hunter if (evlist->is_pos > n) 62575562573SAdrian Hunter return -1; 62675562573SAdrian Hunter n -= evlist->is_pos; 62775562573SAdrian Hunter *id = array[n]; 62875562573SAdrian Hunter } 62975562573SAdrian Hunter return 0; 63075562573SAdrian Hunter } 63175562573SAdrian Hunter 63263503dbaSJiri Olsa struct evsel *perf_evlist__event2evsel(struct evlist *evlist, 63375562573SAdrian Hunter union perf_event *event) 63475562573SAdrian Hunter { 63532dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 63675562573SAdrian Hunter struct hlist_head *head; 63775562573SAdrian Hunter struct perf_sample_id *sid; 63875562573SAdrian Hunter int hash; 63975562573SAdrian Hunter u64 id; 64075562573SAdrian Hunter 64175562573SAdrian Hunter if (evlist->nr_entries == 1) 64298be6966SAdrian Hunter return first; 64398be6966SAdrian Hunter 64498be6966SAdrian Hunter if (!first->attr.sample_id_all && 64598be6966SAdrian Hunter event->header.type != PERF_RECORD_SAMPLE) 64698be6966SAdrian Hunter return first; 64775562573SAdrian Hunter 64875562573SAdrian Hunter if (perf_evlist__event2id(evlist, event, &id)) 64975562573SAdrian Hunter return NULL; 65075562573SAdrian Hunter 65175562573SAdrian Hunter /* Synthesized events have an id of zero */ 65275562573SAdrian Hunter if (!id) 65398be6966SAdrian Hunter return first; 65475562573SAdrian Hunter 65575562573SAdrian Hunter hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 65675562573SAdrian Hunter head = &evlist->heads[hash]; 65775562573SAdrian Hunter 65875562573SAdrian Hunter hlist_for_each_entry(sid, head, node) { 65975562573SAdrian Hunter if (sid->id == id) 66075562573SAdrian Hunter return sid->evsel; 66175562573SAdrian Hunter } 66275562573SAdrian Hunter return NULL; 66375562573SAdrian Hunter } 66475562573SAdrian Hunter 66563503dbaSJiri Olsa static int perf_evlist__set_paused(struct evlist *evlist, bool value) 66665aea233SWang Nan { 66765aea233SWang Nan int i; 66865aea233SWang Nan 6690b72d69aSWang Nan if (!evlist->overwrite_mmap) 670078c3386SWang Nan return 0; 671078c3386SWang Nan 67265aea233SWang Nan for (i = 0; i < evlist->nr_mmaps; i++) { 6730b72d69aSWang Nan int fd = evlist->overwrite_mmap[i].fd; 67465aea233SWang Nan int err; 67565aea233SWang Nan 67665aea233SWang Nan if (fd < 0) 67765aea233SWang Nan continue; 67865aea233SWang Nan err = ioctl(fd, PERF_EVENT_IOC_PAUSE_OUTPUT, value ? 1 : 0); 67965aea233SWang Nan if (err) 68065aea233SWang Nan return err; 68165aea233SWang Nan } 68265aea233SWang Nan return 0; 68365aea233SWang Nan } 68465aea233SWang Nan 68563503dbaSJiri Olsa static int perf_evlist__pause(struct evlist *evlist) 68665aea233SWang Nan { 68765aea233SWang Nan return perf_evlist__set_paused(evlist, true); 68865aea233SWang Nan } 68965aea233SWang Nan 69063503dbaSJiri Olsa static int perf_evlist__resume(struct evlist *evlist) 69165aea233SWang Nan { 69265aea233SWang Nan return perf_evlist__set_paused(evlist, false); 69365aea233SWang Nan } 69465aea233SWang Nan 69563503dbaSJiri Olsa static void perf_evlist__munmap_nofree(struct evlist *evlist) 696f8a95309SArnaldo Carvalho de Melo { 697aece948fSArnaldo Carvalho de Melo int i; 698f8a95309SArnaldo Carvalho de Melo 699b2cb615dSWang Nan if (evlist->mmap) 70093edcbd9SAdrian Hunter for (i = 0; i < evlist->nr_mmaps; i++) 701a1f72618SWang Nan perf_mmap__munmap(&evlist->mmap[i]); 702b2cb615dSWang Nan 7030b72d69aSWang Nan if (evlist->overwrite_mmap) 704b2cb615dSWang Nan for (i = 0; i < evlist->nr_mmaps; i++) 7050b72d69aSWang Nan perf_mmap__munmap(&evlist->overwrite_mmap[i]); 706a1f72618SWang Nan } 707aece948fSArnaldo Carvalho de Melo 70863503dbaSJiri Olsa void perf_evlist__munmap(struct evlist *evlist) 709a1f72618SWang Nan { 710a1f72618SWang Nan perf_evlist__munmap_nofree(evlist); 71104662523SArnaldo Carvalho de Melo zfree(&evlist->mmap); 7120b72d69aSWang Nan zfree(&evlist->overwrite_mmap); 713f8a95309SArnaldo Carvalho de Melo } 714f8a95309SArnaldo Carvalho de Melo 71563503dbaSJiri Olsa static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, 7162c5f6d87SKan Liang bool overwrite) 717f8a95309SArnaldo Carvalho de Melo { 718d4c6fb36SWang Nan int i; 7198db6d6b1SWang Nan struct perf_mmap *map; 720d4c6fb36SWang Nan 721a14bb7a6SArnaldo Carvalho de Melo evlist->nr_mmaps = cpu_map__nr(evlist->cpus); 722ec1e7e43SSukadev Bhattiprolu if (cpu_map__empty(evlist->cpus)) 723b3a319d5SNamhyung Kim evlist->nr_mmaps = thread_map__nr(evlist->threads); 7248db6d6b1SWang Nan map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 7258db6d6b1SWang Nan if (!map) 7268db6d6b1SWang Nan return NULL; 727946ae1d4SWang Nan 7284738ca30SArnaldo Carvalho de Melo for (i = 0; i < evlist->nr_mmaps; i++) { 7298db6d6b1SWang Nan map[i].fd = -1; 7302c5f6d87SKan Liang map[i].overwrite = overwrite; 7314738ca30SArnaldo Carvalho de Melo /* 7324738ca30SArnaldo Carvalho de Melo * When the perf_mmap() call is made we grab one refcount, plus 7336afad54dSKan Liang * one extra to let perf_mmap__consume() get the last 7344738ca30SArnaldo Carvalho de Melo * events after all real references (perf_mmap__get()) are 7354738ca30SArnaldo Carvalho de Melo * dropped. 7364738ca30SArnaldo Carvalho de Melo * 7374738ca30SArnaldo Carvalho de Melo * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and 7384738ca30SArnaldo Carvalho de Melo * thus does perf_mmap__get() on it. 7394738ca30SArnaldo Carvalho de Melo */ 7404738ca30SArnaldo Carvalho de Melo refcount_set(&map[i].refcnt, 0); 7414738ca30SArnaldo Carvalho de Melo } 7428db6d6b1SWang Nan return map; 743f8a95309SArnaldo Carvalho de Melo } 744f8a95309SArnaldo Carvalho de Melo 745f3058a1cSWang Nan static bool 74663503dbaSJiri Olsa perf_evlist__should_poll(struct evlist *evlist __maybe_unused, 74732dcd021SJiri Olsa struct evsel *evsel) 748f3058a1cSWang Nan { 74932a951b4SArnaldo Carvalho de Melo if (evsel->attr.write_backward) 750f3058a1cSWang Nan return false; 751f3058a1cSWang Nan return true; 752f3058a1cSWang Nan } 753f3058a1cSWang Nan 75463503dbaSJiri Olsa static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, 7559f21b815SMark Rutland struct mmap_params *mp, int cpu_idx, 7560b72d69aSWang Nan int thread, int *_output, int *_output_overwrite) 757aece948fSArnaldo Carvalho de Melo { 75832dcd021SJiri Olsa struct evsel *evsel; 759f3058a1cSWang Nan int revent; 7609f21b815SMark Rutland int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); 76104e21314SAdrian Hunter 762e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 763078c3386SWang Nan struct perf_mmap *maps = evlist->mmap; 764078c3386SWang Nan int *output = _output; 765bf8e8f4bSAdrian Hunter int fd; 7669f21b815SMark Rutland int cpu; 767bf8e8f4bSAdrian Hunter 76871f566a3SWang Nan mp->prot = PROT_READ | PROT_WRITE; 769078c3386SWang Nan if (evsel->attr.write_backward) { 7700b72d69aSWang Nan output = _output_overwrite; 7710b72d69aSWang Nan maps = evlist->overwrite_mmap; 772078c3386SWang Nan 773078c3386SWang Nan if (!maps) { 7742c5f6d87SKan Liang maps = perf_evlist__alloc_mmap(evlist, true); 775078c3386SWang Nan if (!maps) 776078c3386SWang Nan return -1; 7770b72d69aSWang Nan evlist->overwrite_mmap = maps; 77854cc54deSWang Nan if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY) 77954cc54deSWang Nan perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); 780078c3386SWang Nan } 78171f566a3SWang Nan mp->prot &= ~PROT_WRITE; 782078c3386SWang Nan } 783f3058a1cSWang Nan 784bf8e8f4bSAdrian Hunter if (evsel->system_wide && thread) 785bf8e8f4bSAdrian Hunter continue; 786bf8e8f4bSAdrian Hunter 7879f21b815SMark Rutland cpu = cpu_map__idx(evsel->cpus, evlist_cpu); 7889f21b815SMark Rutland if (cpu == -1) 7899f21b815SMark Rutland continue; 7909f21b815SMark Rutland 791bf8e8f4bSAdrian Hunter fd = FD(evsel, cpu, thread); 79204e21314SAdrian Hunter 79304e21314SAdrian Hunter if (*output == -1) { 79404e21314SAdrian Hunter *output = fd; 795078c3386SWang Nan 79631fb4c0dSJiri Olsa if (perf_mmap__mmap(&maps[idx], mp, *output, evlist_cpu) < 0) 79704e21314SAdrian Hunter return -1; 79804e21314SAdrian Hunter } else { 79904e21314SAdrian Hunter if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) 80004e21314SAdrian Hunter return -1; 80182396986SArnaldo Carvalho de Melo 802078c3386SWang Nan perf_mmap__get(&maps[idx]); 80304e21314SAdrian Hunter } 80404e21314SAdrian Hunter 805f3058a1cSWang Nan revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0; 806f3058a1cSWang Nan 807f90d194aSAdrian Hunter /* 808f90d194aSAdrian Hunter * The system_wide flag causes a selected event to be opened 809f90d194aSAdrian Hunter * always without a pid. Consequently it will never get a 810f90d194aSAdrian Hunter * POLLHUP, but it is used for tracking in combination with 811f90d194aSAdrian Hunter * other events, so it should not need to be polled anyway. 812f90d194aSAdrian Hunter * Therefore don't add it for polling. 813f90d194aSAdrian Hunter */ 814f90d194aSAdrian Hunter if (!evsel->system_wide && 815078c3386SWang Nan __perf_evlist__add_pollfd(evlist, fd, &maps[idx], revent) < 0) { 816078c3386SWang Nan perf_mmap__put(&maps[idx]); 817ad6765ddSArnaldo Carvalho de Melo return -1; 81882396986SArnaldo Carvalho de Melo } 819033fa713SArnaldo Carvalho de Melo 8203c659eedSAdrian Hunter if (evsel->attr.read_format & PERF_FORMAT_ID) { 8213c659eedSAdrian Hunter if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, 8223c659eedSAdrian Hunter fd) < 0) 82304e21314SAdrian Hunter return -1; 8243c659eedSAdrian Hunter perf_evlist__set_sid_idx(evlist, evsel, idx, cpu, 8253c659eedSAdrian Hunter thread); 8263c659eedSAdrian Hunter } 82704e21314SAdrian Hunter } 82804e21314SAdrian Hunter 82904e21314SAdrian Hunter return 0; 83004e21314SAdrian Hunter } 83104e21314SAdrian Hunter 83263503dbaSJiri Olsa static int perf_evlist__mmap_per_cpu(struct evlist *evlist, 833a8a8f3ebSAdrian Hunter struct mmap_params *mp) 83404e21314SAdrian Hunter { 835aece948fSArnaldo Carvalho de Melo int cpu, thread; 836b3a319d5SNamhyung Kim int nr_cpus = cpu_map__nr(evlist->cpus); 837b3a319d5SNamhyung Kim int nr_threads = thread_map__nr(evlist->threads); 838aece948fSArnaldo Carvalho de Melo 839e3e1a54fSAdrian Hunter pr_debug2("perf event ring buffer mmapped per cpu\n"); 840b3a319d5SNamhyung Kim for (cpu = 0; cpu < nr_cpus; cpu++) { 841aece948fSArnaldo Carvalho de Melo int output = -1; 8420b72d69aSWang Nan int output_overwrite = -1; 843aece948fSArnaldo Carvalho de Melo 844718c602dSAdrian Hunter auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, cpu, 845718c602dSAdrian Hunter true); 846718c602dSAdrian Hunter 847b3a319d5SNamhyung Kim for (thread = 0; thread < nr_threads; thread++) { 848a8a8f3ebSAdrian Hunter if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu, 8490b72d69aSWang Nan thread, &output, &output_overwrite)) 850aece948fSArnaldo Carvalho de Melo goto out_unmap; 851aece948fSArnaldo Carvalho de Melo } 852aece948fSArnaldo Carvalho de Melo } 853aece948fSArnaldo Carvalho de Melo 854aece948fSArnaldo Carvalho de Melo return 0; 855aece948fSArnaldo Carvalho de Melo 856aece948fSArnaldo Carvalho de Melo out_unmap: 857a1f72618SWang Nan perf_evlist__munmap_nofree(evlist); 858aece948fSArnaldo Carvalho de Melo return -1; 859aece948fSArnaldo Carvalho de Melo } 860aece948fSArnaldo Carvalho de Melo 86163503dbaSJiri Olsa static int perf_evlist__mmap_per_thread(struct evlist *evlist, 862a8a8f3ebSAdrian Hunter struct mmap_params *mp) 863aece948fSArnaldo Carvalho de Melo { 864aece948fSArnaldo Carvalho de Melo int thread; 865b3a319d5SNamhyung Kim int nr_threads = thread_map__nr(evlist->threads); 866aece948fSArnaldo Carvalho de Melo 867e3e1a54fSAdrian Hunter pr_debug2("perf event ring buffer mmapped per thread\n"); 868b3a319d5SNamhyung Kim for (thread = 0; thread < nr_threads; thread++) { 869aece948fSArnaldo Carvalho de Melo int output = -1; 8700b72d69aSWang Nan int output_overwrite = -1; 871aece948fSArnaldo Carvalho de Melo 872718c602dSAdrian Hunter auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, thread, 873718c602dSAdrian Hunter false); 874718c602dSAdrian Hunter 875a8a8f3ebSAdrian Hunter if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread, 8760b72d69aSWang Nan &output, &output_overwrite)) 877aece948fSArnaldo Carvalho de Melo goto out_unmap; 878aece948fSArnaldo Carvalho de Melo } 879aece948fSArnaldo Carvalho de Melo 880aece948fSArnaldo Carvalho de Melo return 0; 881aece948fSArnaldo Carvalho de Melo 882aece948fSArnaldo Carvalho de Melo out_unmap: 883a1f72618SWang Nan perf_evlist__munmap_nofree(evlist); 884aece948fSArnaldo Carvalho de Melo return -1; 885aece948fSArnaldo Carvalho de Melo } 886aece948fSArnaldo Carvalho de Melo 887f5e7150cSArnaldo Carvalho de Melo unsigned long perf_event_mlock_kb_in_pages(void) 888994a1f78SJiri Olsa { 889f5e7150cSArnaldo Carvalho de Melo unsigned long pages; 8908185e881SArnaldo Carvalho de Melo int max; 8918185e881SArnaldo Carvalho de Melo 8928185e881SArnaldo Carvalho de Melo if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { 8938185e881SArnaldo Carvalho de Melo /* 8948185e881SArnaldo Carvalho de Melo * Pick a once upon a time good value, i.e. things look 8958185e881SArnaldo Carvalho de Melo * strange since we can't read a sysctl value, but lets not 8968185e881SArnaldo Carvalho de Melo * die yet... 8978185e881SArnaldo Carvalho de Melo */ 8988185e881SArnaldo Carvalho de Melo max = 512; 8998185e881SArnaldo Carvalho de Melo } else { 9008185e881SArnaldo Carvalho de Melo max -= (page_size / 1024); 9018185e881SArnaldo Carvalho de Melo } 9028185e881SArnaldo Carvalho de Melo 9038185e881SArnaldo Carvalho de Melo pages = (max * 1024) / page_size; 9041be300f4SArnaldo Carvalho de Melo if (!is_power_of_2(pages)) 9051be300f4SArnaldo Carvalho de Melo pages = rounddown_pow_of_two(pages); 906f5e7150cSArnaldo Carvalho de Melo 907f5e7150cSArnaldo Carvalho de Melo return pages; 908f5e7150cSArnaldo Carvalho de Melo } 909f5e7150cSArnaldo Carvalho de Melo 9100c582449SJiri Olsa size_t perf_evlist__mmap_size(unsigned long pages) 911f5e7150cSArnaldo Carvalho de Melo { 912f5e7150cSArnaldo Carvalho de Melo if (pages == UINT_MAX) 913f5e7150cSArnaldo Carvalho de Melo pages = perf_event_mlock_kb_in_pages(); 914f5e7150cSArnaldo Carvalho de Melo else if (!is_power_of_2(pages)) 915994a1f78SJiri Olsa return 0; 916994a1f78SJiri Olsa 917994a1f78SJiri Olsa return (pages + 1) * page_size; 918994a1f78SJiri Olsa } 919994a1f78SJiri Olsa 92033c2dcfdSDavid Ahern static long parse_pages_arg(const char *str, unsigned long min, 92133c2dcfdSDavid Ahern unsigned long max) 922994a1f78SJiri Olsa { 9232fbe4abeSAdrian Hunter unsigned long pages, val; 92427050f53SJiri Olsa static struct parse_tag tags[] = { 92527050f53SJiri Olsa { .tag = 'B', .mult = 1 }, 92627050f53SJiri Olsa { .tag = 'K', .mult = 1 << 10 }, 92727050f53SJiri Olsa { .tag = 'M', .mult = 1 << 20 }, 92827050f53SJiri Olsa { .tag = 'G', .mult = 1 << 30 }, 92927050f53SJiri Olsa { .tag = 0 }, 93027050f53SJiri Olsa }; 931994a1f78SJiri Olsa 9328973504bSDavid Ahern if (str == NULL) 93333c2dcfdSDavid Ahern return -EINVAL; 9348973504bSDavid Ahern 93527050f53SJiri Olsa val = parse_tag_value(str, tags); 9362fbe4abeSAdrian Hunter if (val != (unsigned long) -1) { 93727050f53SJiri Olsa /* we got file size value */ 93827050f53SJiri Olsa pages = PERF_ALIGN(val, page_size) / page_size; 93927050f53SJiri Olsa } else { 94027050f53SJiri Olsa /* we got pages count value */ 94127050f53SJiri Olsa char *eptr; 942994a1f78SJiri Olsa pages = strtoul(str, &eptr, 10); 94333c2dcfdSDavid Ahern if (*eptr != '\0') 94433c2dcfdSDavid Ahern return -EINVAL; 94527050f53SJiri Olsa } 946994a1f78SJiri Olsa 9472bcab6c1SAdrian Hunter if (pages == 0 && min == 0) { 94833c2dcfdSDavid Ahern /* leave number of pages at 0 */ 9491dbfa938SAdrian Hunter } else if (!is_power_of_2(pages)) { 9509808143bSJiri Olsa char buf[100]; 9519808143bSJiri Olsa 95233c2dcfdSDavid Ahern /* round pages up to next power of 2 */ 95391529834SArnaldo Carvalho de Melo pages = roundup_pow_of_two(pages); 9541dbfa938SAdrian Hunter if (!pages) 9551dbfa938SAdrian Hunter return -EINVAL; 9569808143bSJiri Olsa 9579808143bSJiri Olsa unit_number__scnprintf(buf, sizeof(buf), pages * page_size); 9589808143bSJiri Olsa pr_info("rounding mmap pages size to %s (%lu pages)\n", 9599808143bSJiri Olsa buf, pages); 9602fbe4abeSAdrian Hunter } 9612fbe4abeSAdrian Hunter 96233c2dcfdSDavid Ahern if (pages > max) 96333c2dcfdSDavid Ahern return -EINVAL; 96433c2dcfdSDavid Ahern 96533c2dcfdSDavid Ahern return pages; 96633c2dcfdSDavid Ahern } 96733c2dcfdSDavid Ahern 968e9db1310SAdrian Hunter int __perf_evlist__parse_mmap_pages(unsigned int *mmap_pages, const char *str) 96933c2dcfdSDavid Ahern { 97033c2dcfdSDavid Ahern unsigned long max = UINT_MAX; 97133c2dcfdSDavid Ahern long pages; 97233c2dcfdSDavid Ahern 973f5ae9c42SAdrian Hunter if (max > SIZE_MAX / page_size) 97433c2dcfdSDavid Ahern max = SIZE_MAX / page_size; 97533c2dcfdSDavid Ahern 97633c2dcfdSDavid Ahern pages = parse_pages_arg(str, 1, max); 97733c2dcfdSDavid Ahern if (pages < 0) { 97833c2dcfdSDavid Ahern pr_err("Invalid argument for --mmap_pages/-m\n"); 979994a1f78SJiri Olsa return -1; 980994a1f78SJiri Olsa } 981994a1f78SJiri Olsa 982994a1f78SJiri Olsa *mmap_pages = pages; 983994a1f78SJiri Olsa return 0; 984994a1f78SJiri Olsa } 985994a1f78SJiri Olsa 986e9db1310SAdrian Hunter int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, 987e9db1310SAdrian Hunter int unset __maybe_unused) 988e9db1310SAdrian Hunter { 989e9db1310SAdrian Hunter return __perf_evlist__parse_mmap_pages(opt->value, str); 990e9db1310SAdrian Hunter } 991e9db1310SAdrian Hunter 992c83fa7f2SAdrian Hunter /** 993718c602dSAdrian Hunter * perf_evlist__mmap_ex - Create mmaps to receive events. 994c83fa7f2SAdrian Hunter * @evlist: list of events 995c83fa7f2SAdrian Hunter * @pages: map length in pages 996c83fa7f2SAdrian Hunter * @overwrite: overwrite older events? 997718c602dSAdrian Hunter * @auxtrace_pages - auxtrace map length in pages 998718c602dSAdrian Hunter * @auxtrace_overwrite - overwrite older auxtrace data? 999f8a95309SArnaldo Carvalho de Melo * 1000c83fa7f2SAdrian Hunter * If @overwrite is %false the user needs to signal event consumption using 1001c83fa7f2SAdrian Hunter * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this 1002c83fa7f2SAdrian Hunter * automatically. 1003f8a95309SArnaldo Carvalho de Melo * 1004718c602dSAdrian Hunter * Similarly, if @auxtrace_overwrite is %false the user needs to signal data 1005718c602dSAdrian Hunter * consumption using auxtrace_mmap__write_tail(). 1006718c602dSAdrian Hunter * 1007c83fa7f2SAdrian Hunter * Return: %0 on success, negative error code otherwise. 1008f8a95309SArnaldo Carvalho de Melo */ 100963503dbaSJiri Olsa int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, 10107a276ff6SWang Nan unsigned int auxtrace_pages, 101151255a8aSAlexey Budankov bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, 101251255a8aSAlexey Budankov int comp_level) 1013f8a95309SArnaldo Carvalho de Melo { 101432dcd021SJiri Olsa struct evsel *evsel; 1015f854839bSJiri Olsa const struct perf_cpu_map *cpus = evlist->cpus; 10169749b90eSJiri Olsa const struct perf_thread_map *threads = evlist->threads; 101771f566a3SWang Nan /* 101871f566a3SWang Nan * Delay setting mp.prot: set it before calling perf_mmap__mmap. 101971f566a3SWang Nan * Its value is decided by evsel's write_backward. 102071f566a3SWang Nan * So &mp should not be passed through const pointer. 102171f566a3SWang Nan */ 102251255a8aSAlexey Budankov struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity, .flush = flush, 102351255a8aSAlexey Budankov .comp_level = comp_level }; 102450a682ceSArnaldo Carvalho de Melo 10258db6d6b1SWang Nan if (!evlist->mmap) 10262c5f6d87SKan Liang evlist->mmap = perf_evlist__alloc_mmap(evlist, false); 10278db6d6b1SWang Nan if (!evlist->mmap) 1028f8a95309SArnaldo Carvalho de Melo return -ENOMEM; 1029f8a95309SArnaldo Carvalho de Melo 10301b85337dSArnaldo Carvalho de Melo if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 1031f8a95309SArnaldo Carvalho de Melo return -ENOMEM; 1032f8a95309SArnaldo Carvalho de Melo 1033994a1f78SJiri Olsa evlist->mmap_len = perf_evlist__mmap_size(pages); 10342af68ef5SAdrian Hunter pr_debug("mmap size %zuB\n", evlist->mmap_len); 1035a8a8f3ebSAdrian Hunter mp.mask = evlist->mmap_len - page_size - 1; 1036f8a95309SArnaldo Carvalho de Melo 1037718c602dSAdrian Hunter auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len, 1038718c602dSAdrian Hunter auxtrace_pages, auxtrace_overwrite); 1039718c602dSAdrian Hunter 1040e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 1041f8a95309SArnaldo Carvalho de Melo if ((evsel->attr.read_format & PERF_FORMAT_ID) && 1042a91e5431SArnaldo Carvalho de Melo evsel->sample_id == NULL && 1043a14bb7a6SArnaldo Carvalho de Melo perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) 1044f8a95309SArnaldo Carvalho de Melo return -ENOMEM; 1045f8a95309SArnaldo Carvalho de Melo } 1046f8a95309SArnaldo Carvalho de Melo 1047ec1e7e43SSukadev Bhattiprolu if (cpu_map__empty(cpus)) 1048a8a8f3ebSAdrian Hunter return perf_evlist__mmap_per_thread(evlist, &mp); 1049f8a95309SArnaldo Carvalho de Melo 1050a8a8f3ebSAdrian Hunter return perf_evlist__mmap_per_cpu(evlist, &mp); 1051f8a95309SArnaldo Carvalho de Melo } 10527e2ed097SArnaldo Carvalho de Melo 105363503dbaSJiri Olsa int perf_evlist__mmap(struct evlist *evlist, unsigned int pages) 1054718c602dSAdrian Hunter { 105551255a8aSAlexey Budankov return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); 1056718c602dSAdrian Hunter } 1057718c602dSAdrian Hunter 105863503dbaSJiri Olsa int perf_evlist__create_maps(struct evlist *evlist, struct target *target) 10597e2ed097SArnaldo Carvalho de Melo { 1060147c508fSJin Yao bool all_threads = (target->per_thread && target->system_wide); 1061f854839bSJiri Olsa struct perf_cpu_map *cpus; 10629749b90eSJiri Olsa struct perf_thread_map *threads; 10637e2ed097SArnaldo Carvalho de Melo 1064147c508fSJin Yao /* 1065147c508fSJin Yao * If specify '-a' and '--per-thread' to perf record, perf record 1066147c508fSJin Yao * will override '--per-thread'. target->per_thread = false and 1067147c508fSJin Yao * target->system_wide = true. 1068147c508fSJin Yao * 1069147c508fSJin Yao * If specify '--per-thread' only to perf record, 1070147c508fSJin Yao * target->per_thread = true and target->system_wide = false. 1071147c508fSJin Yao * 1072147c508fSJin Yao * So target->per_thread && target->system_wide is false. 1073147c508fSJin Yao * For perf record, thread_map__new_str doesn't call 1074147c508fSJin Yao * thread_map__new_all_cpus. That will keep perf record's 1075147c508fSJin Yao * current behavior. 1076147c508fSJin Yao * 1077147c508fSJin Yao * For perf stat, it allows the case that target->per_thread and 1078147c508fSJin Yao * target->system_wide are all true. It means to collect system-wide 1079147c508fSJin Yao * per-thread data. thread_map__new_str will call 1080147c508fSJin Yao * thread_map__new_all_cpus to enumerate all threads. 1081147c508fSJin Yao */ 108273c0ca1eSJin Yao threads = thread_map__new_str(target->pid, target->tid, target->uid, 1083147c508fSJin Yao all_threads); 108474bfd2b2SAdrian Hunter 108574bfd2b2SAdrian Hunter if (!threads) 10867e2ed097SArnaldo Carvalho de Melo return -1; 10877e2ed097SArnaldo Carvalho de Melo 10889c105fbcSDongsheng Yang if (target__uses_dummy_map(target)) 1089397721e0SJiri Olsa cpus = perf_cpu_map__dummy_new(); 1090879d77d0SNamhyung Kim else 109174bfd2b2SAdrian Hunter cpus = cpu_map__new(target->cpu_list); 10927e2ed097SArnaldo Carvalho de Melo 109374bfd2b2SAdrian Hunter if (!cpus) 10947e2ed097SArnaldo Carvalho de Melo goto out_delete_threads; 10957e2ed097SArnaldo Carvalho de Melo 1096ec9a77a7SAdrian Hunter evlist->has_user_cpus = !!target->cpu_list; 1097ec9a77a7SAdrian Hunter 109874bfd2b2SAdrian Hunter perf_evlist__set_maps(evlist, cpus, threads); 1099d5bc056eSAdrian Hunter 1100d5bc056eSAdrian Hunter return 0; 11017e2ed097SArnaldo Carvalho de Melo 11027e2ed097SArnaldo Carvalho de Melo out_delete_threads: 11037836e52eSJiri Olsa perf_thread_map__put(threads); 11047e2ed097SArnaldo Carvalho de Melo return -1; 11057e2ed097SArnaldo Carvalho de Melo } 11067e2ed097SArnaldo Carvalho de Melo 110763503dbaSJiri Olsa void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, 11089749b90eSJiri Olsa struct perf_thread_map *threads) 11093de5cfb0SJiri Olsa { 1110934e0f20SAdrian Hunter /* 1111934e0f20SAdrian Hunter * Allow for the possibility that one or another of the maps isn't being 1112934e0f20SAdrian Hunter * changed i.e. don't put it. Note we are assuming the maps that are 1113934e0f20SAdrian Hunter * being applied are brand new and evlist is taking ownership of the 1114934e0f20SAdrian Hunter * original reference count of 1. If that is not the case it is up to 1115934e0f20SAdrian Hunter * the caller to increase the reference count. 1116934e0f20SAdrian Hunter */ 1117934e0f20SAdrian Hunter if (cpus != evlist->cpus) { 111838f01d8dSJiri Olsa perf_cpu_map__put(evlist->cpus); 111938f01d8dSJiri Olsa evlist->cpus = perf_cpu_map__get(cpus); 1120934e0f20SAdrian Hunter } 11213de5cfb0SJiri Olsa 1122934e0f20SAdrian Hunter if (threads != evlist->threads) { 11237836e52eSJiri Olsa perf_thread_map__put(evlist->threads); 11247836e52eSJiri Olsa evlist->threads = perf_thread_map__get(threads); 1125934e0f20SAdrian Hunter } 11263de5cfb0SJiri Olsa 1127ec9a77a7SAdrian Hunter perf_evlist__propagate_maps(evlist); 11283de5cfb0SJiri Olsa } 11293de5cfb0SJiri Olsa 113063503dbaSJiri Olsa void __perf_evlist__set_sample_bit(struct evlist *evlist, 113122c8a376SArnaldo Carvalho de Melo enum perf_event_sample_format bit) 113222c8a376SArnaldo Carvalho de Melo { 113332dcd021SJiri Olsa struct evsel *evsel; 113422c8a376SArnaldo Carvalho de Melo 1135e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 113622c8a376SArnaldo Carvalho de Melo __perf_evsel__set_sample_bit(evsel, bit); 113722c8a376SArnaldo Carvalho de Melo } 113822c8a376SArnaldo Carvalho de Melo 113963503dbaSJiri Olsa void __perf_evlist__reset_sample_bit(struct evlist *evlist, 114022c8a376SArnaldo Carvalho de Melo enum perf_event_sample_format bit) 114122c8a376SArnaldo Carvalho de Melo { 114232dcd021SJiri Olsa struct evsel *evsel; 114322c8a376SArnaldo Carvalho de Melo 1144e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 114522c8a376SArnaldo Carvalho de Melo __perf_evsel__reset_sample_bit(evsel, bit); 114622c8a376SArnaldo Carvalho de Melo } 114722c8a376SArnaldo Carvalho de Melo 114863503dbaSJiri Olsa int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) 11490a102479SFrederic Weisbecker { 115032dcd021SJiri Olsa struct evsel *evsel; 1151745cefc5SArnaldo Carvalho de Melo int err = 0; 11520a102479SFrederic Weisbecker 1153e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 1154745cefc5SArnaldo Carvalho de Melo if (evsel->filter == NULL) 11550a102479SFrederic Weisbecker continue; 1156745cefc5SArnaldo Carvalho de Melo 1157d988d5eeSKan Liang /* 1158d988d5eeSKan Liang * filters only work for tracepoint event, which doesn't have cpu limit. 1159d988d5eeSKan Liang * So evlist and evsel should always be same. 1160d988d5eeSKan Liang */ 116124e376b2SJiri Olsa err = evsel__apply_filter(evsel, evsel->filter); 116223d4aad4SArnaldo Carvalho de Melo if (err) { 116323d4aad4SArnaldo Carvalho de Melo *err_evsel = evsel; 1164745cefc5SArnaldo Carvalho de Melo break; 11650a102479SFrederic Weisbecker } 116623d4aad4SArnaldo Carvalho de Melo } 11670a102479SFrederic Weisbecker 1168745cefc5SArnaldo Carvalho de Melo return err; 1169745cefc5SArnaldo Carvalho de Melo } 1170745cefc5SArnaldo Carvalho de Melo 117163503dbaSJiri Olsa int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter) 1172745cefc5SArnaldo Carvalho de Melo { 117332dcd021SJiri Olsa struct evsel *evsel; 1174745cefc5SArnaldo Carvalho de Melo int err = 0; 1175745cefc5SArnaldo Carvalho de Melo 1176e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 1177fdf14720SWang Nan if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 1178fdf14720SWang Nan continue; 1179fdf14720SWang Nan 118094ad89bcSArnaldo Carvalho de Melo err = perf_evsel__set_filter(evsel, filter); 1181745cefc5SArnaldo Carvalho de Melo if (err) 1182745cefc5SArnaldo Carvalho de Melo break; 1183745cefc5SArnaldo Carvalho de Melo } 1184745cefc5SArnaldo Carvalho de Melo 1185745cefc5SArnaldo Carvalho de Melo return err; 11860a102479SFrederic Weisbecker } 118774429964SFrederic Weisbecker 118863503dbaSJiri Olsa int perf_evlist__set_tp_filter_pids(struct evlist *evlist, size_t npids, pid_t *pids) 1189cfd70a26SArnaldo Carvalho de Melo { 1190cfd70a26SArnaldo Carvalho de Melo char *filter; 1191be199adaSArnaldo Carvalho de Melo int ret = -1; 1192be199adaSArnaldo Carvalho de Melo size_t i; 1193cfd70a26SArnaldo Carvalho de Melo 1194be199adaSArnaldo Carvalho de Melo for (i = 0; i < npids; ++i) { 1195be199adaSArnaldo Carvalho de Melo if (i == 0) { 1196be199adaSArnaldo Carvalho de Melo if (asprintf(&filter, "common_pid != %d", pids[i]) < 0) 1197cfd70a26SArnaldo Carvalho de Melo return -1; 1198be199adaSArnaldo Carvalho de Melo } else { 1199be199adaSArnaldo Carvalho de Melo char *tmp; 1200be199adaSArnaldo Carvalho de Melo 1201be199adaSArnaldo Carvalho de Melo if (asprintf(&tmp, "%s && common_pid != %d", filter, pids[i]) < 0) 1202be199adaSArnaldo Carvalho de Melo goto out_free; 1203be199adaSArnaldo Carvalho de Melo 1204be199adaSArnaldo Carvalho de Melo free(filter); 1205be199adaSArnaldo Carvalho de Melo filter = tmp; 1206be199adaSArnaldo Carvalho de Melo } 1207be199adaSArnaldo Carvalho de Melo } 1208cfd70a26SArnaldo Carvalho de Melo 12097ad92a33SArnaldo Carvalho de Melo ret = perf_evlist__set_tp_filter(evlist, filter); 1210be199adaSArnaldo Carvalho de Melo out_free: 1211cfd70a26SArnaldo Carvalho de Melo free(filter); 1212cfd70a26SArnaldo Carvalho de Melo return ret; 1213cfd70a26SArnaldo Carvalho de Melo } 1214cfd70a26SArnaldo Carvalho de Melo 121563503dbaSJiri Olsa int perf_evlist__set_tp_filter_pid(struct evlist *evlist, pid_t pid) 1216be199adaSArnaldo Carvalho de Melo { 12177ad92a33SArnaldo Carvalho de Melo return perf_evlist__set_tp_filter_pids(evlist, 1, &pid); 1218be199adaSArnaldo Carvalho de Melo } 1219be199adaSArnaldo Carvalho de Melo 122063503dbaSJiri Olsa bool perf_evlist__valid_sample_type(struct evlist *evlist) 122174429964SFrederic Weisbecker { 122232dcd021SJiri Olsa struct evsel *pos; 1223c2a70653SArnaldo Carvalho de Melo 122475562573SAdrian Hunter if (evlist->nr_entries == 1) 122575562573SAdrian Hunter return true; 122675562573SAdrian Hunter 122775562573SAdrian Hunter if (evlist->id_pos < 0 || evlist->is_pos < 0) 122875562573SAdrian Hunter return false; 122975562573SAdrian Hunter 1230e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 123175562573SAdrian Hunter if (pos->id_pos != evlist->id_pos || 123275562573SAdrian Hunter pos->is_pos != evlist->is_pos) 1233c2a70653SArnaldo Carvalho de Melo return false; 123474429964SFrederic Weisbecker } 123574429964SFrederic Weisbecker 1236c2a70653SArnaldo Carvalho de Melo return true; 1237c2a70653SArnaldo Carvalho de Melo } 1238c2a70653SArnaldo Carvalho de Melo 123963503dbaSJiri Olsa u64 __perf_evlist__combined_sample_type(struct evlist *evlist) 1240c2a70653SArnaldo Carvalho de Melo { 124132dcd021SJiri Olsa struct evsel *evsel; 124275562573SAdrian Hunter 124375562573SAdrian Hunter if (evlist->combined_sample_type) 124475562573SAdrian Hunter return evlist->combined_sample_type; 124575562573SAdrian Hunter 1246e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 124775562573SAdrian Hunter evlist->combined_sample_type |= evsel->attr.sample_type; 124875562573SAdrian Hunter 124975562573SAdrian Hunter return evlist->combined_sample_type; 125075562573SAdrian Hunter } 125175562573SAdrian Hunter 125263503dbaSJiri Olsa u64 perf_evlist__combined_sample_type(struct evlist *evlist) 125375562573SAdrian Hunter { 125475562573SAdrian Hunter evlist->combined_sample_type = 0; 125575562573SAdrian Hunter return __perf_evlist__combined_sample_type(evlist); 1256c2a70653SArnaldo Carvalho de Melo } 1257c2a70653SArnaldo Carvalho de Melo 125863503dbaSJiri Olsa u64 perf_evlist__combined_branch_type(struct evlist *evlist) 125998df858eSAndi Kleen { 126032dcd021SJiri Olsa struct evsel *evsel; 126198df858eSAndi Kleen u64 branch_type = 0; 126298df858eSAndi Kleen 1263e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 126498df858eSAndi Kleen branch_type |= evsel->attr.branch_sample_type; 126598df858eSAndi Kleen return branch_type; 126698df858eSAndi Kleen } 126798df858eSAndi Kleen 126863503dbaSJiri Olsa bool perf_evlist__valid_read_format(struct evlist *evlist) 12699ede473cSJiri Olsa { 127032dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist), *pos = first; 12719ede473cSJiri Olsa u64 read_format = first->attr.read_format; 12729ede473cSJiri Olsa u64 sample_type = first->attr.sample_type; 12739ede473cSJiri Olsa 1274e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 12759ede473cSJiri Olsa if (read_format != pos->attr.read_format) 12769ede473cSJiri Olsa return false; 12779ede473cSJiri Olsa } 12789ede473cSJiri Olsa 12799ede473cSJiri Olsa /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */ 12809ede473cSJiri Olsa if ((sample_type & PERF_SAMPLE_READ) && 12819ede473cSJiri Olsa !(read_format & PERF_FORMAT_ID)) { 12829ede473cSJiri Olsa return false; 12839ede473cSJiri Olsa } 12849ede473cSJiri Olsa 12859ede473cSJiri Olsa return true; 12869ede473cSJiri Olsa } 12879ede473cSJiri Olsa 128863503dbaSJiri Olsa u64 perf_evlist__read_format(struct evlist *evlist) 12899ede473cSJiri Olsa { 129032dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 12919ede473cSJiri Olsa return first->attr.read_format; 12929ede473cSJiri Olsa } 12939ede473cSJiri Olsa 129463503dbaSJiri Olsa u16 perf_evlist__id_hdr_size(struct evlist *evlist) 129581e36bffSArnaldo Carvalho de Melo { 129632dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 129781e36bffSArnaldo Carvalho de Melo struct perf_sample *data; 129881e36bffSArnaldo Carvalho de Melo u64 sample_type; 129981e36bffSArnaldo Carvalho de Melo u16 size = 0; 130081e36bffSArnaldo Carvalho de Melo 130181e36bffSArnaldo Carvalho de Melo if (!first->attr.sample_id_all) 130281e36bffSArnaldo Carvalho de Melo goto out; 130381e36bffSArnaldo Carvalho de Melo 130481e36bffSArnaldo Carvalho de Melo sample_type = first->attr.sample_type; 130581e36bffSArnaldo Carvalho de Melo 130681e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_TID) 130781e36bffSArnaldo Carvalho de Melo size += sizeof(data->tid) * 2; 130881e36bffSArnaldo Carvalho de Melo 130981e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_TIME) 131081e36bffSArnaldo Carvalho de Melo size += sizeof(data->time); 131181e36bffSArnaldo Carvalho de Melo 131281e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_ID) 131381e36bffSArnaldo Carvalho de Melo size += sizeof(data->id); 131481e36bffSArnaldo Carvalho de Melo 131581e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_STREAM_ID) 131681e36bffSArnaldo Carvalho de Melo size += sizeof(data->stream_id); 131781e36bffSArnaldo Carvalho de Melo 131881e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_CPU) 131981e36bffSArnaldo Carvalho de Melo size += sizeof(data->cpu) * 2; 132075562573SAdrian Hunter 132175562573SAdrian Hunter if (sample_type & PERF_SAMPLE_IDENTIFIER) 132275562573SAdrian Hunter size += sizeof(data->id); 132381e36bffSArnaldo Carvalho de Melo out: 132481e36bffSArnaldo Carvalho de Melo return size; 132581e36bffSArnaldo Carvalho de Melo } 132681e36bffSArnaldo Carvalho de Melo 132763503dbaSJiri Olsa bool perf_evlist__valid_sample_id_all(struct evlist *evlist) 1328c2a70653SArnaldo Carvalho de Melo { 132932dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist), *pos = first; 1330c2a70653SArnaldo Carvalho de Melo 1331e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_continue(evlist, pos) { 1332c2a70653SArnaldo Carvalho de Melo if (first->attr.sample_id_all != pos->attr.sample_id_all) 1333c2a70653SArnaldo Carvalho de Melo return false; 1334c2a70653SArnaldo Carvalho de Melo } 1335c2a70653SArnaldo Carvalho de Melo 1336c2a70653SArnaldo Carvalho de Melo return true; 133774429964SFrederic Weisbecker } 133874429964SFrederic Weisbecker 133963503dbaSJiri Olsa bool perf_evlist__sample_id_all(struct evlist *evlist) 134074429964SFrederic Weisbecker { 134132dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 1342c2a70653SArnaldo Carvalho de Melo return first->attr.sample_id_all; 134374429964SFrederic Weisbecker } 134481cce8deSArnaldo Carvalho de Melo 134563503dbaSJiri Olsa void perf_evlist__set_selected(struct evlist *evlist, 134632dcd021SJiri Olsa struct evsel *evsel) 134781cce8deSArnaldo Carvalho de Melo { 134881cce8deSArnaldo Carvalho de Melo evlist->selected = evsel; 134981cce8deSArnaldo Carvalho de Melo } 1350727ab04eSArnaldo Carvalho de Melo 1351750b4edeSJiri Olsa void evlist__close(struct evlist *evlist) 1352a74b4b66SNamhyung Kim { 135332dcd021SJiri Olsa struct evsel *evsel; 1354a74b4b66SNamhyung Kim 1355475fb533SAndi Kleen evlist__for_each_entry_reverse(evlist, evsel) 1356475fb533SAndi Kleen perf_evsel__close(evsel); 1357a74b4b66SNamhyung Kim } 1358a74b4b66SNamhyung Kim 135963503dbaSJiri Olsa static int perf_evlist__create_syswide_maps(struct evlist *evlist) 13604112eb18SArnaldo Carvalho de Melo { 1361f854839bSJiri Olsa struct perf_cpu_map *cpus; 13629749b90eSJiri Olsa struct perf_thread_map *threads; 13634112eb18SArnaldo Carvalho de Melo int err = -ENOMEM; 13644112eb18SArnaldo Carvalho de Melo 13654112eb18SArnaldo Carvalho de Melo /* 13664112eb18SArnaldo Carvalho de Melo * Try reading /sys/devices/system/cpu/online to get 13674112eb18SArnaldo Carvalho de Melo * an all cpus map. 13684112eb18SArnaldo Carvalho de Melo * 13694112eb18SArnaldo Carvalho de Melo * FIXME: -ENOMEM is the best we can do here, the cpu_map 13704112eb18SArnaldo Carvalho de Melo * code needs an overhaul to properly forward the 13714112eb18SArnaldo Carvalho de Melo * error, and we may not want to do that fallback to a 13724112eb18SArnaldo Carvalho de Melo * default cpu identity map :-\ 13734112eb18SArnaldo Carvalho de Melo */ 13748c0498b6SAdrian Hunter cpus = cpu_map__new(NULL); 13758c0498b6SAdrian Hunter if (!cpus) 13764112eb18SArnaldo Carvalho de Melo goto out; 13774112eb18SArnaldo Carvalho de Melo 13784b49cce2SJiri Olsa threads = perf_thread_map__new_dummy(); 13798c0498b6SAdrian Hunter if (!threads) 13808c0498b6SAdrian Hunter goto out_put; 13814112eb18SArnaldo Carvalho de Melo 13828c0498b6SAdrian Hunter perf_evlist__set_maps(evlist, cpus, threads); 13834112eb18SArnaldo Carvalho de Melo out: 13844112eb18SArnaldo Carvalho de Melo return err; 13858c0498b6SAdrian Hunter out_put: 138638f01d8dSJiri Olsa perf_cpu_map__put(cpus); 13874112eb18SArnaldo Carvalho de Melo goto out; 13884112eb18SArnaldo Carvalho de Melo } 13894112eb18SArnaldo Carvalho de Melo 1390474ddc4cSJiri Olsa int evlist__open(struct evlist *evlist) 1391727ab04eSArnaldo Carvalho de Melo { 139232dcd021SJiri Olsa struct evsel *evsel; 1393a74b4b66SNamhyung Kim int err; 1394727ab04eSArnaldo Carvalho de Melo 13954112eb18SArnaldo Carvalho de Melo /* 13964112eb18SArnaldo Carvalho de Melo * Default: one fd per CPU, all threads, aka systemwide 13974112eb18SArnaldo Carvalho de Melo * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL 13984112eb18SArnaldo Carvalho de Melo */ 13994112eb18SArnaldo Carvalho de Melo if (evlist->threads == NULL && evlist->cpus == NULL) { 14004112eb18SArnaldo Carvalho de Melo err = perf_evlist__create_syswide_maps(evlist); 14014112eb18SArnaldo Carvalho de Melo if (err < 0) 14024112eb18SArnaldo Carvalho de Melo goto out_err; 14034112eb18SArnaldo Carvalho de Melo } 14044112eb18SArnaldo Carvalho de Melo 1405733cd2feSAdrian Hunter perf_evlist__update_id_pos(evlist); 1406733cd2feSAdrian Hunter 1407e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 14085972d1e0SJiri Olsa err = evsel__open(evsel, evsel->cpus, evsel->threads); 1409727ab04eSArnaldo Carvalho de Melo if (err < 0) 1410727ab04eSArnaldo Carvalho de Melo goto out_err; 1411727ab04eSArnaldo Carvalho de Melo } 1412727ab04eSArnaldo Carvalho de Melo 1413727ab04eSArnaldo Carvalho de Melo return 0; 1414727ab04eSArnaldo Carvalho de Melo out_err: 1415750b4edeSJiri Olsa evlist__close(evlist); 141641c21a68SNamhyung Kim errno = -err; 1417727ab04eSArnaldo Carvalho de Melo return err; 1418727ab04eSArnaldo Carvalho de Melo } 141935b9d88eSArnaldo Carvalho de Melo 142063503dbaSJiri Olsa int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, 142155e162eaSNamhyung Kim const char *argv[], bool pipe_output, 1422735f7e0bSArnaldo Carvalho de Melo void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) 142335b9d88eSArnaldo Carvalho de Melo { 142435b9d88eSArnaldo Carvalho de Melo int child_ready_pipe[2], go_pipe[2]; 142535b9d88eSArnaldo Carvalho de Melo char bf; 142635b9d88eSArnaldo Carvalho de Melo 142735b9d88eSArnaldo Carvalho de Melo if (pipe(child_ready_pipe) < 0) { 142835b9d88eSArnaldo Carvalho de Melo perror("failed to create 'ready' pipe"); 142935b9d88eSArnaldo Carvalho de Melo return -1; 143035b9d88eSArnaldo Carvalho de Melo } 143135b9d88eSArnaldo Carvalho de Melo 143235b9d88eSArnaldo Carvalho de Melo if (pipe(go_pipe) < 0) { 143335b9d88eSArnaldo Carvalho de Melo perror("failed to create 'go' pipe"); 143435b9d88eSArnaldo Carvalho de Melo goto out_close_ready_pipe; 143535b9d88eSArnaldo Carvalho de Melo } 143635b9d88eSArnaldo Carvalho de Melo 143735b9d88eSArnaldo Carvalho de Melo evlist->workload.pid = fork(); 143835b9d88eSArnaldo Carvalho de Melo if (evlist->workload.pid < 0) { 143935b9d88eSArnaldo Carvalho de Melo perror("failed to fork"); 144035b9d88eSArnaldo Carvalho de Melo goto out_close_pipes; 144135b9d88eSArnaldo Carvalho de Melo } 144235b9d88eSArnaldo Carvalho de Melo 144335b9d88eSArnaldo Carvalho de Melo if (!evlist->workload.pid) { 14445f1c4225SArnaldo Carvalho de Melo int ret; 14455f1c4225SArnaldo Carvalho de Melo 1446119fa3c9SNamhyung Kim if (pipe_output) 144735b9d88eSArnaldo Carvalho de Melo dup2(2, 1); 144835b9d88eSArnaldo Carvalho de Melo 14490817df08SDavid Ahern signal(SIGTERM, SIG_DFL); 14500817df08SDavid Ahern 145135b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 145235b9d88eSArnaldo Carvalho de Melo close(go_pipe[1]); 145335b9d88eSArnaldo Carvalho de Melo fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 145435b9d88eSArnaldo Carvalho de Melo 145535b9d88eSArnaldo Carvalho de Melo /* 145635b9d88eSArnaldo Carvalho de Melo * Tell the parent we're ready to go 145735b9d88eSArnaldo Carvalho de Melo */ 145835b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 145935b9d88eSArnaldo Carvalho de Melo 146035b9d88eSArnaldo Carvalho de Melo /* 146135b9d88eSArnaldo Carvalho de Melo * Wait until the parent tells us to go. 146235b9d88eSArnaldo Carvalho de Melo */ 14635f1c4225SArnaldo Carvalho de Melo ret = read(go_pipe[0], &bf, 1); 14645f1c4225SArnaldo Carvalho de Melo /* 14655f1c4225SArnaldo Carvalho de Melo * The parent will ask for the execvp() to be performed by 14665f1c4225SArnaldo Carvalho de Melo * writing exactly one byte, in workload.cork_fd, usually via 14675f1c4225SArnaldo Carvalho de Melo * perf_evlist__start_workload(). 14685f1c4225SArnaldo Carvalho de Melo * 146920f86fc1SArnaldo Carvalho de Melo * For cancelling the workload without actually running it, 14705f1c4225SArnaldo Carvalho de Melo * the parent will just close workload.cork_fd, without writing 14715f1c4225SArnaldo Carvalho de Melo * anything, i.e. read will return zero and we just exit() 14725f1c4225SArnaldo Carvalho de Melo * here. 14735f1c4225SArnaldo Carvalho de Melo */ 14745f1c4225SArnaldo Carvalho de Melo if (ret != 1) { 14755f1c4225SArnaldo Carvalho de Melo if (ret == -1) 147635b9d88eSArnaldo Carvalho de Melo perror("unable to read pipe"); 14775f1c4225SArnaldo Carvalho de Melo exit(ret); 14785f1c4225SArnaldo Carvalho de Melo } 147935b9d88eSArnaldo Carvalho de Melo 148035b9d88eSArnaldo Carvalho de Melo execvp(argv[0], (char **)argv); 148135b9d88eSArnaldo Carvalho de Melo 1482735f7e0bSArnaldo Carvalho de Melo if (exec_error) { 1483f33cbe72SArnaldo Carvalho de Melo union sigval val; 1484f33cbe72SArnaldo Carvalho de Melo 1485f33cbe72SArnaldo Carvalho de Melo val.sival_int = errno; 1486f33cbe72SArnaldo Carvalho de Melo if (sigqueue(getppid(), SIGUSR1, val)) 148735b9d88eSArnaldo Carvalho de Melo perror(argv[0]); 1488f33cbe72SArnaldo Carvalho de Melo } else 1489f33cbe72SArnaldo Carvalho de Melo perror(argv[0]); 149035b9d88eSArnaldo Carvalho de Melo exit(-1); 149135b9d88eSArnaldo Carvalho de Melo } 149235b9d88eSArnaldo Carvalho de Melo 1493735f7e0bSArnaldo Carvalho de Melo if (exec_error) { 1494735f7e0bSArnaldo Carvalho de Melo struct sigaction act = { 1495735f7e0bSArnaldo Carvalho de Melo .sa_flags = SA_SIGINFO, 1496735f7e0bSArnaldo Carvalho de Melo .sa_sigaction = exec_error, 1497735f7e0bSArnaldo Carvalho de Melo }; 1498735f7e0bSArnaldo Carvalho de Melo sigaction(SIGUSR1, &act, NULL); 1499735f7e0bSArnaldo Carvalho de Melo } 1500735f7e0bSArnaldo Carvalho de Melo 15011aaf63b1SArnaldo Carvalho de Melo if (target__none(target)) { 15021aaf63b1SArnaldo Carvalho de Melo if (evlist->threads == NULL) { 15031aaf63b1SArnaldo Carvalho de Melo fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", 15041aaf63b1SArnaldo Carvalho de Melo __func__, __LINE__); 15051aaf63b1SArnaldo Carvalho de Melo goto out_close_pipes; 15061aaf63b1SArnaldo Carvalho de Melo } 15074b49cce2SJiri Olsa perf_thread_map__set_pid(evlist->threads, 0, evlist->workload.pid); 15081aaf63b1SArnaldo Carvalho de Melo } 150935b9d88eSArnaldo Carvalho de Melo 151035b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 151135b9d88eSArnaldo Carvalho de Melo close(go_pipe[0]); 151235b9d88eSArnaldo Carvalho de Melo /* 151335b9d88eSArnaldo Carvalho de Melo * wait for child to settle 151435b9d88eSArnaldo Carvalho de Melo */ 151535b9d88eSArnaldo Carvalho de Melo if (read(child_ready_pipe[0], &bf, 1) == -1) { 151635b9d88eSArnaldo Carvalho de Melo perror("unable to read pipe"); 151735b9d88eSArnaldo Carvalho de Melo goto out_close_pipes; 151835b9d88eSArnaldo Carvalho de Melo } 151935b9d88eSArnaldo Carvalho de Melo 1520bcf3145fSNamhyung Kim fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); 152135b9d88eSArnaldo Carvalho de Melo evlist->workload.cork_fd = go_pipe[1]; 152235b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 152335b9d88eSArnaldo Carvalho de Melo return 0; 152435b9d88eSArnaldo Carvalho de Melo 152535b9d88eSArnaldo Carvalho de Melo out_close_pipes: 152635b9d88eSArnaldo Carvalho de Melo close(go_pipe[0]); 152735b9d88eSArnaldo Carvalho de Melo close(go_pipe[1]); 152835b9d88eSArnaldo Carvalho de Melo out_close_ready_pipe: 152935b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 153035b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 153135b9d88eSArnaldo Carvalho de Melo return -1; 153235b9d88eSArnaldo Carvalho de Melo } 153335b9d88eSArnaldo Carvalho de Melo 153463503dbaSJiri Olsa int perf_evlist__start_workload(struct evlist *evlist) 153535b9d88eSArnaldo Carvalho de Melo { 153635b9d88eSArnaldo Carvalho de Melo if (evlist->workload.cork_fd > 0) { 1537b3824404SDavid Ahern char bf = 0; 1538bcf3145fSNamhyung Kim int ret; 153935b9d88eSArnaldo Carvalho de Melo /* 154035b9d88eSArnaldo Carvalho de Melo * Remove the cork, let it rip! 154135b9d88eSArnaldo Carvalho de Melo */ 1542bcf3145fSNamhyung Kim ret = write(evlist->workload.cork_fd, &bf, 1); 1543bcf3145fSNamhyung Kim if (ret < 0) 1544e978be9eSSoramichi Akiyama perror("unable to write to pipe"); 1545bcf3145fSNamhyung Kim 1546bcf3145fSNamhyung Kim close(evlist->workload.cork_fd); 1547bcf3145fSNamhyung Kim return ret; 154835b9d88eSArnaldo Carvalho de Melo } 154935b9d88eSArnaldo Carvalho de Melo 155035b9d88eSArnaldo Carvalho de Melo return 0; 155135b9d88eSArnaldo Carvalho de Melo } 1552cb0b29e0SArnaldo Carvalho de Melo 155363503dbaSJiri Olsa int perf_evlist__parse_sample(struct evlist *evlist, union perf_event *event, 15540807d2d8SArnaldo Carvalho de Melo struct perf_sample *sample) 1555cb0b29e0SArnaldo Carvalho de Melo { 155632dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 155775562573SAdrian Hunter 155875562573SAdrian Hunter if (!evsel) 155975562573SAdrian Hunter return -EFAULT; 15600807d2d8SArnaldo Carvalho de Melo return perf_evsel__parse_sample(evsel, event, sample); 1561cb0b29e0SArnaldo Carvalho de Melo } 156278f067b3SArnaldo Carvalho de Melo 156363503dbaSJiri Olsa int perf_evlist__parse_sample_timestamp(struct evlist *evlist, 156401468120SJiri Olsa union perf_event *event, 156501468120SJiri Olsa u64 *timestamp) 156601468120SJiri Olsa { 156732dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 156801468120SJiri Olsa 156901468120SJiri Olsa if (!evsel) 157001468120SJiri Olsa return -EFAULT; 157101468120SJiri Olsa return perf_evsel__parse_sample_timestamp(evsel, event, timestamp); 157201468120SJiri Olsa } 157301468120SJiri Olsa 157463503dbaSJiri Olsa size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp) 157578f067b3SArnaldo Carvalho de Melo { 157632dcd021SJiri Olsa struct evsel *evsel; 157778f067b3SArnaldo Carvalho de Melo size_t printed = 0; 157878f067b3SArnaldo Carvalho de Melo 1579e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 158078f067b3SArnaldo Carvalho de Melo printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", 158178f067b3SArnaldo Carvalho de Melo perf_evsel__name(evsel)); 158278f067b3SArnaldo Carvalho de Melo } 158378f067b3SArnaldo Carvalho de Melo 1584b2222139SDavidlohr Bueso return printed + fprintf(fp, "\n"); 158578f067b3SArnaldo Carvalho de Melo } 15866ef068cbSArnaldo Carvalho de Melo 158763503dbaSJiri Olsa int perf_evlist__strerror_open(struct evlist *evlist, 1588a8f23d8fSArnaldo Carvalho de Melo int err, char *buf, size_t size) 1589a8f23d8fSArnaldo Carvalho de Melo { 1590a8f23d8fSArnaldo Carvalho de Melo int printed, value; 1591c8b5f2c9SArnaldo Carvalho de Melo char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); 1592a8f23d8fSArnaldo Carvalho de Melo 1593a8f23d8fSArnaldo Carvalho de Melo switch (err) { 1594a8f23d8fSArnaldo Carvalho de Melo case EACCES: 1595a8f23d8fSArnaldo Carvalho de Melo case EPERM: 1596a8f23d8fSArnaldo Carvalho de Melo printed = scnprintf(buf, size, 1597a8f23d8fSArnaldo Carvalho de Melo "Error:\t%s.\n" 1598a8f23d8fSArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); 1599a8f23d8fSArnaldo Carvalho de Melo 16001a47245dSAdrian Hunter value = perf_event_paranoid(); 1601a8f23d8fSArnaldo Carvalho de Melo 1602a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, "\nHint:\t"); 1603a8f23d8fSArnaldo Carvalho de Melo 1604a8f23d8fSArnaldo Carvalho de Melo if (value >= 2) { 1605a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1606a8f23d8fSArnaldo Carvalho de Melo "For your workloads it needs to be <= 1\nHint:\t"); 1607a8f23d8fSArnaldo Carvalho de Melo } 1608a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 16095229e366SArnaldo Carvalho de Melo "For system wide tracing it needs to be set to -1.\n"); 1610a8f23d8fSArnaldo Carvalho de Melo 1611a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 16125229e366SArnaldo Carvalho de Melo "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n" 16135229e366SArnaldo Carvalho de Melo "Hint:\tThe current value is %d.", value); 1614a8f23d8fSArnaldo Carvalho de Melo break; 1615d9aade7fSArnaldo Carvalho de Melo case EINVAL: { 161632dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 1617d9aade7fSArnaldo Carvalho de Melo int max_freq; 1618d9aade7fSArnaldo Carvalho de Melo 1619d9aade7fSArnaldo Carvalho de Melo if (sysctl__read_int("kernel/perf_event_max_sample_rate", &max_freq) < 0) 1620d9aade7fSArnaldo Carvalho de Melo goto out_default; 1621d9aade7fSArnaldo Carvalho de Melo 1622d9aade7fSArnaldo Carvalho de Melo if (first->attr.sample_freq < (u64)max_freq) 1623d9aade7fSArnaldo Carvalho de Melo goto out_default; 1624d9aade7fSArnaldo Carvalho de Melo 1625d9aade7fSArnaldo Carvalho de Melo printed = scnprintf(buf, size, 1626d9aade7fSArnaldo Carvalho de Melo "Error:\t%s.\n" 1627d9aade7fSArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_max_sample_rate.\n" 1628d9aade7fSArnaldo Carvalho de Melo "Hint:\tThe current value is %d and %" PRIu64 " is being requested.", 1629d9aade7fSArnaldo Carvalho de Melo emsg, max_freq, first->attr.sample_freq); 1630d9aade7fSArnaldo Carvalho de Melo break; 1631d9aade7fSArnaldo Carvalho de Melo } 1632a8f23d8fSArnaldo Carvalho de Melo default: 1633d9aade7fSArnaldo Carvalho de Melo out_default: 1634a8f23d8fSArnaldo Carvalho de Melo scnprintf(buf, size, "%s", emsg); 1635a8f23d8fSArnaldo Carvalho de Melo break; 1636a8f23d8fSArnaldo Carvalho de Melo } 1637a8f23d8fSArnaldo Carvalho de Melo 1638a8f23d8fSArnaldo Carvalho de Melo return 0; 1639a8f23d8fSArnaldo Carvalho de Melo } 1640a025e4f0SAdrian Hunter 164163503dbaSJiri Olsa int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) 1642956fa571SArnaldo Carvalho de Melo { 1643c8b5f2c9SArnaldo Carvalho de Melo char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); 1644e965bea1SArnaldo Carvalho de Melo int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; 1645956fa571SArnaldo Carvalho de Melo 1646956fa571SArnaldo Carvalho de Melo switch (err) { 1647956fa571SArnaldo Carvalho de Melo case EPERM: 1648e5d4a290SArnaldo Carvalho de Melo sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); 1649e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1650e965bea1SArnaldo Carvalho de Melo "Error:\t%s.\n" 1651956fa571SArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" 1652e965bea1SArnaldo Carvalho de Melo "Hint:\tTried using %zd kB.\n", 1653e5d4a290SArnaldo Carvalho de Melo emsg, pages_max_per_user, pages_attempted); 1654e965bea1SArnaldo Carvalho de Melo 1655e965bea1SArnaldo Carvalho de Melo if (pages_attempted >= pages_max_per_user) { 1656e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1657e965bea1SArnaldo Carvalho de Melo "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", 1658e965bea1SArnaldo Carvalho de Melo pages_max_per_user + pages_attempted); 1659e965bea1SArnaldo Carvalho de Melo } 1660e965bea1SArnaldo Carvalho de Melo 1661e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1662e965bea1SArnaldo Carvalho de Melo "Hint:\tTry using a smaller -m/--mmap-pages value."); 1663956fa571SArnaldo Carvalho de Melo break; 1664956fa571SArnaldo Carvalho de Melo default: 1665956fa571SArnaldo Carvalho de Melo scnprintf(buf, size, "%s", emsg); 1666956fa571SArnaldo Carvalho de Melo break; 1667956fa571SArnaldo Carvalho de Melo } 1668956fa571SArnaldo Carvalho de Melo 1669956fa571SArnaldo Carvalho de Melo return 0; 1670956fa571SArnaldo Carvalho de Melo } 1671956fa571SArnaldo Carvalho de Melo 167263503dbaSJiri Olsa void perf_evlist__to_front(struct evlist *evlist, 167332dcd021SJiri Olsa struct evsel *move_evsel) 1674a025e4f0SAdrian Hunter { 167532dcd021SJiri Olsa struct evsel *evsel, *n; 1676a025e4f0SAdrian Hunter LIST_HEAD(move); 1677a025e4f0SAdrian Hunter 1678a025e4f0SAdrian Hunter if (move_evsel == perf_evlist__first(evlist)) 1679a025e4f0SAdrian Hunter return; 1680a025e4f0SAdrian Hunter 1681e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_safe(evlist, n, evsel) { 1682a025e4f0SAdrian Hunter if (evsel->leader == move_evsel->leader) 1683b27c4eceSJiri Olsa list_move_tail(&evsel->core.node, &move); 1684a025e4f0SAdrian Hunter } 1685a025e4f0SAdrian Hunter 1686ce9036a6SJiri Olsa list_splice(&move, &evlist->core.entries); 1687a025e4f0SAdrian Hunter } 168860b0896cSAdrian Hunter 168963503dbaSJiri Olsa void perf_evlist__set_tracking_event(struct evlist *evlist, 169032dcd021SJiri Olsa struct evsel *tracking_evsel) 169160b0896cSAdrian Hunter { 169232dcd021SJiri Olsa struct evsel *evsel; 169360b0896cSAdrian Hunter 169460b0896cSAdrian Hunter if (tracking_evsel->tracking) 169560b0896cSAdrian Hunter return; 169660b0896cSAdrian Hunter 1697e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 169860b0896cSAdrian Hunter if (evsel != tracking_evsel) 169960b0896cSAdrian Hunter evsel->tracking = false; 170060b0896cSAdrian Hunter } 170160b0896cSAdrian Hunter 170260b0896cSAdrian Hunter tracking_evsel->tracking = true; 170360b0896cSAdrian Hunter } 17047630b3e2SWang Nan 170532dcd021SJiri Olsa struct evsel * 170663503dbaSJiri Olsa perf_evlist__find_evsel_by_str(struct evlist *evlist, 17077630b3e2SWang Nan const char *str) 17087630b3e2SWang Nan { 170932dcd021SJiri Olsa struct evsel *evsel; 17107630b3e2SWang Nan 1711e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 17127630b3e2SWang Nan if (!evsel->name) 17137630b3e2SWang Nan continue; 17147630b3e2SWang Nan if (strcmp(str, evsel->name) == 0) 17157630b3e2SWang Nan return evsel; 17167630b3e2SWang Nan } 17177630b3e2SWang Nan 17187630b3e2SWang Nan return NULL; 17197630b3e2SWang Nan } 172054cc54deSWang Nan 172163503dbaSJiri Olsa void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, 172254cc54deSWang Nan enum bkw_mmap_state state) 172354cc54deSWang Nan { 172454cc54deSWang Nan enum bkw_mmap_state old_state = evlist->bkw_mmap_state; 172554cc54deSWang Nan enum action { 172654cc54deSWang Nan NONE, 172754cc54deSWang Nan PAUSE, 172854cc54deSWang Nan RESUME, 172954cc54deSWang Nan } action = NONE; 173054cc54deSWang Nan 17310b72d69aSWang Nan if (!evlist->overwrite_mmap) 173254cc54deSWang Nan return; 173354cc54deSWang Nan 173454cc54deSWang Nan switch (old_state) { 173554cc54deSWang Nan case BKW_MMAP_NOTREADY: { 173654cc54deSWang Nan if (state != BKW_MMAP_RUNNING) 1737dd8bd53aSLuis de Bethencourt goto state_err; 173854cc54deSWang Nan break; 173954cc54deSWang Nan } 174054cc54deSWang Nan case BKW_MMAP_RUNNING: { 174154cc54deSWang Nan if (state != BKW_MMAP_DATA_PENDING) 174254cc54deSWang Nan goto state_err; 174354cc54deSWang Nan action = PAUSE; 174454cc54deSWang Nan break; 174554cc54deSWang Nan } 174654cc54deSWang Nan case BKW_MMAP_DATA_PENDING: { 174754cc54deSWang Nan if (state != BKW_MMAP_EMPTY) 174854cc54deSWang Nan goto state_err; 174954cc54deSWang Nan break; 175054cc54deSWang Nan } 175154cc54deSWang Nan case BKW_MMAP_EMPTY: { 175254cc54deSWang Nan if (state != BKW_MMAP_RUNNING) 175354cc54deSWang Nan goto state_err; 175454cc54deSWang Nan action = RESUME; 175554cc54deSWang Nan break; 175654cc54deSWang Nan } 175754cc54deSWang Nan default: 175854cc54deSWang Nan WARN_ONCE(1, "Shouldn't get there\n"); 175954cc54deSWang Nan } 176054cc54deSWang Nan 176154cc54deSWang Nan evlist->bkw_mmap_state = state; 176254cc54deSWang Nan 176354cc54deSWang Nan switch (action) { 176454cc54deSWang Nan case PAUSE: 176554cc54deSWang Nan perf_evlist__pause(evlist); 176654cc54deSWang Nan break; 176754cc54deSWang Nan case RESUME: 176854cc54deSWang Nan perf_evlist__resume(evlist); 176954cc54deSWang Nan break; 177054cc54deSWang Nan case NONE: 177154cc54deSWang Nan default: 177254cc54deSWang Nan break; 177354cc54deSWang Nan } 177454cc54deSWang Nan 177554cc54deSWang Nan state_err: 177654cc54deSWang Nan return; 177754cc54deSWang Nan } 177807d6f446SArnaldo Carvalho de Melo 177963503dbaSJiri Olsa bool perf_evlist__exclude_kernel(struct evlist *evlist) 178007d6f446SArnaldo Carvalho de Melo { 178132dcd021SJiri Olsa struct evsel *evsel; 178207d6f446SArnaldo Carvalho de Melo 178307d6f446SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 178407d6f446SArnaldo Carvalho de Melo if (!evsel->attr.exclude_kernel) 178507d6f446SArnaldo Carvalho de Melo return false; 178607d6f446SArnaldo Carvalho de Melo } 178707d6f446SArnaldo Carvalho de Melo 178807d6f446SArnaldo Carvalho de Melo return true; 178907d6f446SArnaldo Carvalho de Melo } 1790e2bdbe80SJin Yao 1791e2bdbe80SJin Yao /* 1792e2bdbe80SJin Yao * Events in data file are not collect in groups, but we still want 1793e2bdbe80SJin Yao * the group display. Set the artificial group and set the leader's 1794e2bdbe80SJin Yao * forced_leader flag to notify the display code. 1795e2bdbe80SJin Yao */ 179663503dbaSJiri Olsa void perf_evlist__force_leader(struct evlist *evlist) 1797e2bdbe80SJin Yao { 1798e2bdbe80SJin Yao if (!evlist->nr_groups) { 179932dcd021SJiri Olsa struct evsel *leader = perf_evlist__first(evlist); 1800e2bdbe80SJin Yao 1801e2bdbe80SJin Yao perf_evlist__set_leader(evlist); 1802e2bdbe80SJin Yao leader->forced_leader = true; 1803e2bdbe80SJin Yao } 1804e2bdbe80SJin Yao } 1805c3537fc2SAndi Kleen 180663503dbaSJiri Olsa struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, 180732dcd021SJiri Olsa struct evsel *evsel) 1808c3537fc2SAndi Kleen { 180932dcd021SJiri Olsa struct evsel *c2, *leader; 1810c3537fc2SAndi Kleen bool is_open = true; 1811c3537fc2SAndi Kleen 1812c3537fc2SAndi Kleen leader = evsel->leader; 1813c3537fc2SAndi Kleen pr_debug("Weak group for %s/%d failed\n", 1814c3537fc2SAndi Kleen leader->name, leader->nr_members); 1815c3537fc2SAndi Kleen 1816c3537fc2SAndi Kleen /* 1817c3537fc2SAndi Kleen * for_each_group_member doesn't work here because it doesn't 1818c3537fc2SAndi Kleen * include the first entry. 1819c3537fc2SAndi Kleen */ 1820c3537fc2SAndi Kleen evlist__for_each_entry(evsel_list, c2) { 1821c3537fc2SAndi Kleen if (c2 == evsel) 1822c3537fc2SAndi Kleen is_open = false; 1823c3537fc2SAndi Kleen if (c2->leader == leader) { 1824c3537fc2SAndi Kleen if (is_open) 1825c3537fc2SAndi Kleen perf_evsel__close(c2); 1826c3537fc2SAndi Kleen c2->leader = c2; 1827c3537fc2SAndi Kleen c2->nr_members = 0; 1828c3537fc2SAndi Kleen } 1829c3537fc2SAndi Kleen } 1830c3537fc2SAndi Kleen return leader; 1831c3537fc2SAndi Kleen } 1832657ee553SSong Liu 183363503dbaSJiri Olsa int perf_evlist__add_sb_event(struct evlist **evlist, 1834657ee553SSong Liu struct perf_event_attr *attr, 1835657ee553SSong Liu perf_evsel__sb_cb_t cb, 1836657ee553SSong Liu void *data) 1837657ee553SSong Liu { 183832dcd021SJiri Olsa struct evsel *evsel; 1839657ee553SSong Liu bool new_evlist = (*evlist) == NULL; 1840657ee553SSong Liu 1841657ee553SSong Liu if (*evlist == NULL) 18420f98b11cSJiri Olsa *evlist = evlist__new(); 1843657ee553SSong Liu if (*evlist == NULL) 1844657ee553SSong Liu return -1; 1845657ee553SSong Liu 1846657ee553SSong Liu if (!attr->sample_id_all) { 1847657ee553SSong Liu pr_warning("enabling sample_id_all for all side band events\n"); 1848657ee553SSong Liu attr->sample_id_all = 1; 1849657ee553SSong Liu } 1850657ee553SSong Liu 1851657ee553SSong Liu evsel = perf_evsel__new_idx(attr, (*evlist)->nr_entries); 1852657ee553SSong Liu if (!evsel) 1853657ee553SSong Liu goto out_err; 1854657ee553SSong Liu 1855657ee553SSong Liu evsel->side_band.cb = cb; 1856657ee553SSong Liu evsel->side_band.data = data; 1857a1cf3a75SJiri Olsa evlist__add(*evlist, evsel); 1858657ee553SSong Liu return 0; 1859657ee553SSong Liu 1860657ee553SSong Liu out_err: 1861657ee553SSong Liu if (new_evlist) { 1862c12995a5SJiri Olsa evlist__delete(*evlist); 1863657ee553SSong Liu *evlist = NULL; 1864657ee553SSong Liu } 1865657ee553SSong Liu return -1; 1866657ee553SSong Liu } 1867657ee553SSong Liu 1868657ee553SSong Liu static void *perf_evlist__poll_thread(void *arg) 1869657ee553SSong Liu { 187063503dbaSJiri Olsa struct evlist *evlist = arg; 1871657ee553SSong Liu bool draining = false; 1872adc6257cSJiri Olsa int i, done = 0; 1873657ee553SSong Liu 1874adc6257cSJiri Olsa while (!done) { 1875adc6257cSJiri Olsa bool got_data = false; 1876adc6257cSJiri Olsa 1877adc6257cSJiri Olsa if (evlist->thread.done) 1878657ee553SSong Liu draining = true; 1879657ee553SSong Liu 1880657ee553SSong Liu if (!draining) 1881657ee553SSong Liu perf_evlist__poll(evlist, 1000); 1882657ee553SSong Liu 1883657ee553SSong Liu for (i = 0; i < evlist->nr_mmaps; i++) { 1884657ee553SSong Liu struct perf_mmap *map = &evlist->mmap[i]; 1885657ee553SSong Liu union perf_event *event; 1886657ee553SSong Liu 1887657ee553SSong Liu if (perf_mmap__read_init(map)) 1888657ee553SSong Liu continue; 1889657ee553SSong Liu while ((event = perf_mmap__read_event(map)) != NULL) { 189032dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 1891657ee553SSong Liu 1892657ee553SSong Liu if (evsel && evsel->side_band.cb) 1893657ee553SSong Liu evsel->side_band.cb(event, evsel->side_band.data); 1894657ee553SSong Liu else 1895657ee553SSong Liu pr_warning("cannot locate proper evsel for the side band event\n"); 1896657ee553SSong Liu 1897657ee553SSong Liu perf_mmap__consume(map); 1898adc6257cSJiri Olsa got_data = true; 1899657ee553SSong Liu } 1900657ee553SSong Liu perf_mmap__read_done(map); 1901657ee553SSong Liu } 1902adc6257cSJiri Olsa 1903adc6257cSJiri Olsa if (draining && !got_data) 1904adc6257cSJiri Olsa break; 1905657ee553SSong Liu } 1906657ee553SSong Liu return NULL; 1907657ee553SSong Liu } 1908657ee553SSong Liu 190963503dbaSJiri Olsa int perf_evlist__start_sb_thread(struct evlist *evlist, 1910657ee553SSong Liu struct target *target) 1911657ee553SSong Liu { 191232dcd021SJiri Olsa struct evsel *counter; 1913657ee553SSong Liu 1914657ee553SSong Liu if (!evlist) 1915657ee553SSong Liu return 0; 1916657ee553SSong Liu 1917657ee553SSong Liu if (perf_evlist__create_maps(evlist, target)) 1918657ee553SSong Liu goto out_delete_evlist; 1919657ee553SSong Liu 1920657ee553SSong Liu evlist__for_each_entry(evlist, counter) { 19215972d1e0SJiri Olsa if (evsel__open(counter, evlist->cpus, 1922657ee553SSong Liu evlist->threads) < 0) 1923657ee553SSong Liu goto out_delete_evlist; 1924657ee553SSong Liu } 1925657ee553SSong Liu 1926657ee553SSong Liu if (perf_evlist__mmap(evlist, UINT_MAX)) 1927657ee553SSong Liu goto out_delete_evlist; 1928657ee553SSong Liu 1929657ee553SSong Liu evlist__for_each_entry(evlist, counter) { 1930ec7f24efSJiri Olsa if (evsel__enable(counter)) 1931657ee553SSong Liu goto out_delete_evlist; 1932657ee553SSong Liu } 1933657ee553SSong Liu 1934657ee553SSong Liu evlist->thread.done = 0; 1935657ee553SSong Liu if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist)) 1936657ee553SSong Liu goto out_delete_evlist; 1937657ee553SSong Liu 1938657ee553SSong Liu return 0; 1939657ee553SSong Liu 1940657ee553SSong Liu out_delete_evlist: 1941c12995a5SJiri Olsa evlist__delete(evlist); 1942657ee553SSong Liu evlist = NULL; 1943657ee553SSong Liu return -1; 1944657ee553SSong Liu } 1945657ee553SSong Liu 194663503dbaSJiri Olsa void perf_evlist__stop_sb_thread(struct evlist *evlist) 1947657ee553SSong Liu { 1948657ee553SSong Liu if (!evlist) 1949657ee553SSong Liu return; 1950657ee553SSong Liu evlist->thread.done = 1; 1951657ee553SSong Liu pthread_join(evlist->thread.th, NULL); 1952c12995a5SJiri Olsa evlist__delete(evlist); 1953657ee553SSong Liu } 1954