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> 364562a739SJiri Olsa #include <perf/evlist.h> 379c3516d1SJiri Olsa #include <perf/cpumap.h> 3870db7533SArnaldo Carvalho de Melo 39748fe088SArnaldo Carvalho de Melo #ifdef LACKS_SIGQUEUE_PROTOTYPE 40748fe088SArnaldo Carvalho de Melo int sigqueue(pid_t pid, int sig, const union sigval value); 41748fe088SArnaldo Carvalho de Melo #endif 42748fe088SArnaldo Carvalho de Melo 43f8a95309SArnaldo Carvalho de Melo #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 44a91e5431SArnaldo Carvalho de Melo #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 45f8a95309SArnaldo Carvalho de Melo 4652c86bcaSJiri Olsa void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, 479749b90eSJiri Olsa struct perf_thread_map *threads) 48361c99a6SArnaldo Carvalho de Melo { 4970db7533SArnaldo Carvalho de Melo int i; 5070db7533SArnaldo Carvalho de Melo 5170db7533SArnaldo Carvalho de Melo for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) 5270db7533SArnaldo Carvalho de Melo INIT_HLIST_HEAD(&evlist->heads[i]); 534562a739SJiri Olsa perf_evlist__init(&evlist->core); 54453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads); 551b85337dSArnaldo Carvalho de Melo fdarray__init(&evlist->pollfd, 64); 5635b9d88eSArnaldo Carvalho de Melo evlist->workload.pid = -1; 5754cc54deSWang Nan evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; 58361c99a6SArnaldo Carvalho de Melo } 59361c99a6SArnaldo Carvalho de Melo 600f98b11cSJiri Olsa struct evlist *evlist__new(void) 61ef1d1af2SArnaldo Carvalho de Melo { 6263503dbaSJiri Olsa struct evlist *evlist = zalloc(sizeof(*evlist)); 63ef1d1af2SArnaldo Carvalho de Melo 64ef1d1af2SArnaldo Carvalho de Melo if (evlist != NULL) 6552c86bcaSJiri Olsa evlist__init(evlist, NULL, NULL); 66ef1d1af2SArnaldo Carvalho de Melo 67361c99a6SArnaldo Carvalho de Melo return evlist; 68361c99a6SArnaldo Carvalho de Melo } 69361c99a6SArnaldo Carvalho de Melo 7063503dbaSJiri Olsa struct evlist *perf_evlist__new_default(void) 71b22d54b0SJiri Olsa { 720f98b11cSJiri Olsa struct evlist *evlist = evlist__new(); 73b22d54b0SJiri Olsa 74b22d54b0SJiri Olsa if (evlist && perf_evlist__add_default(evlist)) { 75c12995a5SJiri Olsa evlist__delete(evlist); 76b22d54b0SJiri Olsa evlist = NULL; 77b22d54b0SJiri Olsa } 78b22d54b0SJiri Olsa 79b22d54b0SJiri Olsa return evlist; 80b22d54b0SJiri Olsa } 81b22d54b0SJiri Olsa 8263503dbaSJiri Olsa struct evlist *perf_evlist__new_dummy(void) 835bae0250SArnaldo Carvalho de Melo { 840f98b11cSJiri Olsa struct evlist *evlist = evlist__new(); 855bae0250SArnaldo Carvalho de Melo 865bae0250SArnaldo Carvalho de Melo if (evlist && perf_evlist__add_dummy(evlist)) { 87c12995a5SJiri Olsa evlist__delete(evlist); 885bae0250SArnaldo Carvalho de Melo evlist = NULL; 895bae0250SArnaldo Carvalho de Melo } 905bae0250SArnaldo Carvalho de Melo 915bae0250SArnaldo Carvalho de Melo return evlist; 925bae0250SArnaldo Carvalho de Melo } 935bae0250SArnaldo Carvalho de Melo 9475562573SAdrian Hunter /** 9575562573SAdrian Hunter * perf_evlist__set_id_pos - set the positions of event ids. 9675562573SAdrian Hunter * @evlist: selected event list 9775562573SAdrian Hunter * 9875562573SAdrian Hunter * Events with compatible sample types all have the same id_pos 9975562573SAdrian Hunter * and is_pos. For convenience, put a copy on evlist. 10075562573SAdrian Hunter */ 10163503dbaSJiri Olsa void perf_evlist__set_id_pos(struct evlist *evlist) 10275562573SAdrian Hunter { 10332dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 10475562573SAdrian Hunter 10575562573SAdrian Hunter evlist->id_pos = first->id_pos; 10675562573SAdrian Hunter evlist->is_pos = first->is_pos; 10775562573SAdrian Hunter } 10875562573SAdrian Hunter 10963503dbaSJiri Olsa static void perf_evlist__update_id_pos(struct evlist *evlist) 110733cd2feSAdrian Hunter { 11132dcd021SJiri Olsa struct evsel *evsel; 112733cd2feSAdrian Hunter 113e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 114733cd2feSAdrian Hunter perf_evsel__calc_id_pos(evsel); 115733cd2feSAdrian Hunter 116733cd2feSAdrian Hunter perf_evlist__set_id_pos(evlist); 117733cd2feSAdrian Hunter } 118733cd2feSAdrian Hunter 11963503dbaSJiri Olsa static void perf_evlist__purge(struct evlist *evlist) 120361c99a6SArnaldo Carvalho de Melo { 12132dcd021SJiri Olsa struct evsel *pos, *n; 122361c99a6SArnaldo Carvalho de Melo 123e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_safe(evlist, n, pos) { 124b27c4eceSJiri Olsa list_del_init(&pos->core.node); 125d49e4695SArnaldo Carvalho de Melo pos->evlist = NULL; 1265eb2dd2aSJiri Olsa evsel__delete(pos); 127361c99a6SArnaldo Carvalho de Melo } 128361c99a6SArnaldo Carvalho de Melo 1296484d2f9SJiri Olsa evlist->core.nr_entries = 0; 130361c99a6SArnaldo Carvalho de Melo } 131361c99a6SArnaldo Carvalho de Melo 13263503dbaSJiri Olsa void perf_evlist__exit(struct evlist *evlist) 133ef1d1af2SArnaldo Carvalho de Melo { 13404662523SArnaldo Carvalho de Melo zfree(&evlist->mmap); 1350b72d69aSWang Nan zfree(&evlist->overwrite_mmap); 1361b85337dSArnaldo Carvalho de Melo fdarray__exit(&evlist->pollfd); 137ef1d1af2SArnaldo Carvalho de Melo } 138ef1d1af2SArnaldo Carvalho de Melo 139c12995a5SJiri Olsa void evlist__delete(struct evlist *evlist) 140361c99a6SArnaldo Carvalho de Melo { 1410b04b3dcSArnaldo Carvalho de Melo if (evlist == NULL) 1420b04b3dcSArnaldo Carvalho de Melo return; 1430b04b3dcSArnaldo Carvalho de Melo 144983874d1SArnaldo Carvalho de Melo perf_evlist__munmap(evlist); 145750b4edeSJiri Olsa evlist__close(evlist); 146f72f901dSJiri Olsa perf_cpu_map__put(evlist->core.cpus); 14703617c22SJiri Olsa perf_thread_map__put(evlist->core.threads); 148f72f901dSJiri Olsa evlist->core.cpus = NULL; 14903617c22SJiri Olsa evlist->core.threads = NULL; 150361c99a6SArnaldo Carvalho de Melo perf_evlist__purge(evlist); 151ef1d1af2SArnaldo Carvalho de Melo perf_evlist__exit(evlist); 152361c99a6SArnaldo Carvalho de Melo free(evlist); 153361c99a6SArnaldo Carvalho de Melo } 154361c99a6SArnaldo Carvalho de Melo 155a1cf3a75SJiri Olsa void evlist__add(struct evlist *evlist, struct evsel *entry) 156361c99a6SArnaldo Carvalho de Melo { 157d49e4695SArnaldo Carvalho de Melo entry->evlist = evlist; 1586484d2f9SJiri Olsa entry->idx = evlist->core.nr_entries; 15960b0896cSAdrian Hunter entry->tracking = !entry->idx; 160ef503831SArnaldo Carvalho de Melo 1616484d2f9SJiri Olsa perf_evlist__add(&evlist->core, &entry->core); 1626484d2f9SJiri Olsa 1636484d2f9SJiri Olsa if (evlist->core.nr_entries == 1) 16475562573SAdrian Hunter perf_evlist__set_id_pos(evlist); 165361c99a6SArnaldo Carvalho de Melo } 166361c99a6SArnaldo Carvalho de Melo 16716251027SJiri Olsa void evlist__remove(struct evlist *evlist, struct evsel *evsel) 1684768230aSAdrian Hunter { 1694768230aSAdrian Hunter evsel->evlist = NULL; 17052e22fb8SJiri Olsa perf_evlist__remove(&evlist->core, &evsel->core); 1714768230aSAdrian Hunter } 1724768230aSAdrian Hunter 17363503dbaSJiri Olsa void perf_evlist__splice_list_tail(struct evlist *evlist, 174f114d6efSAdrian Hunter struct list_head *list) 17550d08e47SArnaldo Carvalho de Melo { 17632dcd021SJiri Olsa struct evsel *evsel, *temp; 17775562573SAdrian Hunter 178e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry_safe(list, temp, evsel) { 179b27c4eceSJiri Olsa list_del_init(&evsel->core.node); 180a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 181f114d6efSAdrian Hunter } 18250d08e47SArnaldo Carvalho de Melo } 18350d08e47SArnaldo Carvalho de Melo 18463dab225SArnaldo Carvalho de Melo void __perf_evlist__set_leader(struct list_head *list) 18563dab225SArnaldo Carvalho de Melo { 18632dcd021SJiri Olsa struct evsel *evsel, *leader; 18763dab225SArnaldo Carvalho de Melo 188b27c4eceSJiri Olsa leader = list_entry(list->next, struct evsel, core.node); 189b27c4eceSJiri Olsa evsel = list_entry(list->prev, struct evsel, core.node); 19097f63e4aSNamhyung Kim 19197f63e4aSNamhyung Kim leader->nr_members = evsel->idx - leader->idx + 1; 19263dab225SArnaldo Carvalho de Melo 193e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry(list, evsel) { 19463dab225SArnaldo Carvalho de Melo evsel->leader = leader; 19563dab225SArnaldo Carvalho de Melo } 19663dab225SArnaldo Carvalho de Melo } 19763dab225SArnaldo Carvalho de Melo 19863503dbaSJiri Olsa void perf_evlist__set_leader(struct evlist *evlist) 1996a4bb04cSJiri Olsa { 2006484d2f9SJiri Olsa if (evlist->core.nr_entries) { 2016484d2f9SJiri Olsa evlist->nr_groups = evlist->core.nr_entries > 1 ? 1 : 0; 202ce9036a6SJiri Olsa __perf_evlist__set_leader(&evlist->core.entries); 2036a4bb04cSJiri Olsa } 20497f63e4aSNamhyung Kim } 2056a4bb04cSJiri Olsa 20663503dbaSJiri Olsa int __perf_evlist__add_default(struct evlist *evlist, bool precise) 207361c99a6SArnaldo Carvalho de Melo { 20832dcd021SJiri Olsa struct evsel *evsel = perf_evsel__new_cycles(precise); 209361c99a6SArnaldo Carvalho de Melo 210361c99a6SArnaldo Carvalho de Melo if (evsel == NULL) 2117c48dcfdSArnaldo Carvalho de Melo return -ENOMEM; 212361c99a6SArnaldo Carvalho de Melo 213a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 214361c99a6SArnaldo Carvalho de Melo return 0; 215361c99a6SArnaldo Carvalho de Melo } 2165c581041SArnaldo Carvalho de Melo 21763503dbaSJiri Olsa int perf_evlist__add_dummy(struct evlist *evlist) 2185bae0250SArnaldo Carvalho de Melo { 2195bae0250SArnaldo Carvalho de Melo struct perf_event_attr attr = { 2205bae0250SArnaldo Carvalho de Melo .type = PERF_TYPE_SOFTWARE, 2215bae0250SArnaldo Carvalho de Melo .config = PERF_COUNT_SW_DUMMY, 2225bae0250SArnaldo Carvalho de Melo .size = sizeof(attr), /* to capture ABI version */ 2235bae0250SArnaldo Carvalho de Melo }; 2246484d2f9SJiri Olsa struct evsel *evsel = perf_evsel__new_idx(&attr, evlist->core.nr_entries); 2255bae0250SArnaldo Carvalho de Melo 2265bae0250SArnaldo Carvalho de Melo if (evsel == NULL) 2275bae0250SArnaldo Carvalho de Melo return -ENOMEM; 2285bae0250SArnaldo Carvalho de Melo 229a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 2305bae0250SArnaldo Carvalho de Melo return 0; 2315bae0250SArnaldo Carvalho de Melo } 2325bae0250SArnaldo Carvalho de Melo 233a1cf3a75SJiri Olsa static int evlist__add_attrs(struct evlist *evlist, 23450d08e47SArnaldo Carvalho de Melo struct perf_event_attr *attrs, size_t nr_attrs) 23550d08e47SArnaldo Carvalho de Melo { 23632dcd021SJiri Olsa struct evsel *evsel, *n; 23750d08e47SArnaldo Carvalho de Melo LIST_HEAD(head); 23850d08e47SArnaldo Carvalho de Melo size_t i; 23950d08e47SArnaldo Carvalho de Melo 24050d08e47SArnaldo Carvalho de Melo for (i = 0; i < nr_attrs; i++) { 2416484d2f9SJiri Olsa evsel = perf_evsel__new_idx(attrs + i, evlist->core.nr_entries + i); 24250d08e47SArnaldo Carvalho de Melo if (evsel == NULL) 24350d08e47SArnaldo Carvalho de Melo goto out_delete_partial_list; 244b27c4eceSJiri Olsa list_add_tail(&evsel->core.node, &head); 24550d08e47SArnaldo Carvalho de Melo } 24650d08e47SArnaldo Carvalho de Melo 247f114d6efSAdrian Hunter perf_evlist__splice_list_tail(evlist, &head); 24850d08e47SArnaldo Carvalho de Melo 24950d08e47SArnaldo Carvalho de Melo return 0; 25050d08e47SArnaldo Carvalho de Melo 25150d08e47SArnaldo Carvalho de Melo out_delete_partial_list: 252e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry_safe(&head, n, evsel) 2535eb2dd2aSJiri Olsa evsel__delete(evsel); 25450d08e47SArnaldo Carvalho de Melo return -1; 25550d08e47SArnaldo Carvalho de Melo } 25650d08e47SArnaldo Carvalho de Melo 25763503dbaSJiri Olsa int __perf_evlist__add_default_attrs(struct evlist *evlist, 25879695e1bSArnaldo Carvalho de Melo struct perf_event_attr *attrs, size_t nr_attrs) 25979695e1bSArnaldo Carvalho de Melo { 26079695e1bSArnaldo Carvalho de Melo size_t i; 26179695e1bSArnaldo Carvalho de Melo 26279695e1bSArnaldo Carvalho de Melo for (i = 0; i < nr_attrs; i++) 26379695e1bSArnaldo Carvalho de Melo event_attr_init(attrs + i); 26479695e1bSArnaldo Carvalho de Melo 265a1cf3a75SJiri Olsa return evlist__add_attrs(evlist, attrs, nr_attrs); 26679695e1bSArnaldo Carvalho de Melo } 26779695e1bSArnaldo Carvalho de Melo 26832dcd021SJiri Olsa struct evsel * 26963503dbaSJiri Olsa perf_evlist__find_tracepoint_by_id(struct evlist *evlist, int id) 270ee29be62SArnaldo Carvalho de Melo { 27132dcd021SJiri Olsa struct evsel *evsel; 272ee29be62SArnaldo Carvalho de Melo 273e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 2741fc632ceSJiri Olsa if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT && 2751fc632ceSJiri Olsa (int)evsel->core.attr.config == id) 276ee29be62SArnaldo Carvalho de Melo return evsel; 277ee29be62SArnaldo Carvalho de Melo } 278ee29be62SArnaldo Carvalho de Melo 279ee29be62SArnaldo Carvalho de Melo return NULL; 280ee29be62SArnaldo Carvalho de Melo } 281ee29be62SArnaldo Carvalho de Melo 28232dcd021SJiri Olsa struct evsel * 28363503dbaSJiri Olsa perf_evlist__find_tracepoint_by_name(struct evlist *evlist, 284a2f2804aSDavid Ahern const char *name) 285a2f2804aSDavid Ahern { 28632dcd021SJiri Olsa struct evsel *evsel; 287a2f2804aSDavid Ahern 288e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 2891fc632ceSJiri Olsa if ((evsel->core.attr.type == PERF_TYPE_TRACEPOINT) && 290a2f2804aSDavid Ahern (strcmp(evsel->name, name) == 0)) 291a2f2804aSDavid Ahern return evsel; 292a2f2804aSDavid Ahern } 293a2f2804aSDavid Ahern 294a2f2804aSDavid Ahern return NULL; 295a2f2804aSDavid Ahern } 296a2f2804aSDavid Ahern 29763503dbaSJiri Olsa int perf_evlist__add_newtp(struct evlist *evlist, 29839876e7dSArnaldo Carvalho de Melo const char *sys, const char *name, void *handler) 29939876e7dSArnaldo Carvalho de Melo { 30032dcd021SJiri Olsa struct evsel *evsel = perf_evsel__newtp(sys, name); 30139876e7dSArnaldo Carvalho de Melo 3028dd2a131SJiri Olsa if (IS_ERR(evsel)) 30339876e7dSArnaldo Carvalho de Melo return -1; 30439876e7dSArnaldo Carvalho de Melo 305744a9719SArnaldo Carvalho de Melo evsel->handler = handler; 306a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 30739876e7dSArnaldo Carvalho de Melo return 0; 30839876e7dSArnaldo Carvalho de Melo } 30939876e7dSArnaldo Carvalho de Melo 31063503dbaSJiri Olsa static int perf_evlist__nr_threads(struct evlist *evlist, 31132dcd021SJiri Olsa struct evsel *evsel) 312bf8e8f4bSAdrian Hunter { 313bf8e8f4bSAdrian Hunter if (evsel->system_wide) 314bf8e8f4bSAdrian Hunter return 1; 315bf8e8f4bSAdrian Hunter else 31603617c22SJiri Olsa return thread_map__nr(evlist->core.threads); 317bf8e8f4bSAdrian Hunter } 318bf8e8f4bSAdrian Hunter 319e74676deSJiri Olsa void evlist__disable(struct evlist *evlist) 3204152ab37SArnaldo Carvalho de Melo { 32132dcd021SJiri Olsa struct evsel *pos; 3224152ab37SArnaldo Carvalho de Melo 323e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 324b7e8452bSArnaldo Carvalho de Melo if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->fd) 3253fe4430dSJiri Olsa continue; 3269a10bb22SJiri Olsa evsel__disable(pos); 3274152ab37SArnaldo Carvalho de Melo } 3282b56bcfbSArnaldo Carvalho de Melo 3292b56bcfbSArnaldo Carvalho de Melo evlist->enabled = false; 3304152ab37SArnaldo Carvalho de Melo } 3314152ab37SArnaldo Carvalho de Melo 3321c87f165SJiri Olsa void evlist__enable(struct evlist *evlist) 333764e16a3SDavid Ahern { 33432dcd021SJiri Olsa struct evsel *pos; 335764e16a3SDavid Ahern 336e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 337395c3070SAdrian Hunter if (!perf_evsel__is_group_leader(pos) || !pos->fd) 3383fe4430dSJiri Olsa continue; 339ec7f24efSJiri Olsa evsel__enable(pos); 340764e16a3SDavid Ahern } 3412b56bcfbSArnaldo Carvalho de Melo 3422b56bcfbSArnaldo Carvalho de Melo evlist->enabled = true; 3432b56bcfbSArnaldo Carvalho de Melo } 3442b56bcfbSArnaldo Carvalho de Melo 34563503dbaSJiri Olsa void perf_evlist__toggle_enable(struct evlist *evlist) 3462b56bcfbSArnaldo Carvalho de Melo { 347e74676deSJiri Olsa (evlist->enabled ? evlist__disable : evlist__enable)(evlist); 348764e16a3SDavid Ahern } 349764e16a3SDavid Ahern 35063503dbaSJiri Olsa static int perf_evlist__enable_event_cpu(struct evlist *evlist, 35132dcd021SJiri Olsa struct evsel *evsel, int cpu) 3521c65056cSAdrian Hunter { 35318ef15c6SArnaldo Carvalho de Melo int thread; 3541c65056cSAdrian Hunter int nr_threads = perf_evlist__nr_threads(evlist, evsel); 3551c65056cSAdrian Hunter 3561c65056cSAdrian Hunter if (!evsel->fd) 3571c65056cSAdrian Hunter return -EINVAL; 3581c65056cSAdrian Hunter 3591c65056cSAdrian Hunter for (thread = 0; thread < nr_threads; thread++) { 36018ef15c6SArnaldo Carvalho de Melo int err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 3611c65056cSAdrian Hunter if (err) 3621c65056cSAdrian Hunter return err; 3631c65056cSAdrian Hunter } 3641c65056cSAdrian Hunter return 0; 3651c65056cSAdrian Hunter } 3661c65056cSAdrian Hunter 36763503dbaSJiri Olsa static int perf_evlist__enable_event_thread(struct evlist *evlist, 36832dcd021SJiri Olsa struct evsel *evsel, 3691c65056cSAdrian Hunter int thread) 3701c65056cSAdrian Hunter { 37118ef15c6SArnaldo Carvalho de Melo int cpu; 372f72f901dSJiri Olsa int nr_cpus = cpu_map__nr(evlist->core.cpus); 3731c65056cSAdrian Hunter 3741c65056cSAdrian Hunter if (!evsel->fd) 3751c65056cSAdrian Hunter return -EINVAL; 3761c65056cSAdrian Hunter 3771c65056cSAdrian Hunter for (cpu = 0; cpu < nr_cpus; cpu++) { 37818ef15c6SArnaldo Carvalho de Melo int err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 3791c65056cSAdrian Hunter if (err) 3801c65056cSAdrian Hunter return err; 3811c65056cSAdrian Hunter } 3821c65056cSAdrian Hunter return 0; 3831c65056cSAdrian Hunter } 3841c65056cSAdrian Hunter 38563503dbaSJiri Olsa int perf_evlist__enable_event_idx(struct evlist *evlist, 38632dcd021SJiri Olsa struct evsel *evsel, int idx) 3871c65056cSAdrian Hunter { 388f72f901dSJiri Olsa bool per_cpu_mmaps = !cpu_map__empty(evlist->core.cpus); 3891c65056cSAdrian Hunter 3901c65056cSAdrian Hunter if (per_cpu_mmaps) 3911c65056cSAdrian Hunter return perf_evlist__enable_event_cpu(evlist, evsel, idx); 3921c65056cSAdrian Hunter else 3931c65056cSAdrian Hunter return perf_evlist__enable_event_thread(evlist, evsel, idx); 3941c65056cSAdrian Hunter } 3951c65056cSAdrian Hunter 39663503dbaSJiri Olsa int perf_evlist__alloc_pollfd(struct evlist *evlist) 3975c581041SArnaldo Carvalho de Melo { 398f72f901dSJiri Olsa int nr_cpus = cpu_map__nr(evlist->core.cpus); 39903617c22SJiri Olsa int nr_threads = thread_map__nr(evlist->core.threads); 400bf8e8f4bSAdrian Hunter int nfds = 0; 40132dcd021SJiri Olsa struct evsel *evsel; 402bf8e8f4bSAdrian Hunter 403e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 404bf8e8f4bSAdrian Hunter if (evsel->system_wide) 405bf8e8f4bSAdrian Hunter nfds += nr_cpus; 406bf8e8f4bSAdrian Hunter else 407bf8e8f4bSAdrian Hunter nfds += nr_cpus * nr_threads; 408bf8e8f4bSAdrian Hunter } 409bf8e8f4bSAdrian Hunter 4101b85337dSArnaldo Carvalho de Melo if (fdarray__available_entries(&evlist->pollfd) < nfds && 4111b85337dSArnaldo Carvalho de Melo fdarray__grow(&evlist->pollfd, nfds) < 0) 412ad6765ddSArnaldo Carvalho de Melo return -ENOMEM; 413ad6765ddSArnaldo Carvalho de Melo 414ad6765ddSArnaldo Carvalho de Melo return 0; 4155c581041SArnaldo Carvalho de Melo } 41670082dd9SArnaldo Carvalho de Melo 41763503dbaSJiri Olsa static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, 4184876075bSWang Nan struct perf_mmap *map, short revent) 419e4b356b5SArnaldo Carvalho de Melo { 420f3058a1cSWang Nan int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); 421e4b356b5SArnaldo Carvalho de Melo /* 422e4b356b5SArnaldo Carvalho de Melo * Save the idx so that when we filter out fds POLLHUP'ed we can 423e4b356b5SArnaldo Carvalho de Melo * close the associated evlist->mmap[] entry. 424e4b356b5SArnaldo Carvalho de Melo */ 425e4b356b5SArnaldo Carvalho de Melo if (pos >= 0) { 4264876075bSWang Nan evlist->pollfd.priv[pos].ptr = map; 427e4b356b5SArnaldo Carvalho de Melo 428e4b356b5SArnaldo Carvalho de Melo fcntl(fd, F_SETFL, O_NONBLOCK); 429e4b356b5SArnaldo Carvalho de Melo } 430e4b356b5SArnaldo Carvalho de Melo 431e4b356b5SArnaldo Carvalho de Melo return pos; 432e4b356b5SArnaldo Carvalho de Melo } 433e4b356b5SArnaldo Carvalho de Melo 43463503dbaSJiri Olsa int perf_evlist__add_pollfd(struct evlist *evlist, int fd) 43570082dd9SArnaldo Carvalho de Melo { 4364876075bSWang Nan return __perf_evlist__add_pollfd(evlist, fd, NULL, POLLIN); 437e4b356b5SArnaldo Carvalho de Melo } 4381b85337dSArnaldo Carvalho de Melo 439258e4bfcSWang Nan static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, 440258e4bfcSWang Nan void *arg __maybe_unused) 441e4b356b5SArnaldo Carvalho de Melo { 4424876075bSWang Nan struct perf_mmap *map = fda->priv[fd].ptr; 443e4b356b5SArnaldo Carvalho de Melo 4444876075bSWang Nan if (map) 4454876075bSWang Nan perf_mmap__put(map); 44670082dd9SArnaldo Carvalho de Melo } 44770db7533SArnaldo Carvalho de Melo 44863503dbaSJiri Olsa int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) 4491ddec7f0SArnaldo Carvalho de Melo { 450e4b356b5SArnaldo Carvalho de Melo return fdarray__filter(&evlist->pollfd, revents_and_mask, 451258e4bfcSWang Nan perf_evlist__munmap_filtered, NULL); 4521ddec7f0SArnaldo Carvalho de Melo } 4531ddec7f0SArnaldo Carvalho de Melo 45463503dbaSJiri Olsa int perf_evlist__poll(struct evlist *evlist, int timeout) 455f66a889dSArnaldo Carvalho de Melo { 4561b85337dSArnaldo Carvalho de Melo return fdarray__poll(&evlist->pollfd, timeout); 457f66a889dSArnaldo Carvalho de Melo } 458f66a889dSArnaldo Carvalho de Melo 45963503dbaSJiri Olsa static void perf_evlist__id_hash(struct evlist *evlist, 46032dcd021SJiri Olsa struct evsel *evsel, 4613d3b5e95SArnaldo Carvalho de Melo int cpu, int thread, u64 id) 4623d3b5e95SArnaldo Carvalho de Melo { 4633d3b5e95SArnaldo Carvalho de Melo int hash; 4643d3b5e95SArnaldo Carvalho de Melo struct perf_sample_id *sid = SID(evsel, cpu, thread); 4653d3b5e95SArnaldo Carvalho de Melo 4663d3b5e95SArnaldo Carvalho de Melo sid->id = id; 4673d3b5e95SArnaldo Carvalho de Melo sid->evsel = evsel; 4683d3b5e95SArnaldo Carvalho de Melo hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); 4693d3b5e95SArnaldo Carvalho de Melo hlist_add_head(&sid->node, &evlist->heads[hash]); 4703d3b5e95SArnaldo Carvalho de Melo } 4713d3b5e95SArnaldo Carvalho de Melo 47263503dbaSJiri Olsa void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, 473a91e5431SArnaldo Carvalho de Melo int cpu, int thread, u64 id) 474a91e5431SArnaldo Carvalho de Melo { 475a91e5431SArnaldo Carvalho de Melo perf_evlist__id_hash(evlist, evsel, cpu, thread, id); 476a91e5431SArnaldo Carvalho de Melo evsel->id[evsel->ids++] = id; 477a91e5431SArnaldo Carvalho de Melo } 478a91e5431SArnaldo Carvalho de Melo 47963503dbaSJiri Olsa int perf_evlist__id_add_fd(struct evlist *evlist, 48032dcd021SJiri Olsa struct evsel *evsel, 481f8a95309SArnaldo Carvalho de Melo int cpu, int thread, int fd) 482f8a95309SArnaldo Carvalho de Melo { 483f8a95309SArnaldo Carvalho de Melo u64 read_data[4] = { 0, }; 4843d3b5e95SArnaldo Carvalho de Melo int id_idx = 1; /* The first entry is the counter value */ 485e2b5abe0SJiri Olsa u64 id; 486e2b5abe0SJiri Olsa int ret; 487e2b5abe0SJiri Olsa 488e2b5abe0SJiri Olsa ret = ioctl(fd, PERF_EVENT_IOC_ID, &id); 489e2b5abe0SJiri Olsa if (!ret) 490e2b5abe0SJiri Olsa goto add; 491e2b5abe0SJiri Olsa 492e2b5abe0SJiri Olsa if (errno != ENOTTY) 493e2b5abe0SJiri Olsa return -1; 494e2b5abe0SJiri Olsa 495e2b5abe0SJiri Olsa /* Legacy way to get event id.. All hail to old kernels! */ 496f8a95309SArnaldo Carvalho de Melo 497c4861afeSJiri Olsa /* 498c4861afeSJiri Olsa * This way does not work with group format read, so bail 499c4861afeSJiri Olsa * out in that case. 500c4861afeSJiri Olsa */ 501c4861afeSJiri Olsa if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) 502c4861afeSJiri Olsa return -1; 503c4861afeSJiri Olsa 5041fc632ceSJiri Olsa if (!(evsel->core.attr.read_format & PERF_FORMAT_ID) || 505f8a95309SArnaldo Carvalho de Melo read(fd, &read_data, sizeof(read_data)) == -1) 506f8a95309SArnaldo Carvalho de Melo return -1; 507f8a95309SArnaldo Carvalho de Melo 5081fc632ceSJiri Olsa if (evsel->core.attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 509f8a95309SArnaldo Carvalho de Melo ++id_idx; 5101fc632ceSJiri Olsa if (evsel->core.attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 511f8a95309SArnaldo Carvalho de Melo ++id_idx; 512f8a95309SArnaldo Carvalho de Melo 513e2b5abe0SJiri Olsa id = read_data[id_idx]; 514e2b5abe0SJiri Olsa 515e2b5abe0SJiri Olsa add: 516e2b5abe0SJiri Olsa perf_evlist__id_add(evlist, evsel, cpu, thread, id); 517f8a95309SArnaldo Carvalho de Melo return 0; 518f8a95309SArnaldo Carvalho de Melo } 519f8a95309SArnaldo Carvalho de Melo 52063503dbaSJiri Olsa static void perf_evlist__set_sid_idx(struct evlist *evlist, 52132dcd021SJiri Olsa struct evsel *evsel, int idx, int cpu, 5223c659eedSAdrian Hunter int thread) 5233c659eedSAdrian Hunter { 5243c659eedSAdrian Hunter struct perf_sample_id *sid = SID(evsel, cpu, thread); 5253c659eedSAdrian Hunter sid->idx = idx; 526f72f901dSJiri Olsa if (evlist->core.cpus && cpu >= 0) 527f72f901dSJiri Olsa sid->cpu = evlist->core.cpus->map[cpu]; 5283c659eedSAdrian Hunter else 5293c659eedSAdrian Hunter sid->cpu = -1; 53003617c22SJiri Olsa if (!evsel->system_wide && evlist->core.threads && thread >= 0) 53103617c22SJiri Olsa sid->tid = thread_map__pid(evlist->core.threads, thread); 5323c659eedSAdrian Hunter else 5333c659eedSAdrian Hunter sid->tid = -1; 5343c659eedSAdrian Hunter } 5353c659eedSAdrian Hunter 53663503dbaSJiri Olsa struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id) 53770db7533SArnaldo Carvalho de Melo { 53870db7533SArnaldo Carvalho de Melo struct hlist_head *head; 53970db7533SArnaldo Carvalho de Melo struct perf_sample_id *sid; 54070db7533SArnaldo Carvalho de Melo int hash; 54170db7533SArnaldo Carvalho de Melo 54270db7533SArnaldo Carvalho de Melo hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 54370db7533SArnaldo Carvalho de Melo head = &evlist->heads[hash]; 54470db7533SArnaldo Carvalho de Melo 545b67bfe0dSSasha Levin hlist_for_each_entry(sid, head, node) 54670db7533SArnaldo Carvalho de Melo if (sid->id == id) 547932a3594SJiri Olsa return sid; 548932a3594SJiri Olsa 549932a3594SJiri Olsa return NULL; 550932a3594SJiri Olsa } 551932a3594SJiri Olsa 55263503dbaSJiri Olsa struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) 553932a3594SJiri Olsa { 554932a3594SJiri Olsa struct perf_sample_id *sid; 555932a3594SJiri Olsa 5566484d2f9SJiri Olsa if (evlist->core.nr_entries == 1 || !id) 557932a3594SJiri Olsa return perf_evlist__first(evlist); 558932a3594SJiri Olsa 559932a3594SJiri Olsa sid = perf_evlist__id2sid(evlist, id); 560932a3594SJiri Olsa if (sid) 56170db7533SArnaldo Carvalho de Melo return sid->evsel; 56230e68bccSNamhyung Kim 56330e68bccSNamhyung Kim if (!perf_evlist__sample_id_all(evlist)) 5640c21f736SArnaldo Carvalho de Melo return perf_evlist__first(evlist); 56530e68bccSNamhyung Kim 56670db7533SArnaldo Carvalho de Melo return NULL; 56770db7533SArnaldo Carvalho de Melo } 56804391debSArnaldo Carvalho de Melo 56963503dbaSJiri Olsa struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, 570dddcf6abSAdrian Hunter u64 id) 571dddcf6abSAdrian Hunter { 572dddcf6abSAdrian Hunter struct perf_sample_id *sid; 573dddcf6abSAdrian Hunter 574dddcf6abSAdrian Hunter if (!id) 575dddcf6abSAdrian Hunter return NULL; 576dddcf6abSAdrian Hunter 577dddcf6abSAdrian Hunter sid = perf_evlist__id2sid(evlist, id); 578dddcf6abSAdrian Hunter if (sid) 579dddcf6abSAdrian Hunter return sid->evsel; 580dddcf6abSAdrian Hunter 581dddcf6abSAdrian Hunter return NULL; 582dddcf6abSAdrian Hunter } 583dddcf6abSAdrian Hunter 58463503dbaSJiri Olsa static int perf_evlist__event2id(struct evlist *evlist, 58575562573SAdrian Hunter union perf_event *event, u64 *id) 58675562573SAdrian Hunter { 58775562573SAdrian Hunter const u64 *array = event->sample.array; 58875562573SAdrian Hunter ssize_t n; 58975562573SAdrian Hunter 59075562573SAdrian Hunter n = (event->header.size - sizeof(event->header)) >> 3; 59175562573SAdrian Hunter 59275562573SAdrian Hunter if (event->header.type == PERF_RECORD_SAMPLE) { 59375562573SAdrian Hunter if (evlist->id_pos >= n) 59475562573SAdrian Hunter return -1; 59575562573SAdrian Hunter *id = array[evlist->id_pos]; 59675562573SAdrian Hunter } else { 59775562573SAdrian Hunter if (evlist->is_pos > n) 59875562573SAdrian Hunter return -1; 59975562573SAdrian Hunter n -= evlist->is_pos; 60075562573SAdrian Hunter *id = array[n]; 60175562573SAdrian Hunter } 60275562573SAdrian Hunter return 0; 60375562573SAdrian Hunter } 60475562573SAdrian Hunter 60563503dbaSJiri Olsa struct evsel *perf_evlist__event2evsel(struct evlist *evlist, 60675562573SAdrian Hunter union perf_event *event) 60775562573SAdrian Hunter { 60832dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 60975562573SAdrian Hunter struct hlist_head *head; 61075562573SAdrian Hunter struct perf_sample_id *sid; 61175562573SAdrian Hunter int hash; 61275562573SAdrian Hunter u64 id; 61375562573SAdrian Hunter 6146484d2f9SJiri Olsa if (evlist->core.nr_entries == 1) 61598be6966SAdrian Hunter return first; 61698be6966SAdrian Hunter 6171fc632ceSJiri Olsa if (!first->core.attr.sample_id_all && 61898be6966SAdrian Hunter event->header.type != PERF_RECORD_SAMPLE) 61998be6966SAdrian Hunter return first; 62075562573SAdrian Hunter 62175562573SAdrian Hunter if (perf_evlist__event2id(evlist, event, &id)) 62275562573SAdrian Hunter return NULL; 62375562573SAdrian Hunter 62475562573SAdrian Hunter /* Synthesized events have an id of zero */ 62575562573SAdrian Hunter if (!id) 62698be6966SAdrian Hunter return first; 62775562573SAdrian Hunter 62875562573SAdrian Hunter hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 62975562573SAdrian Hunter head = &evlist->heads[hash]; 63075562573SAdrian Hunter 63175562573SAdrian Hunter hlist_for_each_entry(sid, head, node) { 63275562573SAdrian Hunter if (sid->id == id) 63375562573SAdrian Hunter return sid->evsel; 63475562573SAdrian Hunter } 63575562573SAdrian Hunter return NULL; 63675562573SAdrian Hunter } 63775562573SAdrian Hunter 63863503dbaSJiri Olsa static int perf_evlist__set_paused(struct evlist *evlist, bool value) 63965aea233SWang Nan { 64065aea233SWang Nan int i; 64165aea233SWang Nan 6420b72d69aSWang Nan if (!evlist->overwrite_mmap) 643078c3386SWang Nan return 0; 644078c3386SWang Nan 64565aea233SWang Nan for (i = 0; i < evlist->nr_mmaps; i++) { 6460b72d69aSWang Nan int fd = evlist->overwrite_mmap[i].fd; 64765aea233SWang Nan int err; 64865aea233SWang Nan 64965aea233SWang Nan if (fd < 0) 65065aea233SWang Nan continue; 65165aea233SWang Nan err = ioctl(fd, PERF_EVENT_IOC_PAUSE_OUTPUT, value ? 1 : 0); 65265aea233SWang Nan if (err) 65365aea233SWang Nan return err; 65465aea233SWang Nan } 65565aea233SWang Nan return 0; 65665aea233SWang Nan } 65765aea233SWang Nan 65863503dbaSJiri Olsa static int perf_evlist__pause(struct evlist *evlist) 65965aea233SWang Nan { 66065aea233SWang Nan return perf_evlist__set_paused(evlist, true); 66165aea233SWang Nan } 66265aea233SWang Nan 66363503dbaSJiri Olsa static int perf_evlist__resume(struct evlist *evlist) 66465aea233SWang Nan { 66565aea233SWang Nan return perf_evlist__set_paused(evlist, false); 66665aea233SWang Nan } 66765aea233SWang Nan 66863503dbaSJiri Olsa static void perf_evlist__munmap_nofree(struct evlist *evlist) 669f8a95309SArnaldo Carvalho de Melo { 670aece948fSArnaldo Carvalho de Melo int i; 671f8a95309SArnaldo Carvalho de Melo 672b2cb615dSWang Nan if (evlist->mmap) 67393edcbd9SAdrian Hunter for (i = 0; i < evlist->nr_mmaps; i++) 674a1f72618SWang Nan perf_mmap__munmap(&evlist->mmap[i]); 675b2cb615dSWang Nan 6760b72d69aSWang Nan if (evlist->overwrite_mmap) 677b2cb615dSWang Nan for (i = 0; i < evlist->nr_mmaps; i++) 6780b72d69aSWang Nan perf_mmap__munmap(&evlist->overwrite_mmap[i]); 679a1f72618SWang Nan } 680aece948fSArnaldo Carvalho de Melo 68163503dbaSJiri Olsa void perf_evlist__munmap(struct evlist *evlist) 682a1f72618SWang Nan { 683a1f72618SWang Nan perf_evlist__munmap_nofree(evlist); 68404662523SArnaldo Carvalho de Melo zfree(&evlist->mmap); 6850b72d69aSWang Nan zfree(&evlist->overwrite_mmap); 686f8a95309SArnaldo Carvalho de Melo } 687f8a95309SArnaldo Carvalho de Melo 68863503dbaSJiri Olsa static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, 6892c5f6d87SKan Liang bool overwrite) 690f8a95309SArnaldo Carvalho de Melo { 691d4c6fb36SWang Nan int i; 6928db6d6b1SWang Nan struct perf_mmap *map; 693d4c6fb36SWang Nan 694f72f901dSJiri Olsa evlist->nr_mmaps = cpu_map__nr(evlist->core.cpus); 695f72f901dSJiri Olsa if (cpu_map__empty(evlist->core.cpus)) 69603617c22SJiri Olsa evlist->nr_mmaps = thread_map__nr(evlist->core.threads); 6978db6d6b1SWang Nan map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 6988db6d6b1SWang Nan if (!map) 6998db6d6b1SWang Nan return NULL; 700946ae1d4SWang Nan 7014738ca30SArnaldo Carvalho de Melo for (i = 0; i < evlist->nr_mmaps; i++) { 7028db6d6b1SWang Nan map[i].fd = -1; 7032c5f6d87SKan Liang map[i].overwrite = overwrite; 7044738ca30SArnaldo Carvalho de Melo /* 7054738ca30SArnaldo Carvalho de Melo * When the perf_mmap() call is made we grab one refcount, plus 7066afad54dSKan Liang * one extra to let perf_mmap__consume() get the last 7074738ca30SArnaldo Carvalho de Melo * events after all real references (perf_mmap__get()) are 7084738ca30SArnaldo Carvalho de Melo * dropped. 7094738ca30SArnaldo Carvalho de Melo * 7104738ca30SArnaldo Carvalho de Melo * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and 7114738ca30SArnaldo Carvalho de Melo * thus does perf_mmap__get() on it. 7124738ca30SArnaldo Carvalho de Melo */ 7134738ca30SArnaldo Carvalho de Melo refcount_set(&map[i].refcnt, 0); 7144738ca30SArnaldo Carvalho de Melo } 7158db6d6b1SWang Nan return map; 716f8a95309SArnaldo Carvalho de Melo } 717f8a95309SArnaldo Carvalho de Melo 718f3058a1cSWang Nan static bool 71963503dbaSJiri Olsa perf_evlist__should_poll(struct evlist *evlist __maybe_unused, 72032dcd021SJiri Olsa struct evsel *evsel) 721f3058a1cSWang Nan { 7221fc632ceSJiri Olsa if (evsel->core.attr.write_backward) 723f3058a1cSWang Nan return false; 724f3058a1cSWang Nan return true; 725f3058a1cSWang Nan } 726f3058a1cSWang Nan 72763503dbaSJiri Olsa static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, 7289f21b815SMark Rutland struct mmap_params *mp, int cpu_idx, 7290b72d69aSWang Nan int thread, int *_output, int *_output_overwrite) 730aece948fSArnaldo Carvalho de Melo { 73132dcd021SJiri Olsa struct evsel *evsel; 732f3058a1cSWang Nan int revent; 733f72f901dSJiri Olsa int evlist_cpu = cpu_map__cpu(evlist->core.cpus, cpu_idx); 73404e21314SAdrian Hunter 735e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 736078c3386SWang Nan struct perf_mmap *maps = evlist->mmap; 737078c3386SWang Nan int *output = _output; 738bf8e8f4bSAdrian Hunter int fd; 7399f21b815SMark Rutland int cpu; 740bf8e8f4bSAdrian Hunter 74171f566a3SWang Nan mp->prot = PROT_READ | PROT_WRITE; 7421fc632ceSJiri Olsa if (evsel->core.attr.write_backward) { 7430b72d69aSWang Nan output = _output_overwrite; 7440b72d69aSWang Nan maps = evlist->overwrite_mmap; 745078c3386SWang Nan 746078c3386SWang Nan if (!maps) { 7472c5f6d87SKan Liang maps = perf_evlist__alloc_mmap(evlist, true); 748078c3386SWang Nan if (!maps) 749078c3386SWang Nan return -1; 7500b72d69aSWang Nan evlist->overwrite_mmap = maps; 75154cc54deSWang Nan if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY) 75254cc54deSWang Nan perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); 753078c3386SWang Nan } 75471f566a3SWang Nan mp->prot &= ~PROT_WRITE; 755078c3386SWang Nan } 756f3058a1cSWang Nan 757bf8e8f4bSAdrian Hunter if (evsel->system_wide && thread) 758bf8e8f4bSAdrian Hunter continue; 759bf8e8f4bSAdrian Hunter 760d400bd3aSJiri Olsa cpu = cpu_map__idx(evsel->core.cpus, evlist_cpu); 7619f21b815SMark Rutland if (cpu == -1) 7629f21b815SMark Rutland continue; 7639f21b815SMark Rutland 764bf8e8f4bSAdrian Hunter fd = FD(evsel, cpu, thread); 76504e21314SAdrian Hunter 76604e21314SAdrian Hunter if (*output == -1) { 76704e21314SAdrian Hunter *output = fd; 768078c3386SWang Nan 76931fb4c0dSJiri Olsa if (perf_mmap__mmap(&maps[idx], mp, *output, evlist_cpu) < 0) 77004e21314SAdrian Hunter return -1; 77104e21314SAdrian Hunter } else { 77204e21314SAdrian Hunter if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) 77304e21314SAdrian Hunter return -1; 77482396986SArnaldo Carvalho de Melo 775078c3386SWang Nan perf_mmap__get(&maps[idx]); 77604e21314SAdrian Hunter } 77704e21314SAdrian Hunter 778f3058a1cSWang Nan revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0; 779f3058a1cSWang Nan 780f90d194aSAdrian Hunter /* 781f90d194aSAdrian Hunter * The system_wide flag causes a selected event to be opened 782f90d194aSAdrian Hunter * always without a pid. Consequently it will never get a 783f90d194aSAdrian Hunter * POLLHUP, but it is used for tracking in combination with 784f90d194aSAdrian Hunter * other events, so it should not need to be polled anyway. 785f90d194aSAdrian Hunter * Therefore don't add it for polling. 786f90d194aSAdrian Hunter */ 787f90d194aSAdrian Hunter if (!evsel->system_wide && 788078c3386SWang Nan __perf_evlist__add_pollfd(evlist, fd, &maps[idx], revent) < 0) { 789078c3386SWang Nan perf_mmap__put(&maps[idx]); 790ad6765ddSArnaldo Carvalho de Melo return -1; 79182396986SArnaldo Carvalho de Melo } 792033fa713SArnaldo Carvalho de Melo 7931fc632ceSJiri Olsa if (evsel->core.attr.read_format & PERF_FORMAT_ID) { 7943c659eedSAdrian Hunter if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, 7953c659eedSAdrian Hunter fd) < 0) 79604e21314SAdrian Hunter return -1; 7973c659eedSAdrian Hunter perf_evlist__set_sid_idx(evlist, evsel, idx, cpu, 7983c659eedSAdrian Hunter thread); 7993c659eedSAdrian Hunter } 80004e21314SAdrian Hunter } 80104e21314SAdrian Hunter 80204e21314SAdrian Hunter return 0; 80304e21314SAdrian Hunter } 80404e21314SAdrian Hunter 80563503dbaSJiri Olsa static int perf_evlist__mmap_per_cpu(struct evlist *evlist, 806a8a8f3ebSAdrian Hunter struct mmap_params *mp) 80704e21314SAdrian Hunter { 808aece948fSArnaldo Carvalho de Melo int cpu, thread; 809f72f901dSJiri Olsa int nr_cpus = cpu_map__nr(evlist->core.cpus); 81003617c22SJiri Olsa int nr_threads = thread_map__nr(evlist->core.threads); 811aece948fSArnaldo Carvalho de Melo 812e3e1a54fSAdrian Hunter pr_debug2("perf event ring buffer mmapped per cpu\n"); 813b3a319d5SNamhyung Kim for (cpu = 0; cpu < nr_cpus; cpu++) { 814aece948fSArnaldo Carvalho de Melo int output = -1; 8150b72d69aSWang Nan int output_overwrite = -1; 816aece948fSArnaldo Carvalho de Melo 817718c602dSAdrian Hunter auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, cpu, 818718c602dSAdrian Hunter true); 819718c602dSAdrian Hunter 820b3a319d5SNamhyung Kim for (thread = 0; thread < nr_threads; thread++) { 821a8a8f3ebSAdrian Hunter if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu, 8220b72d69aSWang Nan thread, &output, &output_overwrite)) 823aece948fSArnaldo Carvalho de Melo goto out_unmap; 824aece948fSArnaldo Carvalho de Melo } 825aece948fSArnaldo Carvalho de Melo } 826aece948fSArnaldo Carvalho de Melo 827aece948fSArnaldo Carvalho de Melo return 0; 828aece948fSArnaldo Carvalho de Melo 829aece948fSArnaldo Carvalho de Melo out_unmap: 830a1f72618SWang Nan perf_evlist__munmap_nofree(evlist); 831aece948fSArnaldo Carvalho de Melo return -1; 832aece948fSArnaldo Carvalho de Melo } 833aece948fSArnaldo Carvalho de Melo 83463503dbaSJiri Olsa static int perf_evlist__mmap_per_thread(struct evlist *evlist, 835a8a8f3ebSAdrian Hunter struct mmap_params *mp) 836aece948fSArnaldo Carvalho de Melo { 837aece948fSArnaldo Carvalho de Melo int thread; 83803617c22SJiri Olsa int nr_threads = thread_map__nr(evlist->core.threads); 839aece948fSArnaldo Carvalho de Melo 840e3e1a54fSAdrian Hunter pr_debug2("perf event ring buffer mmapped per thread\n"); 841b3a319d5SNamhyung Kim for (thread = 0; thread < nr_threads; thread++) { 842aece948fSArnaldo Carvalho de Melo int output = -1; 8430b72d69aSWang Nan int output_overwrite = -1; 844aece948fSArnaldo Carvalho de Melo 845718c602dSAdrian Hunter auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, thread, 846718c602dSAdrian Hunter false); 847718c602dSAdrian Hunter 848a8a8f3ebSAdrian Hunter if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread, 8490b72d69aSWang Nan &output, &output_overwrite)) 850aece948fSArnaldo Carvalho de Melo goto out_unmap; 851aece948fSArnaldo Carvalho de Melo } 852aece948fSArnaldo Carvalho de Melo 853aece948fSArnaldo Carvalho de Melo return 0; 854aece948fSArnaldo Carvalho de Melo 855aece948fSArnaldo Carvalho de Melo out_unmap: 856a1f72618SWang Nan perf_evlist__munmap_nofree(evlist); 857aece948fSArnaldo Carvalho de Melo return -1; 858aece948fSArnaldo Carvalho de Melo } 859aece948fSArnaldo Carvalho de Melo 860f5e7150cSArnaldo Carvalho de Melo unsigned long perf_event_mlock_kb_in_pages(void) 861994a1f78SJiri Olsa { 862f5e7150cSArnaldo Carvalho de Melo unsigned long pages; 8638185e881SArnaldo Carvalho de Melo int max; 8648185e881SArnaldo Carvalho de Melo 8658185e881SArnaldo Carvalho de Melo if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { 8668185e881SArnaldo Carvalho de Melo /* 8678185e881SArnaldo Carvalho de Melo * Pick a once upon a time good value, i.e. things look 8688185e881SArnaldo Carvalho de Melo * strange since we can't read a sysctl value, but lets not 8698185e881SArnaldo Carvalho de Melo * die yet... 8708185e881SArnaldo Carvalho de Melo */ 8718185e881SArnaldo Carvalho de Melo max = 512; 8728185e881SArnaldo Carvalho de Melo } else { 8738185e881SArnaldo Carvalho de Melo max -= (page_size / 1024); 8748185e881SArnaldo Carvalho de Melo } 8758185e881SArnaldo Carvalho de Melo 8768185e881SArnaldo Carvalho de Melo pages = (max * 1024) / page_size; 8771be300f4SArnaldo Carvalho de Melo if (!is_power_of_2(pages)) 8781be300f4SArnaldo Carvalho de Melo pages = rounddown_pow_of_two(pages); 879f5e7150cSArnaldo Carvalho de Melo 880f5e7150cSArnaldo Carvalho de Melo return pages; 881f5e7150cSArnaldo Carvalho de Melo } 882f5e7150cSArnaldo Carvalho de Melo 8830c582449SJiri Olsa size_t perf_evlist__mmap_size(unsigned long pages) 884f5e7150cSArnaldo Carvalho de Melo { 885f5e7150cSArnaldo Carvalho de Melo if (pages == UINT_MAX) 886f5e7150cSArnaldo Carvalho de Melo pages = perf_event_mlock_kb_in_pages(); 887f5e7150cSArnaldo Carvalho de Melo else if (!is_power_of_2(pages)) 888994a1f78SJiri Olsa return 0; 889994a1f78SJiri Olsa 890994a1f78SJiri Olsa return (pages + 1) * page_size; 891994a1f78SJiri Olsa } 892994a1f78SJiri Olsa 89333c2dcfdSDavid Ahern static long parse_pages_arg(const char *str, unsigned long min, 89433c2dcfdSDavid Ahern unsigned long max) 895994a1f78SJiri Olsa { 8962fbe4abeSAdrian Hunter unsigned long pages, val; 89727050f53SJiri Olsa static struct parse_tag tags[] = { 89827050f53SJiri Olsa { .tag = 'B', .mult = 1 }, 89927050f53SJiri Olsa { .tag = 'K', .mult = 1 << 10 }, 90027050f53SJiri Olsa { .tag = 'M', .mult = 1 << 20 }, 90127050f53SJiri Olsa { .tag = 'G', .mult = 1 << 30 }, 90227050f53SJiri Olsa { .tag = 0 }, 90327050f53SJiri Olsa }; 904994a1f78SJiri Olsa 9058973504bSDavid Ahern if (str == NULL) 90633c2dcfdSDavid Ahern return -EINVAL; 9078973504bSDavid Ahern 90827050f53SJiri Olsa val = parse_tag_value(str, tags); 9092fbe4abeSAdrian Hunter if (val != (unsigned long) -1) { 91027050f53SJiri Olsa /* we got file size value */ 91127050f53SJiri Olsa pages = PERF_ALIGN(val, page_size) / page_size; 91227050f53SJiri Olsa } else { 91327050f53SJiri Olsa /* we got pages count value */ 91427050f53SJiri Olsa char *eptr; 915994a1f78SJiri Olsa pages = strtoul(str, &eptr, 10); 91633c2dcfdSDavid Ahern if (*eptr != '\0') 91733c2dcfdSDavid Ahern return -EINVAL; 91827050f53SJiri Olsa } 919994a1f78SJiri Olsa 9202bcab6c1SAdrian Hunter if (pages == 0 && min == 0) { 92133c2dcfdSDavid Ahern /* leave number of pages at 0 */ 9221dbfa938SAdrian Hunter } else if (!is_power_of_2(pages)) { 9239808143bSJiri Olsa char buf[100]; 9249808143bSJiri Olsa 92533c2dcfdSDavid Ahern /* round pages up to next power of 2 */ 92691529834SArnaldo Carvalho de Melo pages = roundup_pow_of_two(pages); 9271dbfa938SAdrian Hunter if (!pages) 9281dbfa938SAdrian Hunter return -EINVAL; 9299808143bSJiri Olsa 9309808143bSJiri Olsa unit_number__scnprintf(buf, sizeof(buf), pages * page_size); 9319808143bSJiri Olsa pr_info("rounding mmap pages size to %s (%lu pages)\n", 9329808143bSJiri Olsa buf, pages); 9332fbe4abeSAdrian Hunter } 9342fbe4abeSAdrian Hunter 93533c2dcfdSDavid Ahern if (pages > max) 93633c2dcfdSDavid Ahern return -EINVAL; 93733c2dcfdSDavid Ahern 93833c2dcfdSDavid Ahern return pages; 93933c2dcfdSDavid Ahern } 94033c2dcfdSDavid Ahern 941e9db1310SAdrian Hunter int __perf_evlist__parse_mmap_pages(unsigned int *mmap_pages, const char *str) 94233c2dcfdSDavid Ahern { 94333c2dcfdSDavid Ahern unsigned long max = UINT_MAX; 94433c2dcfdSDavid Ahern long pages; 94533c2dcfdSDavid Ahern 946f5ae9c42SAdrian Hunter if (max > SIZE_MAX / page_size) 94733c2dcfdSDavid Ahern max = SIZE_MAX / page_size; 94833c2dcfdSDavid Ahern 94933c2dcfdSDavid Ahern pages = parse_pages_arg(str, 1, max); 95033c2dcfdSDavid Ahern if (pages < 0) { 95133c2dcfdSDavid Ahern pr_err("Invalid argument for --mmap_pages/-m\n"); 952994a1f78SJiri Olsa return -1; 953994a1f78SJiri Olsa } 954994a1f78SJiri Olsa 955994a1f78SJiri Olsa *mmap_pages = pages; 956994a1f78SJiri Olsa return 0; 957994a1f78SJiri Olsa } 958994a1f78SJiri Olsa 959e9db1310SAdrian Hunter int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, 960e9db1310SAdrian Hunter int unset __maybe_unused) 961e9db1310SAdrian Hunter { 962e9db1310SAdrian Hunter return __perf_evlist__parse_mmap_pages(opt->value, str); 963e9db1310SAdrian Hunter } 964e9db1310SAdrian Hunter 965c83fa7f2SAdrian Hunter /** 966718c602dSAdrian Hunter * perf_evlist__mmap_ex - Create mmaps to receive events. 967c83fa7f2SAdrian Hunter * @evlist: list of events 968c83fa7f2SAdrian Hunter * @pages: map length in pages 969c83fa7f2SAdrian Hunter * @overwrite: overwrite older events? 970718c602dSAdrian Hunter * @auxtrace_pages - auxtrace map length in pages 971718c602dSAdrian Hunter * @auxtrace_overwrite - overwrite older auxtrace data? 972f8a95309SArnaldo Carvalho de Melo * 973c83fa7f2SAdrian Hunter * If @overwrite is %false the user needs to signal event consumption using 974c83fa7f2SAdrian Hunter * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this 975c83fa7f2SAdrian Hunter * automatically. 976f8a95309SArnaldo Carvalho de Melo * 977718c602dSAdrian Hunter * Similarly, if @auxtrace_overwrite is %false the user needs to signal data 978718c602dSAdrian Hunter * consumption using auxtrace_mmap__write_tail(). 979718c602dSAdrian Hunter * 980c83fa7f2SAdrian Hunter * Return: %0 on success, negative error code otherwise. 981f8a95309SArnaldo Carvalho de Melo */ 98263503dbaSJiri Olsa int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, 9837a276ff6SWang Nan unsigned int auxtrace_pages, 98451255a8aSAlexey Budankov bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, 98551255a8aSAlexey Budankov int comp_level) 986f8a95309SArnaldo Carvalho de Melo { 98732dcd021SJiri Olsa struct evsel *evsel; 988f72f901dSJiri Olsa const struct perf_cpu_map *cpus = evlist->core.cpus; 98903617c22SJiri Olsa const struct perf_thread_map *threads = evlist->core.threads; 99071f566a3SWang Nan /* 99171f566a3SWang Nan * Delay setting mp.prot: set it before calling perf_mmap__mmap. 99271f566a3SWang Nan * Its value is decided by evsel's write_backward. 99371f566a3SWang Nan * So &mp should not be passed through const pointer. 99471f566a3SWang Nan */ 99551255a8aSAlexey Budankov struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity, .flush = flush, 99651255a8aSAlexey Budankov .comp_level = comp_level }; 99750a682ceSArnaldo Carvalho de Melo 9988db6d6b1SWang Nan if (!evlist->mmap) 9992c5f6d87SKan Liang evlist->mmap = perf_evlist__alloc_mmap(evlist, false); 10008db6d6b1SWang Nan if (!evlist->mmap) 1001f8a95309SArnaldo Carvalho de Melo return -ENOMEM; 1002f8a95309SArnaldo Carvalho de Melo 10031b85337dSArnaldo Carvalho de Melo if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 1004f8a95309SArnaldo Carvalho de Melo return -ENOMEM; 1005f8a95309SArnaldo Carvalho de Melo 1006994a1f78SJiri Olsa evlist->mmap_len = perf_evlist__mmap_size(pages); 10072af68ef5SAdrian Hunter pr_debug("mmap size %zuB\n", evlist->mmap_len); 1008a8a8f3ebSAdrian Hunter mp.mask = evlist->mmap_len - page_size - 1; 1009f8a95309SArnaldo Carvalho de Melo 1010718c602dSAdrian Hunter auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len, 1011718c602dSAdrian Hunter auxtrace_pages, auxtrace_overwrite); 1012718c602dSAdrian Hunter 1013e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 10141fc632ceSJiri Olsa if ((evsel->core.attr.read_format & PERF_FORMAT_ID) && 1015a91e5431SArnaldo Carvalho de Melo evsel->sample_id == NULL && 1016a14bb7a6SArnaldo Carvalho de Melo perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) 1017f8a95309SArnaldo Carvalho de Melo return -ENOMEM; 1018f8a95309SArnaldo Carvalho de Melo } 1019f8a95309SArnaldo Carvalho de Melo 1020ec1e7e43SSukadev Bhattiprolu if (cpu_map__empty(cpus)) 1021a8a8f3ebSAdrian Hunter return perf_evlist__mmap_per_thread(evlist, &mp); 1022f8a95309SArnaldo Carvalho de Melo 1023a8a8f3ebSAdrian Hunter return perf_evlist__mmap_per_cpu(evlist, &mp); 1024f8a95309SArnaldo Carvalho de Melo } 10257e2ed097SArnaldo Carvalho de Melo 102663503dbaSJiri Olsa int perf_evlist__mmap(struct evlist *evlist, unsigned int pages) 1027718c602dSAdrian Hunter { 102851255a8aSAlexey Budankov return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); 1029718c602dSAdrian Hunter } 1030718c602dSAdrian Hunter 103163503dbaSJiri Olsa int perf_evlist__create_maps(struct evlist *evlist, struct target *target) 10327e2ed097SArnaldo Carvalho de Melo { 1033147c508fSJin Yao bool all_threads = (target->per_thread && target->system_wide); 1034f854839bSJiri Olsa struct perf_cpu_map *cpus; 10359749b90eSJiri Olsa struct perf_thread_map *threads; 10367e2ed097SArnaldo Carvalho de Melo 1037147c508fSJin Yao /* 1038147c508fSJin Yao * If specify '-a' and '--per-thread' to perf record, perf record 1039147c508fSJin Yao * will override '--per-thread'. target->per_thread = false and 1040147c508fSJin Yao * target->system_wide = true. 1041147c508fSJin Yao * 1042147c508fSJin Yao * If specify '--per-thread' only to perf record, 1043147c508fSJin Yao * target->per_thread = true and target->system_wide = false. 1044147c508fSJin Yao * 1045147c508fSJin Yao * So target->per_thread && target->system_wide is false. 1046147c508fSJin Yao * For perf record, thread_map__new_str doesn't call 1047147c508fSJin Yao * thread_map__new_all_cpus. That will keep perf record's 1048147c508fSJin Yao * current behavior. 1049147c508fSJin Yao * 1050147c508fSJin Yao * For perf stat, it allows the case that target->per_thread and 1051147c508fSJin Yao * target->system_wide are all true. It means to collect system-wide 1052147c508fSJin Yao * per-thread data. thread_map__new_str will call 1053147c508fSJin Yao * thread_map__new_all_cpus to enumerate all threads. 1054147c508fSJin Yao */ 105573c0ca1eSJin Yao threads = thread_map__new_str(target->pid, target->tid, target->uid, 1056147c508fSJin Yao all_threads); 105774bfd2b2SAdrian Hunter 105874bfd2b2SAdrian Hunter if (!threads) 10597e2ed097SArnaldo Carvalho de Melo return -1; 10607e2ed097SArnaldo Carvalho de Melo 10619c105fbcSDongsheng Yang if (target__uses_dummy_map(target)) 1062397721e0SJiri Olsa cpus = perf_cpu_map__dummy_new(); 1063879d77d0SNamhyung Kim else 10649c3516d1SJiri Olsa cpus = perf_cpu_map__new(target->cpu_list); 10657e2ed097SArnaldo Carvalho de Melo 106674bfd2b2SAdrian Hunter if (!cpus) 10677e2ed097SArnaldo Carvalho de Melo goto out_delete_threads; 10687e2ed097SArnaldo Carvalho de Melo 1069ec903f26SJiri Olsa evlist->core.has_user_cpus = !!target->cpu_list; 1070ec9a77a7SAdrian Hunter 1071453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads); 1072d5bc056eSAdrian Hunter 1073d5bc056eSAdrian Hunter return 0; 10747e2ed097SArnaldo Carvalho de Melo 10757e2ed097SArnaldo Carvalho de Melo out_delete_threads: 10767836e52eSJiri Olsa perf_thread_map__put(threads); 10777e2ed097SArnaldo Carvalho de Melo return -1; 10787e2ed097SArnaldo Carvalho de Melo } 10797e2ed097SArnaldo Carvalho de Melo 108063503dbaSJiri Olsa void __perf_evlist__set_sample_bit(struct evlist *evlist, 108122c8a376SArnaldo Carvalho de Melo enum perf_event_sample_format bit) 108222c8a376SArnaldo Carvalho de Melo { 108332dcd021SJiri Olsa struct evsel *evsel; 108422c8a376SArnaldo Carvalho de Melo 1085e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 108622c8a376SArnaldo Carvalho de Melo __perf_evsel__set_sample_bit(evsel, bit); 108722c8a376SArnaldo Carvalho de Melo } 108822c8a376SArnaldo Carvalho de Melo 108963503dbaSJiri Olsa void __perf_evlist__reset_sample_bit(struct evlist *evlist, 109022c8a376SArnaldo Carvalho de Melo enum perf_event_sample_format bit) 109122c8a376SArnaldo Carvalho de Melo { 109232dcd021SJiri Olsa struct evsel *evsel; 109322c8a376SArnaldo Carvalho de Melo 1094e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 109522c8a376SArnaldo Carvalho de Melo __perf_evsel__reset_sample_bit(evsel, bit); 109622c8a376SArnaldo Carvalho de Melo } 109722c8a376SArnaldo Carvalho de Melo 109863503dbaSJiri Olsa int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) 10990a102479SFrederic Weisbecker { 110032dcd021SJiri Olsa struct evsel *evsel; 1101745cefc5SArnaldo Carvalho de Melo int err = 0; 11020a102479SFrederic Weisbecker 1103e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 1104745cefc5SArnaldo Carvalho de Melo if (evsel->filter == NULL) 11050a102479SFrederic Weisbecker continue; 1106745cefc5SArnaldo Carvalho de Melo 1107d988d5eeSKan Liang /* 1108d988d5eeSKan Liang * filters only work for tracepoint event, which doesn't have cpu limit. 1109d988d5eeSKan Liang * So evlist and evsel should always be same. 1110d988d5eeSKan Liang */ 111124e376b2SJiri Olsa err = evsel__apply_filter(evsel, evsel->filter); 111223d4aad4SArnaldo Carvalho de Melo if (err) { 111323d4aad4SArnaldo Carvalho de Melo *err_evsel = evsel; 1114745cefc5SArnaldo Carvalho de Melo break; 11150a102479SFrederic Weisbecker } 111623d4aad4SArnaldo Carvalho de Melo } 11170a102479SFrederic Weisbecker 1118745cefc5SArnaldo Carvalho de Melo return err; 1119745cefc5SArnaldo Carvalho de Melo } 1120745cefc5SArnaldo Carvalho de Melo 112163503dbaSJiri Olsa int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter) 1122745cefc5SArnaldo Carvalho de Melo { 112332dcd021SJiri Olsa struct evsel *evsel; 1124745cefc5SArnaldo Carvalho de Melo int err = 0; 1125745cefc5SArnaldo Carvalho de Melo 1126e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 11271fc632ceSJiri Olsa if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) 1128fdf14720SWang Nan continue; 1129fdf14720SWang Nan 113094ad89bcSArnaldo Carvalho de Melo err = perf_evsel__set_filter(evsel, filter); 1131745cefc5SArnaldo Carvalho de Melo if (err) 1132745cefc5SArnaldo Carvalho de Melo break; 1133745cefc5SArnaldo Carvalho de Melo } 1134745cefc5SArnaldo Carvalho de Melo 1135745cefc5SArnaldo Carvalho de Melo return err; 11360a102479SFrederic Weisbecker } 113774429964SFrederic Weisbecker 113863503dbaSJiri Olsa int perf_evlist__set_tp_filter_pids(struct evlist *evlist, size_t npids, pid_t *pids) 1139cfd70a26SArnaldo Carvalho de Melo { 1140cfd70a26SArnaldo Carvalho de Melo char *filter; 1141be199adaSArnaldo Carvalho de Melo int ret = -1; 1142be199adaSArnaldo Carvalho de Melo size_t i; 1143cfd70a26SArnaldo Carvalho de Melo 1144be199adaSArnaldo Carvalho de Melo for (i = 0; i < npids; ++i) { 1145be199adaSArnaldo Carvalho de Melo if (i == 0) { 1146be199adaSArnaldo Carvalho de Melo if (asprintf(&filter, "common_pid != %d", pids[i]) < 0) 1147cfd70a26SArnaldo Carvalho de Melo return -1; 1148be199adaSArnaldo Carvalho de Melo } else { 1149be199adaSArnaldo Carvalho de Melo char *tmp; 1150be199adaSArnaldo Carvalho de Melo 1151be199adaSArnaldo Carvalho de Melo if (asprintf(&tmp, "%s && common_pid != %d", filter, pids[i]) < 0) 1152be199adaSArnaldo Carvalho de Melo goto out_free; 1153be199adaSArnaldo Carvalho de Melo 1154be199adaSArnaldo Carvalho de Melo free(filter); 1155be199adaSArnaldo Carvalho de Melo filter = tmp; 1156be199adaSArnaldo Carvalho de Melo } 1157be199adaSArnaldo Carvalho de Melo } 1158cfd70a26SArnaldo Carvalho de Melo 11597ad92a33SArnaldo Carvalho de Melo ret = perf_evlist__set_tp_filter(evlist, filter); 1160be199adaSArnaldo Carvalho de Melo out_free: 1161cfd70a26SArnaldo Carvalho de Melo free(filter); 1162cfd70a26SArnaldo Carvalho de Melo return ret; 1163cfd70a26SArnaldo Carvalho de Melo } 1164cfd70a26SArnaldo Carvalho de Melo 116563503dbaSJiri Olsa int perf_evlist__set_tp_filter_pid(struct evlist *evlist, pid_t pid) 1166be199adaSArnaldo Carvalho de Melo { 11677ad92a33SArnaldo Carvalho de Melo return perf_evlist__set_tp_filter_pids(evlist, 1, &pid); 1168be199adaSArnaldo Carvalho de Melo } 1169be199adaSArnaldo Carvalho de Melo 117063503dbaSJiri Olsa bool perf_evlist__valid_sample_type(struct evlist *evlist) 117174429964SFrederic Weisbecker { 117232dcd021SJiri Olsa struct evsel *pos; 1173c2a70653SArnaldo Carvalho de Melo 11746484d2f9SJiri Olsa if (evlist->core.nr_entries == 1) 117575562573SAdrian Hunter return true; 117675562573SAdrian Hunter 117775562573SAdrian Hunter if (evlist->id_pos < 0 || evlist->is_pos < 0) 117875562573SAdrian Hunter return false; 117975562573SAdrian Hunter 1180e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 118175562573SAdrian Hunter if (pos->id_pos != evlist->id_pos || 118275562573SAdrian Hunter pos->is_pos != evlist->is_pos) 1183c2a70653SArnaldo Carvalho de Melo return false; 118474429964SFrederic Weisbecker } 118574429964SFrederic Weisbecker 1186c2a70653SArnaldo Carvalho de Melo return true; 1187c2a70653SArnaldo Carvalho de Melo } 1188c2a70653SArnaldo Carvalho de Melo 118963503dbaSJiri Olsa u64 __perf_evlist__combined_sample_type(struct evlist *evlist) 1190c2a70653SArnaldo Carvalho de Melo { 119132dcd021SJiri Olsa struct evsel *evsel; 119275562573SAdrian Hunter 119375562573SAdrian Hunter if (evlist->combined_sample_type) 119475562573SAdrian Hunter return evlist->combined_sample_type; 119575562573SAdrian Hunter 1196e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 11971fc632ceSJiri Olsa evlist->combined_sample_type |= evsel->core.attr.sample_type; 119875562573SAdrian Hunter 119975562573SAdrian Hunter return evlist->combined_sample_type; 120075562573SAdrian Hunter } 120175562573SAdrian Hunter 120263503dbaSJiri Olsa u64 perf_evlist__combined_sample_type(struct evlist *evlist) 120375562573SAdrian Hunter { 120475562573SAdrian Hunter evlist->combined_sample_type = 0; 120575562573SAdrian Hunter return __perf_evlist__combined_sample_type(evlist); 1206c2a70653SArnaldo Carvalho de Melo } 1207c2a70653SArnaldo Carvalho de Melo 120863503dbaSJiri Olsa u64 perf_evlist__combined_branch_type(struct evlist *evlist) 120998df858eSAndi Kleen { 121032dcd021SJiri Olsa struct evsel *evsel; 121198df858eSAndi Kleen u64 branch_type = 0; 121298df858eSAndi Kleen 1213e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 12141fc632ceSJiri Olsa branch_type |= evsel->core.attr.branch_sample_type; 121598df858eSAndi Kleen return branch_type; 121698df858eSAndi Kleen } 121798df858eSAndi Kleen 121863503dbaSJiri Olsa bool perf_evlist__valid_read_format(struct evlist *evlist) 12199ede473cSJiri Olsa { 122032dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist), *pos = first; 12211fc632ceSJiri Olsa u64 read_format = first->core.attr.read_format; 12221fc632ceSJiri Olsa u64 sample_type = first->core.attr.sample_type; 12239ede473cSJiri Olsa 1224e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 12251fc632ceSJiri Olsa if (read_format != pos->core.attr.read_format) 12269ede473cSJiri Olsa return false; 12279ede473cSJiri Olsa } 12289ede473cSJiri Olsa 12299ede473cSJiri Olsa /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */ 12309ede473cSJiri Olsa if ((sample_type & PERF_SAMPLE_READ) && 12319ede473cSJiri Olsa !(read_format & PERF_FORMAT_ID)) { 12329ede473cSJiri Olsa return false; 12339ede473cSJiri Olsa } 12349ede473cSJiri Olsa 12359ede473cSJiri Olsa return true; 12369ede473cSJiri Olsa } 12379ede473cSJiri Olsa 123863503dbaSJiri Olsa u64 perf_evlist__read_format(struct evlist *evlist) 12399ede473cSJiri Olsa { 124032dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 12411fc632ceSJiri Olsa return first->core.attr.read_format; 12429ede473cSJiri Olsa } 12439ede473cSJiri Olsa 124463503dbaSJiri Olsa u16 perf_evlist__id_hdr_size(struct evlist *evlist) 124581e36bffSArnaldo Carvalho de Melo { 124632dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 124781e36bffSArnaldo Carvalho de Melo struct perf_sample *data; 124881e36bffSArnaldo Carvalho de Melo u64 sample_type; 124981e36bffSArnaldo Carvalho de Melo u16 size = 0; 125081e36bffSArnaldo Carvalho de Melo 12511fc632ceSJiri Olsa if (!first->core.attr.sample_id_all) 125281e36bffSArnaldo Carvalho de Melo goto out; 125381e36bffSArnaldo Carvalho de Melo 12541fc632ceSJiri Olsa sample_type = first->core.attr.sample_type; 125581e36bffSArnaldo Carvalho de Melo 125681e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_TID) 125781e36bffSArnaldo Carvalho de Melo size += sizeof(data->tid) * 2; 125881e36bffSArnaldo Carvalho de Melo 125981e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_TIME) 126081e36bffSArnaldo Carvalho de Melo size += sizeof(data->time); 126181e36bffSArnaldo Carvalho de Melo 126281e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_ID) 126381e36bffSArnaldo Carvalho de Melo size += sizeof(data->id); 126481e36bffSArnaldo Carvalho de Melo 126581e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_STREAM_ID) 126681e36bffSArnaldo Carvalho de Melo size += sizeof(data->stream_id); 126781e36bffSArnaldo Carvalho de Melo 126881e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_CPU) 126981e36bffSArnaldo Carvalho de Melo size += sizeof(data->cpu) * 2; 127075562573SAdrian Hunter 127175562573SAdrian Hunter if (sample_type & PERF_SAMPLE_IDENTIFIER) 127275562573SAdrian Hunter size += sizeof(data->id); 127381e36bffSArnaldo Carvalho de Melo out: 127481e36bffSArnaldo Carvalho de Melo return size; 127581e36bffSArnaldo Carvalho de Melo } 127681e36bffSArnaldo Carvalho de Melo 127763503dbaSJiri Olsa bool perf_evlist__valid_sample_id_all(struct evlist *evlist) 1278c2a70653SArnaldo Carvalho de Melo { 127932dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist), *pos = first; 1280c2a70653SArnaldo Carvalho de Melo 1281e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_continue(evlist, pos) { 12821fc632ceSJiri Olsa if (first->core.attr.sample_id_all != pos->core.attr.sample_id_all) 1283c2a70653SArnaldo Carvalho de Melo return false; 1284c2a70653SArnaldo Carvalho de Melo } 1285c2a70653SArnaldo Carvalho de Melo 1286c2a70653SArnaldo Carvalho de Melo return true; 128774429964SFrederic Weisbecker } 128874429964SFrederic Weisbecker 128963503dbaSJiri Olsa bool perf_evlist__sample_id_all(struct evlist *evlist) 129074429964SFrederic Weisbecker { 129132dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 12921fc632ceSJiri Olsa return first->core.attr.sample_id_all; 129374429964SFrederic Weisbecker } 129481cce8deSArnaldo Carvalho de Melo 129563503dbaSJiri Olsa void perf_evlist__set_selected(struct evlist *evlist, 129632dcd021SJiri Olsa struct evsel *evsel) 129781cce8deSArnaldo Carvalho de Melo { 129881cce8deSArnaldo Carvalho de Melo evlist->selected = evsel; 129981cce8deSArnaldo Carvalho de Melo } 1300727ab04eSArnaldo Carvalho de Melo 1301750b4edeSJiri Olsa void evlist__close(struct evlist *evlist) 1302a74b4b66SNamhyung Kim { 130332dcd021SJiri Olsa struct evsel *evsel; 1304a74b4b66SNamhyung Kim 1305475fb533SAndi Kleen evlist__for_each_entry_reverse(evlist, evsel) 1306475fb533SAndi Kleen perf_evsel__close(evsel); 1307a74b4b66SNamhyung Kim } 1308a74b4b66SNamhyung Kim 130963503dbaSJiri Olsa static int perf_evlist__create_syswide_maps(struct evlist *evlist) 13104112eb18SArnaldo Carvalho de Melo { 1311f854839bSJiri Olsa struct perf_cpu_map *cpus; 13129749b90eSJiri Olsa struct perf_thread_map *threads; 13134112eb18SArnaldo Carvalho de Melo int err = -ENOMEM; 13144112eb18SArnaldo Carvalho de Melo 13154112eb18SArnaldo Carvalho de Melo /* 13164112eb18SArnaldo Carvalho de Melo * Try reading /sys/devices/system/cpu/online to get 13174112eb18SArnaldo Carvalho de Melo * an all cpus map. 13184112eb18SArnaldo Carvalho de Melo * 13194112eb18SArnaldo Carvalho de Melo * FIXME: -ENOMEM is the best we can do here, the cpu_map 13204112eb18SArnaldo Carvalho de Melo * code needs an overhaul to properly forward the 13214112eb18SArnaldo Carvalho de Melo * error, and we may not want to do that fallback to a 13224112eb18SArnaldo Carvalho de Melo * default cpu identity map :-\ 13234112eb18SArnaldo Carvalho de Melo */ 13249c3516d1SJiri Olsa cpus = perf_cpu_map__new(NULL); 13258c0498b6SAdrian Hunter if (!cpus) 13264112eb18SArnaldo Carvalho de Melo goto out; 13274112eb18SArnaldo Carvalho de Melo 13284b49cce2SJiri Olsa threads = perf_thread_map__new_dummy(); 13298c0498b6SAdrian Hunter if (!threads) 13308c0498b6SAdrian Hunter goto out_put; 13314112eb18SArnaldo Carvalho de Melo 1332453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads); 13334112eb18SArnaldo Carvalho de Melo out: 13344112eb18SArnaldo Carvalho de Melo return err; 13358c0498b6SAdrian Hunter out_put: 133638f01d8dSJiri Olsa perf_cpu_map__put(cpus); 13374112eb18SArnaldo Carvalho de Melo goto out; 13384112eb18SArnaldo Carvalho de Melo } 13394112eb18SArnaldo Carvalho de Melo 1340474ddc4cSJiri Olsa int evlist__open(struct evlist *evlist) 1341727ab04eSArnaldo Carvalho de Melo { 134232dcd021SJiri Olsa struct evsel *evsel; 1343a74b4b66SNamhyung Kim int err; 1344727ab04eSArnaldo Carvalho de Melo 13454112eb18SArnaldo Carvalho de Melo /* 13464112eb18SArnaldo Carvalho de Melo * Default: one fd per CPU, all threads, aka systemwide 13474112eb18SArnaldo Carvalho de Melo * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL 13484112eb18SArnaldo Carvalho de Melo */ 134903617c22SJiri Olsa if (evlist->core.threads == NULL && evlist->core.cpus == NULL) { 13504112eb18SArnaldo Carvalho de Melo err = perf_evlist__create_syswide_maps(evlist); 13514112eb18SArnaldo Carvalho de Melo if (err < 0) 13524112eb18SArnaldo Carvalho de Melo goto out_err; 13534112eb18SArnaldo Carvalho de Melo } 13544112eb18SArnaldo Carvalho de Melo 1355733cd2feSAdrian Hunter perf_evlist__update_id_pos(evlist); 1356733cd2feSAdrian Hunter 1357e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 1358af663bd0SJiri Olsa err = evsel__open(evsel, evsel->core.cpus, evsel->core.threads); 1359727ab04eSArnaldo Carvalho de Melo if (err < 0) 1360727ab04eSArnaldo Carvalho de Melo goto out_err; 1361727ab04eSArnaldo Carvalho de Melo } 1362727ab04eSArnaldo Carvalho de Melo 1363727ab04eSArnaldo Carvalho de Melo return 0; 1364727ab04eSArnaldo Carvalho de Melo out_err: 1365750b4edeSJiri Olsa evlist__close(evlist); 136641c21a68SNamhyung Kim errno = -err; 1367727ab04eSArnaldo Carvalho de Melo return err; 1368727ab04eSArnaldo Carvalho de Melo } 136935b9d88eSArnaldo Carvalho de Melo 137063503dbaSJiri Olsa int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, 137155e162eaSNamhyung Kim const char *argv[], bool pipe_output, 1372735f7e0bSArnaldo Carvalho de Melo void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) 137335b9d88eSArnaldo Carvalho de Melo { 137435b9d88eSArnaldo Carvalho de Melo int child_ready_pipe[2], go_pipe[2]; 137535b9d88eSArnaldo Carvalho de Melo char bf; 137635b9d88eSArnaldo Carvalho de Melo 137735b9d88eSArnaldo Carvalho de Melo if (pipe(child_ready_pipe) < 0) { 137835b9d88eSArnaldo Carvalho de Melo perror("failed to create 'ready' pipe"); 137935b9d88eSArnaldo Carvalho de Melo return -1; 138035b9d88eSArnaldo Carvalho de Melo } 138135b9d88eSArnaldo Carvalho de Melo 138235b9d88eSArnaldo Carvalho de Melo if (pipe(go_pipe) < 0) { 138335b9d88eSArnaldo Carvalho de Melo perror("failed to create 'go' pipe"); 138435b9d88eSArnaldo Carvalho de Melo goto out_close_ready_pipe; 138535b9d88eSArnaldo Carvalho de Melo } 138635b9d88eSArnaldo Carvalho de Melo 138735b9d88eSArnaldo Carvalho de Melo evlist->workload.pid = fork(); 138835b9d88eSArnaldo Carvalho de Melo if (evlist->workload.pid < 0) { 138935b9d88eSArnaldo Carvalho de Melo perror("failed to fork"); 139035b9d88eSArnaldo Carvalho de Melo goto out_close_pipes; 139135b9d88eSArnaldo Carvalho de Melo } 139235b9d88eSArnaldo Carvalho de Melo 139335b9d88eSArnaldo Carvalho de Melo if (!evlist->workload.pid) { 13945f1c4225SArnaldo Carvalho de Melo int ret; 13955f1c4225SArnaldo Carvalho de Melo 1396119fa3c9SNamhyung Kim if (pipe_output) 139735b9d88eSArnaldo Carvalho de Melo dup2(2, 1); 139835b9d88eSArnaldo Carvalho de Melo 13990817df08SDavid Ahern signal(SIGTERM, SIG_DFL); 14000817df08SDavid Ahern 140135b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 140235b9d88eSArnaldo Carvalho de Melo close(go_pipe[1]); 140335b9d88eSArnaldo Carvalho de Melo fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 140435b9d88eSArnaldo Carvalho de Melo 140535b9d88eSArnaldo Carvalho de Melo /* 140635b9d88eSArnaldo Carvalho de Melo * Tell the parent we're ready to go 140735b9d88eSArnaldo Carvalho de Melo */ 140835b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 140935b9d88eSArnaldo Carvalho de Melo 141035b9d88eSArnaldo Carvalho de Melo /* 141135b9d88eSArnaldo Carvalho de Melo * Wait until the parent tells us to go. 141235b9d88eSArnaldo Carvalho de Melo */ 14135f1c4225SArnaldo Carvalho de Melo ret = read(go_pipe[0], &bf, 1); 14145f1c4225SArnaldo Carvalho de Melo /* 14155f1c4225SArnaldo Carvalho de Melo * The parent will ask for the execvp() to be performed by 14165f1c4225SArnaldo Carvalho de Melo * writing exactly one byte, in workload.cork_fd, usually via 14175f1c4225SArnaldo Carvalho de Melo * perf_evlist__start_workload(). 14185f1c4225SArnaldo Carvalho de Melo * 141920f86fc1SArnaldo Carvalho de Melo * For cancelling the workload without actually running it, 14205f1c4225SArnaldo Carvalho de Melo * the parent will just close workload.cork_fd, without writing 14215f1c4225SArnaldo Carvalho de Melo * anything, i.e. read will return zero and we just exit() 14225f1c4225SArnaldo Carvalho de Melo * here. 14235f1c4225SArnaldo Carvalho de Melo */ 14245f1c4225SArnaldo Carvalho de Melo if (ret != 1) { 14255f1c4225SArnaldo Carvalho de Melo if (ret == -1) 142635b9d88eSArnaldo Carvalho de Melo perror("unable to read pipe"); 14275f1c4225SArnaldo Carvalho de Melo exit(ret); 14285f1c4225SArnaldo Carvalho de Melo } 142935b9d88eSArnaldo Carvalho de Melo 143035b9d88eSArnaldo Carvalho de Melo execvp(argv[0], (char **)argv); 143135b9d88eSArnaldo Carvalho de Melo 1432735f7e0bSArnaldo Carvalho de Melo if (exec_error) { 1433f33cbe72SArnaldo Carvalho de Melo union sigval val; 1434f33cbe72SArnaldo Carvalho de Melo 1435f33cbe72SArnaldo Carvalho de Melo val.sival_int = errno; 1436f33cbe72SArnaldo Carvalho de Melo if (sigqueue(getppid(), SIGUSR1, val)) 143735b9d88eSArnaldo Carvalho de Melo perror(argv[0]); 1438f33cbe72SArnaldo Carvalho de Melo } else 1439f33cbe72SArnaldo Carvalho de Melo perror(argv[0]); 144035b9d88eSArnaldo Carvalho de Melo exit(-1); 144135b9d88eSArnaldo Carvalho de Melo } 144235b9d88eSArnaldo Carvalho de Melo 1443735f7e0bSArnaldo Carvalho de Melo if (exec_error) { 1444735f7e0bSArnaldo Carvalho de Melo struct sigaction act = { 1445735f7e0bSArnaldo Carvalho de Melo .sa_flags = SA_SIGINFO, 1446735f7e0bSArnaldo Carvalho de Melo .sa_sigaction = exec_error, 1447735f7e0bSArnaldo Carvalho de Melo }; 1448735f7e0bSArnaldo Carvalho de Melo sigaction(SIGUSR1, &act, NULL); 1449735f7e0bSArnaldo Carvalho de Melo } 1450735f7e0bSArnaldo Carvalho de Melo 14511aaf63b1SArnaldo Carvalho de Melo if (target__none(target)) { 145203617c22SJiri Olsa if (evlist->core.threads == NULL) { 14531aaf63b1SArnaldo Carvalho de Melo fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", 14541aaf63b1SArnaldo Carvalho de Melo __func__, __LINE__); 14551aaf63b1SArnaldo Carvalho de Melo goto out_close_pipes; 14561aaf63b1SArnaldo Carvalho de Melo } 145703617c22SJiri Olsa perf_thread_map__set_pid(evlist->core.threads, 0, evlist->workload.pid); 14581aaf63b1SArnaldo Carvalho de Melo } 145935b9d88eSArnaldo Carvalho de Melo 146035b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 146135b9d88eSArnaldo Carvalho de Melo close(go_pipe[0]); 146235b9d88eSArnaldo Carvalho de Melo /* 146335b9d88eSArnaldo Carvalho de Melo * wait for child to settle 146435b9d88eSArnaldo Carvalho de Melo */ 146535b9d88eSArnaldo Carvalho de Melo if (read(child_ready_pipe[0], &bf, 1) == -1) { 146635b9d88eSArnaldo Carvalho de Melo perror("unable to read pipe"); 146735b9d88eSArnaldo Carvalho de Melo goto out_close_pipes; 146835b9d88eSArnaldo Carvalho de Melo } 146935b9d88eSArnaldo Carvalho de Melo 1470bcf3145fSNamhyung Kim fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); 147135b9d88eSArnaldo Carvalho de Melo evlist->workload.cork_fd = go_pipe[1]; 147235b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 147335b9d88eSArnaldo Carvalho de Melo return 0; 147435b9d88eSArnaldo Carvalho de Melo 147535b9d88eSArnaldo Carvalho de Melo out_close_pipes: 147635b9d88eSArnaldo Carvalho de Melo close(go_pipe[0]); 147735b9d88eSArnaldo Carvalho de Melo close(go_pipe[1]); 147835b9d88eSArnaldo Carvalho de Melo out_close_ready_pipe: 147935b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 148035b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 148135b9d88eSArnaldo Carvalho de Melo return -1; 148235b9d88eSArnaldo Carvalho de Melo } 148335b9d88eSArnaldo Carvalho de Melo 148463503dbaSJiri Olsa int perf_evlist__start_workload(struct evlist *evlist) 148535b9d88eSArnaldo Carvalho de Melo { 148635b9d88eSArnaldo Carvalho de Melo if (evlist->workload.cork_fd > 0) { 1487b3824404SDavid Ahern char bf = 0; 1488bcf3145fSNamhyung Kim int ret; 148935b9d88eSArnaldo Carvalho de Melo /* 149035b9d88eSArnaldo Carvalho de Melo * Remove the cork, let it rip! 149135b9d88eSArnaldo Carvalho de Melo */ 1492bcf3145fSNamhyung Kim ret = write(evlist->workload.cork_fd, &bf, 1); 1493bcf3145fSNamhyung Kim if (ret < 0) 1494e978be9eSSoramichi Akiyama perror("unable to write to pipe"); 1495bcf3145fSNamhyung Kim 1496bcf3145fSNamhyung Kim close(evlist->workload.cork_fd); 1497bcf3145fSNamhyung Kim return ret; 149835b9d88eSArnaldo Carvalho de Melo } 149935b9d88eSArnaldo Carvalho de Melo 150035b9d88eSArnaldo Carvalho de Melo return 0; 150135b9d88eSArnaldo Carvalho de Melo } 1502cb0b29e0SArnaldo Carvalho de Melo 150363503dbaSJiri Olsa int perf_evlist__parse_sample(struct evlist *evlist, union perf_event *event, 15040807d2d8SArnaldo Carvalho de Melo struct perf_sample *sample) 1505cb0b29e0SArnaldo Carvalho de Melo { 150632dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 150775562573SAdrian Hunter 150875562573SAdrian Hunter if (!evsel) 150975562573SAdrian Hunter return -EFAULT; 15100807d2d8SArnaldo Carvalho de Melo return perf_evsel__parse_sample(evsel, event, sample); 1511cb0b29e0SArnaldo Carvalho de Melo } 151278f067b3SArnaldo Carvalho de Melo 151363503dbaSJiri Olsa int perf_evlist__parse_sample_timestamp(struct evlist *evlist, 151401468120SJiri Olsa union perf_event *event, 151501468120SJiri Olsa u64 *timestamp) 151601468120SJiri Olsa { 151732dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 151801468120SJiri Olsa 151901468120SJiri Olsa if (!evsel) 152001468120SJiri Olsa return -EFAULT; 152101468120SJiri Olsa return perf_evsel__parse_sample_timestamp(evsel, event, timestamp); 152201468120SJiri Olsa } 152301468120SJiri Olsa 152463503dbaSJiri Olsa size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp) 152578f067b3SArnaldo Carvalho de Melo { 152632dcd021SJiri Olsa struct evsel *evsel; 152778f067b3SArnaldo Carvalho de Melo size_t printed = 0; 152878f067b3SArnaldo Carvalho de Melo 1529e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 153078f067b3SArnaldo Carvalho de Melo printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", 153178f067b3SArnaldo Carvalho de Melo perf_evsel__name(evsel)); 153278f067b3SArnaldo Carvalho de Melo } 153378f067b3SArnaldo Carvalho de Melo 1534b2222139SDavidlohr Bueso return printed + fprintf(fp, "\n"); 153578f067b3SArnaldo Carvalho de Melo } 15366ef068cbSArnaldo Carvalho de Melo 153763503dbaSJiri Olsa int perf_evlist__strerror_open(struct evlist *evlist, 1538a8f23d8fSArnaldo Carvalho de Melo int err, char *buf, size_t size) 1539a8f23d8fSArnaldo Carvalho de Melo { 1540a8f23d8fSArnaldo Carvalho de Melo int printed, value; 1541c8b5f2c9SArnaldo Carvalho de Melo char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); 1542a8f23d8fSArnaldo Carvalho de Melo 1543a8f23d8fSArnaldo Carvalho de Melo switch (err) { 1544a8f23d8fSArnaldo Carvalho de Melo case EACCES: 1545a8f23d8fSArnaldo Carvalho de Melo case EPERM: 1546a8f23d8fSArnaldo Carvalho de Melo printed = scnprintf(buf, size, 1547a8f23d8fSArnaldo Carvalho de Melo "Error:\t%s.\n" 1548a8f23d8fSArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); 1549a8f23d8fSArnaldo Carvalho de Melo 15501a47245dSAdrian Hunter value = perf_event_paranoid(); 1551a8f23d8fSArnaldo Carvalho de Melo 1552a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, "\nHint:\t"); 1553a8f23d8fSArnaldo Carvalho de Melo 1554a8f23d8fSArnaldo Carvalho de Melo if (value >= 2) { 1555a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1556a8f23d8fSArnaldo Carvalho de Melo "For your workloads it needs to be <= 1\nHint:\t"); 1557a8f23d8fSArnaldo Carvalho de Melo } 1558a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 15595229e366SArnaldo Carvalho de Melo "For system wide tracing it needs to be set to -1.\n"); 1560a8f23d8fSArnaldo Carvalho de Melo 1561a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 15625229e366SArnaldo Carvalho de Melo "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n" 15635229e366SArnaldo Carvalho de Melo "Hint:\tThe current value is %d.", value); 1564a8f23d8fSArnaldo Carvalho de Melo break; 1565d9aade7fSArnaldo Carvalho de Melo case EINVAL: { 156632dcd021SJiri Olsa struct evsel *first = perf_evlist__first(evlist); 1567d9aade7fSArnaldo Carvalho de Melo int max_freq; 1568d9aade7fSArnaldo Carvalho de Melo 1569d9aade7fSArnaldo Carvalho de Melo if (sysctl__read_int("kernel/perf_event_max_sample_rate", &max_freq) < 0) 1570d9aade7fSArnaldo Carvalho de Melo goto out_default; 1571d9aade7fSArnaldo Carvalho de Melo 15721fc632ceSJiri Olsa if (first->core.attr.sample_freq < (u64)max_freq) 1573d9aade7fSArnaldo Carvalho de Melo goto out_default; 1574d9aade7fSArnaldo Carvalho de Melo 1575d9aade7fSArnaldo Carvalho de Melo printed = scnprintf(buf, size, 1576d9aade7fSArnaldo Carvalho de Melo "Error:\t%s.\n" 1577d9aade7fSArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_max_sample_rate.\n" 1578d9aade7fSArnaldo Carvalho de Melo "Hint:\tThe current value is %d and %" PRIu64 " is being requested.", 15791fc632ceSJiri Olsa emsg, max_freq, first->core.attr.sample_freq); 1580d9aade7fSArnaldo Carvalho de Melo break; 1581d9aade7fSArnaldo Carvalho de Melo } 1582a8f23d8fSArnaldo Carvalho de Melo default: 1583d9aade7fSArnaldo Carvalho de Melo out_default: 1584a8f23d8fSArnaldo Carvalho de Melo scnprintf(buf, size, "%s", emsg); 1585a8f23d8fSArnaldo Carvalho de Melo break; 1586a8f23d8fSArnaldo Carvalho de Melo } 1587a8f23d8fSArnaldo Carvalho de Melo 1588a8f23d8fSArnaldo Carvalho de Melo return 0; 1589a8f23d8fSArnaldo Carvalho de Melo } 1590a025e4f0SAdrian Hunter 159163503dbaSJiri Olsa int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) 1592956fa571SArnaldo Carvalho de Melo { 1593c8b5f2c9SArnaldo Carvalho de Melo char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); 1594e965bea1SArnaldo Carvalho de Melo int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; 1595956fa571SArnaldo Carvalho de Melo 1596956fa571SArnaldo Carvalho de Melo switch (err) { 1597956fa571SArnaldo Carvalho de Melo case EPERM: 1598e5d4a290SArnaldo Carvalho de Melo sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); 1599e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1600e965bea1SArnaldo Carvalho de Melo "Error:\t%s.\n" 1601956fa571SArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" 1602e965bea1SArnaldo Carvalho de Melo "Hint:\tTried using %zd kB.\n", 1603e5d4a290SArnaldo Carvalho de Melo emsg, pages_max_per_user, pages_attempted); 1604e965bea1SArnaldo Carvalho de Melo 1605e965bea1SArnaldo Carvalho de Melo if (pages_attempted >= pages_max_per_user) { 1606e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1607e965bea1SArnaldo Carvalho de Melo "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", 1608e965bea1SArnaldo Carvalho de Melo pages_max_per_user + pages_attempted); 1609e965bea1SArnaldo Carvalho de Melo } 1610e965bea1SArnaldo Carvalho de Melo 1611e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1612e965bea1SArnaldo Carvalho de Melo "Hint:\tTry using a smaller -m/--mmap-pages value."); 1613956fa571SArnaldo Carvalho de Melo break; 1614956fa571SArnaldo Carvalho de Melo default: 1615956fa571SArnaldo Carvalho de Melo scnprintf(buf, size, "%s", emsg); 1616956fa571SArnaldo Carvalho de Melo break; 1617956fa571SArnaldo Carvalho de Melo } 1618956fa571SArnaldo Carvalho de Melo 1619956fa571SArnaldo Carvalho de Melo return 0; 1620956fa571SArnaldo Carvalho de Melo } 1621956fa571SArnaldo Carvalho de Melo 162263503dbaSJiri Olsa void perf_evlist__to_front(struct evlist *evlist, 162332dcd021SJiri Olsa struct evsel *move_evsel) 1624a025e4f0SAdrian Hunter { 162532dcd021SJiri Olsa struct evsel *evsel, *n; 1626a025e4f0SAdrian Hunter LIST_HEAD(move); 1627a025e4f0SAdrian Hunter 1628a025e4f0SAdrian Hunter if (move_evsel == perf_evlist__first(evlist)) 1629a025e4f0SAdrian Hunter return; 1630a025e4f0SAdrian Hunter 1631e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_safe(evlist, n, evsel) { 1632a025e4f0SAdrian Hunter if (evsel->leader == move_evsel->leader) 1633b27c4eceSJiri Olsa list_move_tail(&evsel->core.node, &move); 1634a025e4f0SAdrian Hunter } 1635a025e4f0SAdrian Hunter 1636ce9036a6SJiri Olsa list_splice(&move, &evlist->core.entries); 1637a025e4f0SAdrian Hunter } 163860b0896cSAdrian Hunter 163963503dbaSJiri Olsa void perf_evlist__set_tracking_event(struct evlist *evlist, 164032dcd021SJiri Olsa struct evsel *tracking_evsel) 164160b0896cSAdrian Hunter { 164232dcd021SJiri Olsa struct evsel *evsel; 164360b0896cSAdrian Hunter 164460b0896cSAdrian Hunter if (tracking_evsel->tracking) 164560b0896cSAdrian Hunter return; 164660b0896cSAdrian Hunter 1647e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 164860b0896cSAdrian Hunter if (evsel != tracking_evsel) 164960b0896cSAdrian Hunter evsel->tracking = false; 165060b0896cSAdrian Hunter } 165160b0896cSAdrian Hunter 165260b0896cSAdrian Hunter tracking_evsel->tracking = true; 165360b0896cSAdrian Hunter } 16547630b3e2SWang Nan 165532dcd021SJiri Olsa struct evsel * 165663503dbaSJiri Olsa perf_evlist__find_evsel_by_str(struct evlist *evlist, 16577630b3e2SWang Nan const char *str) 16587630b3e2SWang Nan { 165932dcd021SJiri Olsa struct evsel *evsel; 16607630b3e2SWang Nan 1661e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 16627630b3e2SWang Nan if (!evsel->name) 16637630b3e2SWang Nan continue; 16647630b3e2SWang Nan if (strcmp(str, evsel->name) == 0) 16657630b3e2SWang Nan return evsel; 16667630b3e2SWang Nan } 16677630b3e2SWang Nan 16687630b3e2SWang Nan return NULL; 16697630b3e2SWang Nan } 167054cc54deSWang Nan 167163503dbaSJiri Olsa void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, 167254cc54deSWang Nan enum bkw_mmap_state state) 167354cc54deSWang Nan { 167454cc54deSWang Nan enum bkw_mmap_state old_state = evlist->bkw_mmap_state; 167554cc54deSWang Nan enum action { 167654cc54deSWang Nan NONE, 167754cc54deSWang Nan PAUSE, 167854cc54deSWang Nan RESUME, 167954cc54deSWang Nan } action = NONE; 168054cc54deSWang Nan 16810b72d69aSWang Nan if (!evlist->overwrite_mmap) 168254cc54deSWang Nan return; 168354cc54deSWang Nan 168454cc54deSWang Nan switch (old_state) { 168554cc54deSWang Nan case BKW_MMAP_NOTREADY: { 168654cc54deSWang Nan if (state != BKW_MMAP_RUNNING) 1687dd8bd53aSLuis de Bethencourt goto state_err; 168854cc54deSWang Nan break; 168954cc54deSWang Nan } 169054cc54deSWang Nan case BKW_MMAP_RUNNING: { 169154cc54deSWang Nan if (state != BKW_MMAP_DATA_PENDING) 169254cc54deSWang Nan goto state_err; 169354cc54deSWang Nan action = PAUSE; 169454cc54deSWang Nan break; 169554cc54deSWang Nan } 169654cc54deSWang Nan case BKW_MMAP_DATA_PENDING: { 169754cc54deSWang Nan if (state != BKW_MMAP_EMPTY) 169854cc54deSWang Nan goto state_err; 169954cc54deSWang Nan break; 170054cc54deSWang Nan } 170154cc54deSWang Nan case BKW_MMAP_EMPTY: { 170254cc54deSWang Nan if (state != BKW_MMAP_RUNNING) 170354cc54deSWang Nan goto state_err; 170454cc54deSWang Nan action = RESUME; 170554cc54deSWang Nan break; 170654cc54deSWang Nan } 170754cc54deSWang Nan default: 170854cc54deSWang Nan WARN_ONCE(1, "Shouldn't get there\n"); 170954cc54deSWang Nan } 171054cc54deSWang Nan 171154cc54deSWang Nan evlist->bkw_mmap_state = state; 171254cc54deSWang Nan 171354cc54deSWang Nan switch (action) { 171454cc54deSWang Nan case PAUSE: 171554cc54deSWang Nan perf_evlist__pause(evlist); 171654cc54deSWang Nan break; 171754cc54deSWang Nan case RESUME: 171854cc54deSWang Nan perf_evlist__resume(evlist); 171954cc54deSWang Nan break; 172054cc54deSWang Nan case NONE: 172154cc54deSWang Nan default: 172254cc54deSWang Nan break; 172354cc54deSWang Nan } 172454cc54deSWang Nan 172554cc54deSWang Nan state_err: 172654cc54deSWang Nan return; 172754cc54deSWang Nan } 172807d6f446SArnaldo Carvalho de Melo 172963503dbaSJiri Olsa bool perf_evlist__exclude_kernel(struct evlist *evlist) 173007d6f446SArnaldo Carvalho de Melo { 173132dcd021SJiri Olsa struct evsel *evsel; 173207d6f446SArnaldo Carvalho de Melo 173307d6f446SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 17341fc632ceSJiri Olsa if (!evsel->core.attr.exclude_kernel) 173507d6f446SArnaldo Carvalho de Melo return false; 173607d6f446SArnaldo Carvalho de Melo } 173707d6f446SArnaldo Carvalho de Melo 173807d6f446SArnaldo Carvalho de Melo return true; 173907d6f446SArnaldo Carvalho de Melo } 1740e2bdbe80SJin Yao 1741e2bdbe80SJin Yao /* 1742e2bdbe80SJin Yao * Events in data file are not collect in groups, but we still want 1743e2bdbe80SJin Yao * the group display. Set the artificial group and set the leader's 1744e2bdbe80SJin Yao * forced_leader flag to notify the display code. 1745e2bdbe80SJin Yao */ 174663503dbaSJiri Olsa void perf_evlist__force_leader(struct evlist *evlist) 1747e2bdbe80SJin Yao { 1748e2bdbe80SJin Yao if (!evlist->nr_groups) { 174932dcd021SJiri Olsa struct evsel *leader = perf_evlist__first(evlist); 1750e2bdbe80SJin Yao 1751e2bdbe80SJin Yao perf_evlist__set_leader(evlist); 1752e2bdbe80SJin Yao leader->forced_leader = true; 1753e2bdbe80SJin Yao } 1754e2bdbe80SJin Yao } 1755c3537fc2SAndi Kleen 175663503dbaSJiri Olsa struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, 175732dcd021SJiri Olsa struct evsel *evsel) 1758c3537fc2SAndi Kleen { 175932dcd021SJiri Olsa struct evsel *c2, *leader; 1760c3537fc2SAndi Kleen bool is_open = true; 1761c3537fc2SAndi Kleen 1762c3537fc2SAndi Kleen leader = evsel->leader; 1763c3537fc2SAndi Kleen pr_debug("Weak group for %s/%d failed\n", 1764c3537fc2SAndi Kleen leader->name, leader->nr_members); 1765c3537fc2SAndi Kleen 1766c3537fc2SAndi Kleen /* 1767c3537fc2SAndi Kleen * for_each_group_member doesn't work here because it doesn't 1768c3537fc2SAndi Kleen * include the first entry. 1769c3537fc2SAndi Kleen */ 1770c3537fc2SAndi Kleen evlist__for_each_entry(evsel_list, c2) { 1771c3537fc2SAndi Kleen if (c2 == evsel) 1772c3537fc2SAndi Kleen is_open = false; 1773c3537fc2SAndi Kleen if (c2->leader == leader) { 1774c3537fc2SAndi Kleen if (is_open) 1775c3537fc2SAndi Kleen perf_evsel__close(c2); 1776c3537fc2SAndi Kleen c2->leader = c2; 1777c3537fc2SAndi Kleen c2->nr_members = 0; 1778c3537fc2SAndi Kleen } 1779c3537fc2SAndi Kleen } 1780c3537fc2SAndi Kleen return leader; 1781c3537fc2SAndi Kleen } 1782657ee553SSong Liu 178363503dbaSJiri Olsa int perf_evlist__add_sb_event(struct evlist **evlist, 1784657ee553SSong Liu struct perf_event_attr *attr, 1785657ee553SSong Liu perf_evsel__sb_cb_t cb, 1786657ee553SSong Liu void *data) 1787657ee553SSong Liu { 178832dcd021SJiri Olsa struct evsel *evsel; 1789657ee553SSong Liu bool new_evlist = (*evlist) == NULL; 1790657ee553SSong Liu 1791657ee553SSong Liu if (*evlist == NULL) 17920f98b11cSJiri Olsa *evlist = evlist__new(); 1793657ee553SSong Liu if (*evlist == NULL) 1794657ee553SSong Liu return -1; 1795657ee553SSong Liu 1796657ee553SSong Liu if (!attr->sample_id_all) { 1797657ee553SSong Liu pr_warning("enabling sample_id_all for all side band events\n"); 1798657ee553SSong Liu attr->sample_id_all = 1; 1799657ee553SSong Liu } 1800657ee553SSong Liu 18016484d2f9SJiri Olsa evsel = perf_evsel__new_idx(attr, (*evlist)->core.nr_entries); 1802657ee553SSong Liu if (!evsel) 1803657ee553SSong Liu goto out_err; 1804657ee553SSong Liu 1805657ee553SSong Liu evsel->side_band.cb = cb; 1806657ee553SSong Liu evsel->side_band.data = data; 1807a1cf3a75SJiri Olsa evlist__add(*evlist, evsel); 1808657ee553SSong Liu return 0; 1809657ee553SSong Liu 1810657ee553SSong Liu out_err: 1811657ee553SSong Liu if (new_evlist) { 1812c12995a5SJiri Olsa evlist__delete(*evlist); 1813657ee553SSong Liu *evlist = NULL; 1814657ee553SSong Liu } 1815657ee553SSong Liu return -1; 1816657ee553SSong Liu } 1817657ee553SSong Liu 1818657ee553SSong Liu static void *perf_evlist__poll_thread(void *arg) 1819657ee553SSong Liu { 182063503dbaSJiri Olsa struct evlist *evlist = arg; 1821657ee553SSong Liu bool draining = false; 1822adc6257cSJiri Olsa int i, done = 0; 1823657ee553SSong Liu 1824adc6257cSJiri Olsa while (!done) { 1825adc6257cSJiri Olsa bool got_data = false; 1826adc6257cSJiri Olsa 1827adc6257cSJiri Olsa if (evlist->thread.done) 1828657ee553SSong Liu draining = true; 1829657ee553SSong Liu 1830657ee553SSong Liu if (!draining) 1831657ee553SSong Liu perf_evlist__poll(evlist, 1000); 1832657ee553SSong Liu 1833657ee553SSong Liu for (i = 0; i < evlist->nr_mmaps; i++) { 1834657ee553SSong Liu struct perf_mmap *map = &evlist->mmap[i]; 1835657ee553SSong Liu union perf_event *event; 1836657ee553SSong Liu 1837657ee553SSong Liu if (perf_mmap__read_init(map)) 1838657ee553SSong Liu continue; 1839657ee553SSong Liu while ((event = perf_mmap__read_event(map)) != NULL) { 184032dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 1841657ee553SSong Liu 1842657ee553SSong Liu if (evsel && evsel->side_band.cb) 1843657ee553SSong Liu evsel->side_band.cb(event, evsel->side_band.data); 1844657ee553SSong Liu else 1845657ee553SSong Liu pr_warning("cannot locate proper evsel for the side band event\n"); 1846657ee553SSong Liu 1847657ee553SSong Liu perf_mmap__consume(map); 1848adc6257cSJiri Olsa got_data = true; 1849657ee553SSong Liu } 1850657ee553SSong Liu perf_mmap__read_done(map); 1851657ee553SSong Liu } 1852adc6257cSJiri Olsa 1853adc6257cSJiri Olsa if (draining && !got_data) 1854adc6257cSJiri Olsa break; 1855657ee553SSong Liu } 1856657ee553SSong Liu return NULL; 1857657ee553SSong Liu } 1858657ee553SSong Liu 185963503dbaSJiri Olsa int perf_evlist__start_sb_thread(struct evlist *evlist, 1860657ee553SSong Liu struct target *target) 1861657ee553SSong Liu { 186232dcd021SJiri Olsa struct evsel *counter; 1863657ee553SSong Liu 1864657ee553SSong Liu if (!evlist) 1865657ee553SSong Liu return 0; 1866657ee553SSong Liu 1867657ee553SSong Liu if (perf_evlist__create_maps(evlist, target)) 1868657ee553SSong Liu goto out_delete_evlist; 1869657ee553SSong Liu 1870657ee553SSong Liu evlist__for_each_entry(evlist, counter) { 1871f72f901dSJiri Olsa if (evsel__open(counter, evlist->core.cpus, 187203617c22SJiri Olsa evlist->core.threads) < 0) 1873657ee553SSong Liu goto out_delete_evlist; 1874657ee553SSong Liu } 1875657ee553SSong Liu 1876657ee553SSong Liu if (perf_evlist__mmap(evlist, UINT_MAX)) 1877657ee553SSong Liu goto out_delete_evlist; 1878657ee553SSong Liu 1879657ee553SSong Liu evlist__for_each_entry(evlist, counter) { 1880ec7f24efSJiri Olsa if (evsel__enable(counter)) 1881657ee553SSong Liu goto out_delete_evlist; 1882657ee553SSong Liu } 1883657ee553SSong Liu 1884657ee553SSong Liu evlist->thread.done = 0; 1885657ee553SSong Liu if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist)) 1886657ee553SSong Liu goto out_delete_evlist; 1887657ee553SSong Liu 1888657ee553SSong Liu return 0; 1889657ee553SSong Liu 1890657ee553SSong Liu out_delete_evlist: 1891c12995a5SJiri Olsa evlist__delete(evlist); 1892657ee553SSong Liu evlist = NULL; 1893657ee553SSong Liu return -1; 1894657ee553SSong Liu } 1895657ee553SSong Liu 189663503dbaSJiri Olsa void perf_evlist__stop_sb_thread(struct evlist *evlist) 1897657ee553SSong Liu { 1898657ee553SSong Liu if (!evlist) 1899657ee553SSong Liu return; 1900657ee553SSong Liu evlist->thread.done = 1; 1901657ee553SSong Liu pthread_join(evlist->thread.th, NULL); 1902c12995a5SJiri Olsa evlist__delete(evlist); 1903657ee553SSong Liu } 1904