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" 13e0fcfb08SArnaldo Carvalho de Melo #include "util/mmap.h" 14f8a95309SArnaldo Carvalho de Melo #include "thread_map.h" 1512864b31SNamhyung Kim #include "target.h" 16361c99a6SArnaldo Carvalho de Melo #include "evlist.h" 17361c99a6SArnaldo Carvalho de Melo #include "evsel.h" 18e3e1a54fSAdrian Hunter #include "debug.h" 1958db1d6eSArnaldo Carvalho de Melo #include "units.h" 2020f2be1dSJiri Olsa #include <internal/lib.h> // page_size 217736627bSAndi Kleen #include "affinity.h" 22c1a604dfSArnaldo Carvalho de Melo #include "../perf.h" 2354cc54deSWang Nan #include "asm/bug.h" 24657ee553SSong Liu #include "bpf-event.h" 25da949f50SArnaldo Carvalho de Melo #include "util/string2.h" 269607ad3aSArnaldo Carvalho de Melo #include <signal.h> 2735b9d88eSArnaldo Carvalho de Melo #include <unistd.h> 28b397f846SArnaldo Carvalho de Melo #include <sched.h> 29f2a39fe8SArnaldo Carvalho de Melo #include <stdlib.h> 30361c99a6SArnaldo Carvalho de Melo 3150d08e47SArnaldo Carvalho de Melo #include "parse-events.h" 324b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 3350d08e47SArnaldo Carvalho de Melo 34bafae98eSArnaldo Carvalho de Melo #include <fcntl.h> 3586a5e0c2SArnaldo Carvalho de Melo #include <sys/ioctl.h> 36f8a95309SArnaldo Carvalho de Melo #include <sys/mman.h> 37f8a95309SArnaldo Carvalho de Melo 3870db7533SArnaldo Carvalho de Melo #include <linux/bitops.h> 3970db7533SArnaldo Carvalho de Melo #include <linux/hash.h> 400389cd1fSArnaldo Carvalho de Melo #include <linux/log2.h> 418dd2a131SJiri Olsa #include <linux/err.h> 428520a98dSArnaldo Carvalho de Melo #include <linux/string.h> 437f7c536fSArnaldo Carvalho de Melo #include <linux/zalloc.h> 444562a739SJiri Olsa #include <perf/evlist.h> 4588761fa1SJiri Olsa #include <perf/evsel.h> 469c3516d1SJiri Olsa #include <perf/cpumap.h> 477728fa0cSJiri Olsa #include <perf/mmap.h> 4870db7533SArnaldo Carvalho de Melo 49e14e5497SArnaldo Carvalho de Melo #include <internal/xyarray.h> 50e14e5497SArnaldo Carvalho de Melo 51748fe088SArnaldo Carvalho de Melo #ifdef LACKS_SIGQUEUE_PROTOTYPE 52748fe088SArnaldo Carvalho de Melo int sigqueue(pid_t pid, int sig, const union sigval value); 53748fe088SArnaldo Carvalho de Melo #endif 54748fe088SArnaldo Carvalho de Melo 559dfcb759SJiri Olsa #define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) 568cd36f3eSJiri Olsa #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) 57f8a95309SArnaldo Carvalho de Melo 5852c86bcaSJiri Olsa void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, 599749b90eSJiri Olsa struct perf_thread_map *threads) 60361c99a6SArnaldo Carvalho de Melo { 614562a739SJiri Olsa perf_evlist__init(&evlist->core); 62453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads); 6335b9d88eSArnaldo Carvalho de Melo evlist->workload.pid = -1; 6454cc54deSWang Nan evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; 65361c99a6SArnaldo Carvalho de Melo } 66361c99a6SArnaldo Carvalho de Melo 670f98b11cSJiri Olsa struct evlist *evlist__new(void) 68ef1d1af2SArnaldo Carvalho de Melo { 6963503dbaSJiri Olsa struct evlist *evlist = zalloc(sizeof(*evlist)); 70ef1d1af2SArnaldo Carvalho de Melo 71ef1d1af2SArnaldo Carvalho de Melo if (evlist != NULL) 7252c86bcaSJiri Olsa evlist__init(evlist, NULL, NULL); 73ef1d1af2SArnaldo Carvalho de Melo 74361c99a6SArnaldo Carvalho de Melo return evlist; 75361c99a6SArnaldo Carvalho de Melo } 76361c99a6SArnaldo Carvalho de Melo 7763503dbaSJiri Olsa struct evlist *perf_evlist__new_default(void) 78b22d54b0SJiri Olsa { 790f98b11cSJiri Olsa struct evlist *evlist = evlist__new(); 80b22d54b0SJiri Olsa 81b22d54b0SJiri Olsa if (evlist && perf_evlist__add_default(evlist)) { 82c12995a5SJiri Olsa evlist__delete(evlist); 83b22d54b0SJiri Olsa evlist = NULL; 84b22d54b0SJiri Olsa } 85b22d54b0SJiri Olsa 86b22d54b0SJiri Olsa return evlist; 87b22d54b0SJiri Olsa } 88b22d54b0SJiri Olsa 8963503dbaSJiri Olsa struct evlist *perf_evlist__new_dummy(void) 905bae0250SArnaldo Carvalho de Melo { 910f98b11cSJiri Olsa struct evlist *evlist = evlist__new(); 925bae0250SArnaldo Carvalho de Melo 935bae0250SArnaldo Carvalho de Melo if (evlist && perf_evlist__add_dummy(evlist)) { 94c12995a5SJiri Olsa evlist__delete(evlist); 955bae0250SArnaldo Carvalho de Melo evlist = NULL; 965bae0250SArnaldo Carvalho de Melo } 975bae0250SArnaldo Carvalho de Melo 985bae0250SArnaldo Carvalho de Melo return evlist; 995bae0250SArnaldo Carvalho de Melo } 1005bae0250SArnaldo Carvalho de Melo 10175562573SAdrian Hunter /** 10275562573SAdrian Hunter * perf_evlist__set_id_pos - set the positions of event ids. 10375562573SAdrian Hunter * @evlist: selected event list 10475562573SAdrian Hunter * 10575562573SAdrian Hunter * Events with compatible sample types all have the same id_pos 10675562573SAdrian Hunter * and is_pos. For convenience, put a copy on evlist. 10775562573SAdrian Hunter */ 10863503dbaSJiri Olsa void perf_evlist__set_id_pos(struct evlist *evlist) 10975562573SAdrian Hunter { 110515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist); 11175562573SAdrian Hunter 11275562573SAdrian Hunter evlist->id_pos = first->id_pos; 11375562573SAdrian Hunter evlist->is_pos = first->is_pos; 11475562573SAdrian Hunter } 11575562573SAdrian Hunter 11663503dbaSJiri Olsa static void perf_evlist__update_id_pos(struct evlist *evlist) 117733cd2feSAdrian Hunter { 11832dcd021SJiri Olsa struct evsel *evsel; 119733cd2feSAdrian Hunter 120e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 121733cd2feSAdrian Hunter perf_evsel__calc_id_pos(evsel); 122733cd2feSAdrian Hunter 123733cd2feSAdrian Hunter perf_evlist__set_id_pos(evlist); 124733cd2feSAdrian Hunter } 125733cd2feSAdrian Hunter 126e6b1878dSJiri Olsa static void evlist__purge(struct evlist *evlist) 127361c99a6SArnaldo Carvalho de Melo { 12832dcd021SJiri Olsa struct evsel *pos, *n; 129361c99a6SArnaldo Carvalho de Melo 130e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_safe(evlist, n, pos) { 131b27c4eceSJiri Olsa list_del_init(&pos->core.node); 132d49e4695SArnaldo Carvalho de Melo pos->evlist = NULL; 1335eb2dd2aSJiri Olsa evsel__delete(pos); 134361c99a6SArnaldo Carvalho de Melo } 135361c99a6SArnaldo Carvalho de Melo 1366484d2f9SJiri Olsa evlist->core.nr_entries = 0; 137361c99a6SArnaldo Carvalho de Melo } 138361c99a6SArnaldo Carvalho de Melo 139470579b0SJiri Olsa void evlist__exit(struct evlist *evlist) 140ef1d1af2SArnaldo Carvalho de Melo { 14104662523SArnaldo Carvalho de Melo zfree(&evlist->mmap); 1420b72d69aSWang Nan zfree(&evlist->overwrite_mmap); 14393dd6e28SJiri Olsa perf_evlist__exit(&evlist->core); 144ef1d1af2SArnaldo Carvalho de Melo } 145ef1d1af2SArnaldo Carvalho de Melo 146c12995a5SJiri Olsa void evlist__delete(struct evlist *evlist) 147361c99a6SArnaldo Carvalho de Melo { 1480b04b3dcSArnaldo Carvalho de Melo if (evlist == NULL) 1490b04b3dcSArnaldo Carvalho de Melo return; 1500b04b3dcSArnaldo Carvalho de Melo 151db6b7b13SJiri Olsa evlist__munmap(evlist); 152750b4edeSJiri Olsa evlist__close(evlist); 153e6b1878dSJiri Olsa evlist__purge(evlist); 154470579b0SJiri Olsa evlist__exit(evlist); 155361c99a6SArnaldo Carvalho de Melo free(evlist); 156361c99a6SArnaldo Carvalho de Melo } 157361c99a6SArnaldo Carvalho de Melo 158a1cf3a75SJiri Olsa void evlist__add(struct evlist *evlist, struct evsel *entry) 159361c99a6SArnaldo Carvalho de Melo { 160d49e4695SArnaldo Carvalho de Melo entry->evlist = evlist; 1616484d2f9SJiri Olsa entry->idx = evlist->core.nr_entries; 16260b0896cSAdrian Hunter entry->tracking = !entry->idx; 163ef503831SArnaldo Carvalho de Melo 1646484d2f9SJiri Olsa perf_evlist__add(&evlist->core, &entry->core); 1656484d2f9SJiri Olsa 1666484d2f9SJiri Olsa if (evlist->core.nr_entries == 1) 16775562573SAdrian Hunter perf_evlist__set_id_pos(evlist); 168361c99a6SArnaldo Carvalho de Melo } 169361c99a6SArnaldo Carvalho de Melo 17016251027SJiri Olsa void evlist__remove(struct evlist *evlist, struct evsel *evsel) 1714768230aSAdrian Hunter { 1724768230aSAdrian Hunter evsel->evlist = NULL; 17352e22fb8SJiri Olsa perf_evlist__remove(&evlist->core, &evsel->core); 1744768230aSAdrian Hunter } 1754768230aSAdrian Hunter 17663503dbaSJiri Olsa void perf_evlist__splice_list_tail(struct evlist *evlist, 177f114d6efSAdrian Hunter struct list_head *list) 17850d08e47SArnaldo Carvalho de Melo { 17932dcd021SJiri Olsa struct evsel *evsel, *temp; 18075562573SAdrian Hunter 181e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry_safe(list, temp, evsel) { 182b27c4eceSJiri Olsa list_del_init(&evsel->core.node); 183a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 184f114d6efSAdrian Hunter } 18550d08e47SArnaldo Carvalho de Melo } 18650d08e47SArnaldo Carvalho de Melo 187c0e53476SArnaldo Carvalho de Melo int __evlist__set_tracepoints_handlers(struct evlist *evlist, 188c0e53476SArnaldo Carvalho de Melo const struct evsel_str_handler *assocs, size_t nr_assocs) 189c0e53476SArnaldo Carvalho de Melo { 190c0e53476SArnaldo Carvalho de Melo struct evsel *evsel; 191c0e53476SArnaldo Carvalho de Melo size_t i; 192c0e53476SArnaldo Carvalho de Melo int err; 193c0e53476SArnaldo Carvalho de Melo 194c0e53476SArnaldo Carvalho de Melo for (i = 0; i < nr_assocs; i++) { 195c0e53476SArnaldo Carvalho de Melo // Adding a handler for an event not in this evlist, just ignore it. 196c0e53476SArnaldo Carvalho de Melo evsel = perf_evlist__find_tracepoint_by_name(evlist, assocs[i].name); 197c0e53476SArnaldo Carvalho de Melo if (evsel == NULL) 198c0e53476SArnaldo Carvalho de Melo continue; 199c0e53476SArnaldo Carvalho de Melo 200c0e53476SArnaldo Carvalho de Melo err = -EEXIST; 201c0e53476SArnaldo Carvalho de Melo if (evsel->handler != NULL) 202c0e53476SArnaldo Carvalho de Melo goto out; 203c0e53476SArnaldo Carvalho de Melo evsel->handler = assocs[i].handler; 204c0e53476SArnaldo Carvalho de Melo } 205c0e53476SArnaldo Carvalho de Melo 206c0e53476SArnaldo Carvalho de Melo err = 0; 207c0e53476SArnaldo Carvalho de Melo out: 208c0e53476SArnaldo Carvalho de Melo return err; 209c0e53476SArnaldo Carvalho de Melo } 210c0e53476SArnaldo Carvalho de Melo 21163dab225SArnaldo Carvalho de Melo void __perf_evlist__set_leader(struct list_head *list) 21263dab225SArnaldo Carvalho de Melo { 21332dcd021SJiri Olsa struct evsel *evsel, *leader; 21463dab225SArnaldo Carvalho de Melo 215b27c4eceSJiri Olsa leader = list_entry(list->next, struct evsel, core.node); 216b27c4eceSJiri Olsa evsel = list_entry(list->prev, struct evsel, core.node); 21797f63e4aSNamhyung Kim 2185643b1a5SJiri Olsa leader->core.nr_members = evsel->idx - leader->idx + 1; 21963dab225SArnaldo Carvalho de Melo 220e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry(list, evsel) { 22163dab225SArnaldo Carvalho de Melo evsel->leader = leader; 22263dab225SArnaldo Carvalho de Melo } 22363dab225SArnaldo Carvalho de Melo } 22463dab225SArnaldo Carvalho de Melo 22563503dbaSJiri Olsa void perf_evlist__set_leader(struct evlist *evlist) 2266a4bb04cSJiri Olsa { 2276484d2f9SJiri Olsa if (evlist->core.nr_entries) { 2286484d2f9SJiri Olsa evlist->nr_groups = evlist->core.nr_entries > 1 ? 1 : 0; 229ce9036a6SJiri Olsa __perf_evlist__set_leader(&evlist->core.entries); 2306a4bb04cSJiri Olsa } 23197f63e4aSNamhyung Kim } 2326a4bb04cSJiri Olsa 23363503dbaSJiri Olsa int __perf_evlist__add_default(struct evlist *evlist, bool precise) 234361c99a6SArnaldo Carvalho de Melo { 23532dcd021SJiri Olsa struct evsel *evsel = perf_evsel__new_cycles(precise); 236361c99a6SArnaldo Carvalho de Melo 237361c99a6SArnaldo Carvalho de Melo if (evsel == NULL) 2387c48dcfdSArnaldo Carvalho de Melo return -ENOMEM; 239361c99a6SArnaldo Carvalho de Melo 240a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 241361c99a6SArnaldo Carvalho de Melo return 0; 242361c99a6SArnaldo Carvalho de Melo } 2435c581041SArnaldo Carvalho de Melo 24463503dbaSJiri Olsa int perf_evlist__add_dummy(struct evlist *evlist) 2455bae0250SArnaldo Carvalho de Melo { 2465bae0250SArnaldo Carvalho de Melo struct perf_event_attr attr = { 2475bae0250SArnaldo Carvalho de Melo .type = PERF_TYPE_SOFTWARE, 2485bae0250SArnaldo Carvalho de Melo .config = PERF_COUNT_SW_DUMMY, 2495bae0250SArnaldo Carvalho de Melo .size = sizeof(attr), /* to capture ABI version */ 2505bae0250SArnaldo Carvalho de Melo }; 2516484d2f9SJiri Olsa struct evsel *evsel = perf_evsel__new_idx(&attr, evlist->core.nr_entries); 2525bae0250SArnaldo Carvalho de Melo 2535bae0250SArnaldo Carvalho de Melo if (evsel == NULL) 2545bae0250SArnaldo Carvalho de Melo return -ENOMEM; 2555bae0250SArnaldo Carvalho de Melo 256a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 2575bae0250SArnaldo Carvalho de Melo return 0; 2585bae0250SArnaldo Carvalho de Melo } 2595bae0250SArnaldo Carvalho de Melo 260a1cf3a75SJiri Olsa static int evlist__add_attrs(struct evlist *evlist, 26150d08e47SArnaldo Carvalho de Melo struct perf_event_attr *attrs, size_t nr_attrs) 26250d08e47SArnaldo Carvalho de Melo { 26332dcd021SJiri Olsa struct evsel *evsel, *n; 26450d08e47SArnaldo Carvalho de Melo LIST_HEAD(head); 26550d08e47SArnaldo Carvalho de Melo size_t i; 26650d08e47SArnaldo Carvalho de Melo 26750d08e47SArnaldo Carvalho de Melo for (i = 0; i < nr_attrs; i++) { 2686484d2f9SJiri Olsa evsel = perf_evsel__new_idx(attrs + i, evlist->core.nr_entries + i); 26950d08e47SArnaldo Carvalho de Melo if (evsel == NULL) 27050d08e47SArnaldo Carvalho de Melo goto out_delete_partial_list; 271b27c4eceSJiri Olsa list_add_tail(&evsel->core.node, &head); 27250d08e47SArnaldo Carvalho de Melo } 27350d08e47SArnaldo Carvalho de Melo 274f114d6efSAdrian Hunter perf_evlist__splice_list_tail(evlist, &head); 27550d08e47SArnaldo Carvalho de Melo 27650d08e47SArnaldo Carvalho de Melo return 0; 27750d08e47SArnaldo Carvalho de Melo 27850d08e47SArnaldo Carvalho de Melo out_delete_partial_list: 279e5cadb93SArnaldo Carvalho de Melo __evlist__for_each_entry_safe(&head, n, evsel) 2805eb2dd2aSJiri Olsa evsel__delete(evsel); 28150d08e47SArnaldo Carvalho de Melo return -1; 28250d08e47SArnaldo Carvalho de Melo } 28350d08e47SArnaldo Carvalho de Melo 28463503dbaSJiri Olsa int __perf_evlist__add_default_attrs(struct evlist *evlist, 28579695e1bSArnaldo Carvalho de Melo struct perf_event_attr *attrs, size_t nr_attrs) 28679695e1bSArnaldo Carvalho de Melo { 28779695e1bSArnaldo Carvalho de Melo size_t i; 28879695e1bSArnaldo Carvalho de Melo 28979695e1bSArnaldo Carvalho de Melo for (i = 0; i < nr_attrs; i++) 29079695e1bSArnaldo Carvalho de Melo event_attr_init(attrs + i); 29179695e1bSArnaldo Carvalho de Melo 292a1cf3a75SJiri Olsa return evlist__add_attrs(evlist, attrs, nr_attrs); 29379695e1bSArnaldo Carvalho de Melo } 29479695e1bSArnaldo Carvalho de Melo 29532dcd021SJiri Olsa struct evsel * 29663503dbaSJiri Olsa perf_evlist__find_tracepoint_by_id(struct evlist *evlist, int id) 297ee29be62SArnaldo Carvalho de Melo { 29832dcd021SJiri Olsa struct evsel *evsel; 299ee29be62SArnaldo Carvalho de Melo 300e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 3011fc632ceSJiri Olsa if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT && 3021fc632ceSJiri Olsa (int)evsel->core.attr.config == id) 303ee29be62SArnaldo Carvalho de Melo return evsel; 304ee29be62SArnaldo Carvalho de Melo } 305ee29be62SArnaldo Carvalho de Melo 306ee29be62SArnaldo Carvalho de Melo return NULL; 307ee29be62SArnaldo Carvalho de Melo } 308ee29be62SArnaldo Carvalho de Melo 30932dcd021SJiri Olsa struct evsel * 31063503dbaSJiri Olsa perf_evlist__find_tracepoint_by_name(struct evlist *evlist, 311a2f2804aSDavid Ahern const char *name) 312a2f2804aSDavid Ahern { 31332dcd021SJiri Olsa struct evsel *evsel; 314a2f2804aSDavid Ahern 315e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 3161fc632ceSJiri Olsa if ((evsel->core.attr.type == PERF_TYPE_TRACEPOINT) && 317a2f2804aSDavid Ahern (strcmp(evsel->name, name) == 0)) 318a2f2804aSDavid Ahern return evsel; 319a2f2804aSDavid Ahern } 320a2f2804aSDavid Ahern 321a2f2804aSDavid Ahern return NULL; 322a2f2804aSDavid Ahern } 323a2f2804aSDavid Ahern 32463503dbaSJiri Olsa int perf_evlist__add_newtp(struct evlist *evlist, 32539876e7dSArnaldo Carvalho de Melo const char *sys, const char *name, void *handler) 32639876e7dSArnaldo Carvalho de Melo { 32732dcd021SJiri Olsa struct evsel *evsel = perf_evsel__newtp(sys, name); 32839876e7dSArnaldo Carvalho de Melo 3298dd2a131SJiri Olsa if (IS_ERR(evsel)) 33039876e7dSArnaldo Carvalho de Melo return -1; 33139876e7dSArnaldo Carvalho de Melo 332744a9719SArnaldo Carvalho de Melo evsel->handler = handler; 333a1cf3a75SJiri Olsa evlist__add(evlist, evsel); 33439876e7dSArnaldo Carvalho de Melo return 0; 33539876e7dSArnaldo Carvalho de Melo } 33639876e7dSArnaldo Carvalho de Melo 33763503dbaSJiri Olsa static int perf_evlist__nr_threads(struct evlist *evlist, 33832dcd021SJiri Olsa struct evsel *evsel) 339bf8e8f4bSAdrian Hunter { 340648b5af3SJiri Olsa if (evsel->core.system_wide) 341bf8e8f4bSAdrian Hunter return 1; 342bf8e8f4bSAdrian Hunter else 343a2f354e3SJiri Olsa return perf_thread_map__nr(evlist->core.threads); 344bf8e8f4bSAdrian Hunter } 345bf8e8f4bSAdrian Hunter 346a8cbe40fSAndi Kleen void evlist__cpu_iter_start(struct evlist *evlist) 347a8cbe40fSAndi Kleen { 348a8cbe40fSAndi Kleen struct evsel *pos; 349a8cbe40fSAndi Kleen 350a8cbe40fSAndi Kleen /* 351a8cbe40fSAndi Kleen * Reset the per evsel cpu_iter. This is needed because 352a8cbe40fSAndi Kleen * each evsel's cpumap may have a different index space, 353a8cbe40fSAndi Kleen * and some operations need the index to modify 354a8cbe40fSAndi Kleen * the FD xyarray (e.g. open, close) 355a8cbe40fSAndi Kleen */ 356a8cbe40fSAndi Kleen evlist__for_each_entry(evlist, pos) 357a8cbe40fSAndi Kleen pos->cpu_iter = 0; 358a8cbe40fSAndi Kleen } 359a8cbe40fSAndi Kleen 360a8cbe40fSAndi Kleen bool evsel__cpu_iter_skip_no_inc(struct evsel *ev, int cpu) 361a8cbe40fSAndi Kleen { 362a8cbe40fSAndi Kleen if (ev->cpu_iter >= ev->core.cpus->nr) 363a8cbe40fSAndi Kleen return true; 364a8cbe40fSAndi Kleen if (cpu >= 0 && ev->core.cpus->map[ev->cpu_iter] != cpu) 365a8cbe40fSAndi Kleen return true; 366a8cbe40fSAndi Kleen return false; 367a8cbe40fSAndi Kleen } 368a8cbe40fSAndi Kleen 369a8cbe40fSAndi Kleen bool evsel__cpu_iter_skip(struct evsel *ev, int cpu) 370a8cbe40fSAndi Kleen { 371a8cbe40fSAndi Kleen if (!evsel__cpu_iter_skip_no_inc(ev, cpu)) { 372a8cbe40fSAndi Kleen ev->cpu_iter++; 373a8cbe40fSAndi Kleen return false; 374a8cbe40fSAndi Kleen } 375a8cbe40fSAndi Kleen return true; 376a8cbe40fSAndi Kleen } 377a8cbe40fSAndi Kleen 378e74676deSJiri Olsa void evlist__disable(struct evlist *evlist) 3794152ab37SArnaldo Carvalho de Melo { 38032dcd021SJiri Olsa struct evsel *pos; 381704e2f5bSAndi Kleen struct affinity affinity; 382704e2f5bSAndi Kleen int cpu, i; 383704e2f5bSAndi Kleen 384704e2f5bSAndi Kleen if (affinity__setup(&affinity) < 0) 385704e2f5bSAndi Kleen return; 386704e2f5bSAndi Kleen 387704e2f5bSAndi Kleen evlist__for_each_cpu(evlist, i, cpu) { 388704e2f5bSAndi Kleen affinity__set(&affinity, cpu); 3894152ab37SArnaldo Carvalho de Melo 390e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 391704e2f5bSAndi Kleen if (evsel__cpu_iter_skip(pos, cpu)) 392704e2f5bSAndi Kleen continue; 3939dfcb759SJiri Olsa if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->core.fd) 3943fe4430dSJiri Olsa continue; 395704e2f5bSAndi Kleen evsel__disable_cpu(pos, pos->cpu_iter - 1); 396704e2f5bSAndi Kleen } 397704e2f5bSAndi Kleen } 398704e2f5bSAndi Kleen affinity__cleanup(&affinity); 399704e2f5bSAndi Kleen evlist__for_each_entry(evlist, pos) { 400704e2f5bSAndi Kleen if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) 401704e2f5bSAndi Kleen continue; 402704e2f5bSAndi Kleen pos->disabled = true; 4034152ab37SArnaldo Carvalho de Melo } 4042b56bcfbSArnaldo Carvalho de Melo 4052b56bcfbSArnaldo Carvalho de Melo evlist->enabled = false; 4064152ab37SArnaldo Carvalho de Melo } 4074152ab37SArnaldo Carvalho de Melo 4081c87f165SJiri Olsa void evlist__enable(struct evlist *evlist) 409764e16a3SDavid Ahern { 41032dcd021SJiri Olsa struct evsel *pos; 411704e2f5bSAndi Kleen struct affinity affinity; 412704e2f5bSAndi Kleen int cpu, i; 413764e16a3SDavid Ahern 414704e2f5bSAndi Kleen if (affinity__setup(&affinity) < 0) 415704e2f5bSAndi Kleen return; 416704e2f5bSAndi Kleen 417704e2f5bSAndi Kleen evlist__for_each_cpu(evlist, i, cpu) { 418704e2f5bSAndi Kleen affinity__set(&affinity, cpu); 419704e2f5bSAndi Kleen 420704e2f5bSAndi Kleen evlist__for_each_entry(evlist, pos) { 421704e2f5bSAndi Kleen if (evsel__cpu_iter_skip(pos, cpu)) 422704e2f5bSAndi Kleen continue; 423704e2f5bSAndi Kleen if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) 424704e2f5bSAndi Kleen continue; 425704e2f5bSAndi Kleen evsel__enable_cpu(pos, pos->cpu_iter - 1); 426704e2f5bSAndi Kleen } 427704e2f5bSAndi Kleen } 428704e2f5bSAndi Kleen affinity__cleanup(&affinity); 429e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 4309dfcb759SJiri Olsa if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) 4313fe4430dSJiri Olsa continue; 432704e2f5bSAndi Kleen pos->disabled = false; 433764e16a3SDavid Ahern } 4342b56bcfbSArnaldo Carvalho de Melo 4352b56bcfbSArnaldo Carvalho de Melo evlist->enabled = true; 4362b56bcfbSArnaldo Carvalho de Melo } 4372b56bcfbSArnaldo Carvalho de Melo 43863503dbaSJiri Olsa void perf_evlist__toggle_enable(struct evlist *evlist) 4392b56bcfbSArnaldo Carvalho de Melo { 440e74676deSJiri Olsa (evlist->enabled ? evlist__disable : evlist__enable)(evlist); 441764e16a3SDavid Ahern } 442764e16a3SDavid Ahern 44363503dbaSJiri Olsa static int perf_evlist__enable_event_cpu(struct evlist *evlist, 44432dcd021SJiri Olsa struct evsel *evsel, int cpu) 4451c65056cSAdrian Hunter { 44618ef15c6SArnaldo Carvalho de Melo int thread; 4471c65056cSAdrian Hunter int nr_threads = perf_evlist__nr_threads(evlist, evsel); 4481c65056cSAdrian Hunter 4499dfcb759SJiri Olsa if (!evsel->core.fd) 4501c65056cSAdrian Hunter return -EINVAL; 4511c65056cSAdrian Hunter 4521c65056cSAdrian Hunter for (thread = 0; thread < nr_threads; thread++) { 45318ef15c6SArnaldo Carvalho de Melo int err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 4541c65056cSAdrian Hunter if (err) 4551c65056cSAdrian Hunter return err; 4561c65056cSAdrian Hunter } 4571c65056cSAdrian Hunter return 0; 4581c65056cSAdrian Hunter } 4591c65056cSAdrian Hunter 46063503dbaSJiri Olsa static int perf_evlist__enable_event_thread(struct evlist *evlist, 46132dcd021SJiri Olsa struct evsel *evsel, 4621c65056cSAdrian Hunter int thread) 4631c65056cSAdrian Hunter { 46418ef15c6SArnaldo Carvalho de Melo int cpu; 4656549cd8fSJiri Olsa int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); 4661c65056cSAdrian Hunter 4679dfcb759SJiri Olsa if (!evsel->core.fd) 4681c65056cSAdrian Hunter return -EINVAL; 4691c65056cSAdrian Hunter 4701c65056cSAdrian Hunter for (cpu = 0; cpu < nr_cpus; cpu++) { 47118ef15c6SArnaldo Carvalho de Melo int err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 4721c65056cSAdrian Hunter if (err) 4731c65056cSAdrian Hunter return err; 4741c65056cSAdrian Hunter } 4751c65056cSAdrian Hunter return 0; 4761c65056cSAdrian Hunter } 4771c65056cSAdrian Hunter 47863503dbaSJiri Olsa int perf_evlist__enable_event_idx(struct evlist *evlist, 47932dcd021SJiri Olsa struct evsel *evsel, int idx) 4801c65056cSAdrian Hunter { 481315c0a1fSJiri Olsa bool per_cpu_mmaps = !perf_cpu_map__empty(evlist->core.cpus); 4821c65056cSAdrian Hunter 4831c65056cSAdrian Hunter if (per_cpu_mmaps) 4841c65056cSAdrian Hunter return perf_evlist__enable_event_cpu(evlist, evsel, idx); 4851c65056cSAdrian Hunter else 4861c65056cSAdrian Hunter return perf_evlist__enable_event_thread(evlist, evsel, idx); 4871c65056cSAdrian Hunter } 4881c65056cSAdrian Hunter 489f4009e7bSJiri Olsa int evlist__add_pollfd(struct evlist *evlist, int fd) 490e4b356b5SArnaldo Carvalho de Melo { 491f4009e7bSJiri Olsa return perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN); 492e4b356b5SArnaldo Carvalho de Melo } 4931b85337dSArnaldo Carvalho de Melo 494f4009e7bSJiri Olsa int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) 4951ddec7f0SArnaldo Carvalho de Melo { 49684227cb1SJiri Olsa return perf_evlist__filter_pollfd(&evlist->core, revents_and_mask); 4971ddec7f0SArnaldo Carvalho de Melo } 4981ddec7f0SArnaldo Carvalho de Melo 49980ab2987SJiri Olsa int evlist__poll(struct evlist *evlist, int timeout) 500f66a889dSArnaldo Carvalho de Melo { 50180ab2987SJiri Olsa return perf_evlist__poll(&evlist->core, timeout); 502f66a889dSArnaldo Carvalho de Melo } 503f66a889dSArnaldo Carvalho de Melo 50463503dbaSJiri Olsa struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id) 50570db7533SArnaldo Carvalho de Melo { 50670db7533SArnaldo Carvalho de Melo struct hlist_head *head; 50770db7533SArnaldo Carvalho de Melo struct perf_sample_id *sid; 50870db7533SArnaldo Carvalho de Melo int hash; 50970db7533SArnaldo Carvalho de Melo 51070db7533SArnaldo Carvalho de Melo hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 5111d5af02dSJiri Olsa head = &evlist->core.heads[hash]; 51270db7533SArnaldo Carvalho de Melo 513b67bfe0dSSasha Levin hlist_for_each_entry(sid, head, node) 51470db7533SArnaldo Carvalho de Melo if (sid->id == id) 515932a3594SJiri Olsa return sid; 516932a3594SJiri Olsa 517932a3594SJiri Olsa return NULL; 518932a3594SJiri Olsa } 519932a3594SJiri Olsa 52063503dbaSJiri Olsa struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) 521932a3594SJiri Olsa { 522932a3594SJiri Olsa struct perf_sample_id *sid; 523932a3594SJiri Olsa 5246484d2f9SJiri Olsa if (evlist->core.nr_entries == 1 || !id) 525515dbe48SJiri Olsa return evlist__first(evlist); 526932a3594SJiri Olsa 527932a3594SJiri Olsa sid = perf_evlist__id2sid(evlist, id); 528932a3594SJiri Olsa if (sid) 52970c20369SJiri Olsa return container_of(sid->evsel, struct evsel, core); 53030e68bccSNamhyung Kim 53130e68bccSNamhyung Kim if (!perf_evlist__sample_id_all(evlist)) 532515dbe48SJiri Olsa return evlist__first(evlist); 53330e68bccSNamhyung Kim 53470db7533SArnaldo Carvalho de Melo return NULL; 53570db7533SArnaldo Carvalho de Melo } 53604391debSArnaldo Carvalho de Melo 53763503dbaSJiri Olsa struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, 538dddcf6abSAdrian Hunter u64 id) 539dddcf6abSAdrian Hunter { 540dddcf6abSAdrian Hunter struct perf_sample_id *sid; 541dddcf6abSAdrian Hunter 542dddcf6abSAdrian Hunter if (!id) 543dddcf6abSAdrian Hunter return NULL; 544dddcf6abSAdrian Hunter 545dddcf6abSAdrian Hunter sid = perf_evlist__id2sid(evlist, id); 546dddcf6abSAdrian Hunter if (sid) 54770c20369SJiri Olsa return container_of(sid->evsel, struct evsel, core); 548dddcf6abSAdrian Hunter 549dddcf6abSAdrian Hunter return NULL; 550dddcf6abSAdrian Hunter } 551dddcf6abSAdrian Hunter 55263503dbaSJiri Olsa static int perf_evlist__event2id(struct evlist *evlist, 55375562573SAdrian Hunter union perf_event *event, u64 *id) 55475562573SAdrian Hunter { 555b1fcd190SJiri Olsa const __u64 *array = event->sample.array; 55675562573SAdrian Hunter ssize_t n; 55775562573SAdrian Hunter 55875562573SAdrian Hunter n = (event->header.size - sizeof(event->header)) >> 3; 55975562573SAdrian Hunter 56075562573SAdrian Hunter if (event->header.type == PERF_RECORD_SAMPLE) { 56175562573SAdrian Hunter if (evlist->id_pos >= n) 56275562573SAdrian Hunter return -1; 56375562573SAdrian Hunter *id = array[evlist->id_pos]; 56475562573SAdrian Hunter } else { 56575562573SAdrian Hunter if (evlist->is_pos > n) 56675562573SAdrian Hunter return -1; 56775562573SAdrian Hunter n -= evlist->is_pos; 56875562573SAdrian Hunter *id = array[n]; 56975562573SAdrian Hunter } 57075562573SAdrian Hunter return 0; 57175562573SAdrian Hunter } 57275562573SAdrian Hunter 57363503dbaSJiri Olsa struct evsel *perf_evlist__event2evsel(struct evlist *evlist, 57475562573SAdrian Hunter union perf_event *event) 57575562573SAdrian Hunter { 576515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist); 57775562573SAdrian Hunter struct hlist_head *head; 57875562573SAdrian Hunter struct perf_sample_id *sid; 57975562573SAdrian Hunter int hash; 58075562573SAdrian Hunter u64 id; 58175562573SAdrian Hunter 5826484d2f9SJiri Olsa if (evlist->core.nr_entries == 1) 58398be6966SAdrian Hunter return first; 58498be6966SAdrian Hunter 5851fc632ceSJiri Olsa if (!first->core.attr.sample_id_all && 58698be6966SAdrian Hunter event->header.type != PERF_RECORD_SAMPLE) 58798be6966SAdrian Hunter return first; 58875562573SAdrian Hunter 58975562573SAdrian Hunter if (perf_evlist__event2id(evlist, event, &id)) 59075562573SAdrian Hunter return NULL; 59175562573SAdrian Hunter 59275562573SAdrian Hunter /* Synthesized events have an id of zero */ 59375562573SAdrian Hunter if (!id) 59498be6966SAdrian Hunter return first; 59575562573SAdrian Hunter 59675562573SAdrian Hunter hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 5971d5af02dSJiri Olsa head = &evlist->core.heads[hash]; 59875562573SAdrian Hunter 59975562573SAdrian Hunter hlist_for_each_entry(sid, head, node) { 60075562573SAdrian Hunter if (sid->id == id) 60170c20369SJiri Olsa return container_of(sid->evsel, struct evsel, core); 60275562573SAdrian Hunter } 60375562573SAdrian Hunter return NULL; 60475562573SAdrian Hunter } 60575562573SAdrian Hunter 60663503dbaSJiri Olsa static int perf_evlist__set_paused(struct evlist *evlist, bool value) 60765aea233SWang Nan { 60865aea233SWang Nan int i; 60965aea233SWang Nan 6100b72d69aSWang Nan if (!evlist->overwrite_mmap) 611078c3386SWang Nan return 0; 612078c3386SWang Nan 613c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) { 6142cf07b29SJiri Olsa int fd = evlist->overwrite_mmap[i].core.fd; 61565aea233SWang Nan int err; 61665aea233SWang Nan 61765aea233SWang Nan if (fd < 0) 61865aea233SWang Nan continue; 61965aea233SWang Nan err = ioctl(fd, PERF_EVENT_IOC_PAUSE_OUTPUT, value ? 1 : 0); 62065aea233SWang Nan if (err) 62165aea233SWang Nan return err; 62265aea233SWang Nan } 62365aea233SWang Nan return 0; 62465aea233SWang Nan } 62565aea233SWang Nan 62663503dbaSJiri Olsa static int perf_evlist__pause(struct evlist *evlist) 62765aea233SWang Nan { 62865aea233SWang Nan return perf_evlist__set_paused(evlist, true); 62965aea233SWang Nan } 63065aea233SWang Nan 63163503dbaSJiri Olsa static int perf_evlist__resume(struct evlist *evlist) 63265aea233SWang Nan { 63365aea233SWang Nan return perf_evlist__set_paused(evlist, false); 63465aea233SWang Nan } 63565aea233SWang Nan 636db6b7b13SJiri Olsa static void evlist__munmap_nofree(struct evlist *evlist) 637f8a95309SArnaldo Carvalho de Melo { 638aece948fSArnaldo Carvalho de Melo int i; 639f8a95309SArnaldo Carvalho de Melo 640b2cb615dSWang Nan if (evlist->mmap) 641c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) 64280e53d11SJiri Olsa perf_mmap__munmap(&evlist->mmap[i].core); 643b2cb615dSWang Nan 6440b72d69aSWang Nan if (evlist->overwrite_mmap) 645c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) 64680e53d11SJiri Olsa perf_mmap__munmap(&evlist->overwrite_mmap[i].core); 647a1f72618SWang Nan } 648aece948fSArnaldo Carvalho de Melo 649db6b7b13SJiri Olsa void evlist__munmap(struct evlist *evlist) 650a1f72618SWang Nan { 651db6b7b13SJiri Olsa evlist__munmap_nofree(evlist); 65204662523SArnaldo Carvalho de Melo zfree(&evlist->mmap); 6530b72d69aSWang Nan zfree(&evlist->overwrite_mmap); 654f8a95309SArnaldo Carvalho de Melo } 655f8a95309SArnaldo Carvalho de Melo 65680e53d11SJiri Olsa static void perf_mmap__unmap_cb(struct perf_mmap *map) 65780e53d11SJiri Olsa { 65880e53d11SJiri Olsa struct mmap *m = container_of(map, struct mmap, core); 65980e53d11SJiri Olsa 66080e53d11SJiri Olsa mmap__munmap(m); 66180e53d11SJiri Olsa } 66280e53d11SJiri Olsa 663d50cf361SJiri Olsa static struct mmap *evlist__alloc_mmap(struct evlist *evlist, 6642c5f6d87SKan Liang bool overwrite) 665f8a95309SArnaldo Carvalho de Melo { 666d4c6fb36SWang Nan int i; 667a5830532SJiri Olsa struct mmap *map; 668d4c6fb36SWang Nan 669c976ee11SJiri Olsa map = zalloc(evlist->core.nr_mmaps * sizeof(struct mmap)); 6708db6d6b1SWang Nan if (!map) 6718db6d6b1SWang Nan return NULL; 672946ae1d4SWang Nan 673c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) { 6746eb65f7aSJiri Olsa struct perf_mmap *prev = i ? &map[i - 1].core : NULL; 6756eb65f7aSJiri Olsa 6764738ca30SArnaldo Carvalho de Melo /* 6774738ca30SArnaldo Carvalho de Melo * When the perf_mmap() call is made we grab one refcount, plus 6786afad54dSKan Liang * one extra to let perf_mmap__consume() get the last 6794738ca30SArnaldo Carvalho de Melo * events after all real references (perf_mmap__get()) are 6804738ca30SArnaldo Carvalho de Melo * dropped. 6814738ca30SArnaldo Carvalho de Melo * 6824738ca30SArnaldo Carvalho de Melo * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and 6834738ca30SArnaldo Carvalho de Melo * thus does perf_mmap__get() on it. 6844738ca30SArnaldo Carvalho de Melo */ 6856eb65f7aSJiri Olsa perf_mmap__init(&map[i].core, prev, overwrite, perf_mmap__unmap_cb); 6864738ca30SArnaldo Carvalho de Melo } 687353120b4SJiri Olsa 6888db6d6b1SWang Nan return map; 689f8a95309SArnaldo Carvalho de Melo } 690f8a95309SArnaldo Carvalho de Melo 6919abd2ab2SJiri Olsa static void 6929abd2ab2SJiri Olsa perf_evlist__mmap_cb_idx(struct perf_evlist *_evlist, 6939abd2ab2SJiri Olsa struct perf_mmap_param *_mp, 6949abd2ab2SJiri Olsa int idx, bool per_cpu) 6959abd2ab2SJiri Olsa { 6969abd2ab2SJiri Olsa struct evlist *evlist = container_of(_evlist, struct evlist, core); 6979abd2ab2SJiri Olsa struct mmap_params *mp = container_of(_mp, struct mmap_params, core); 6989abd2ab2SJiri Olsa 6999abd2ab2SJiri Olsa auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, idx, per_cpu); 7009abd2ab2SJiri Olsa } 7019abd2ab2SJiri Olsa 702bb1b1885SJiri Olsa static struct perf_mmap* 703bb1b1885SJiri Olsa perf_evlist__mmap_cb_get(struct perf_evlist *_evlist, bool overwrite, int idx) 704bb1b1885SJiri Olsa { 705bb1b1885SJiri Olsa struct evlist *evlist = container_of(_evlist, struct evlist, core); 7063805e4f3SJiri Olsa struct mmap *maps; 707bb1b1885SJiri Olsa 7083805e4f3SJiri Olsa maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; 709bb1b1885SJiri Olsa 710bb1b1885SJiri Olsa if (!maps) { 7113805e4f3SJiri Olsa maps = evlist__alloc_mmap(evlist, overwrite); 712bb1b1885SJiri Olsa if (!maps) 713bb1b1885SJiri Olsa return NULL; 714bb1b1885SJiri Olsa 7153805e4f3SJiri Olsa if (overwrite) { 716bb1b1885SJiri Olsa evlist->overwrite_mmap = maps; 717bb1b1885SJiri Olsa if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY) 718bb1b1885SJiri Olsa perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); 7193805e4f3SJiri Olsa } else { 7203805e4f3SJiri Olsa evlist->mmap = maps; 721bb1b1885SJiri Olsa } 722bb1b1885SJiri Olsa } 723bb1b1885SJiri Olsa 724bb1b1885SJiri Olsa return &maps[idx].core; 725bb1b1885SJiri Olsa } 726bb1b1885SJiri Olsa 727b80132b1SJiri Olsa static int 728b80132b1SJiri Olsa perf_evlist__mmap_cb_mmap(struct perf_mmap *_map, struct perf_mmap_param *_mp, 729b80132b1SJiri Olsa int output, int cpu) 730b80132b1SJiri Olsa { 731b80132b1SJiri Olsa struct mmap *map = container_of(_map, struct mmap, core); 732b80132b1SJiri Olsa struct mmap_params *mp = container_of(_mp, struct mmap_params, core); 733b80132b1SJiri Olsa 734b80132b1SJiri Olsa return mmap__mmap(map, mp, output, cpu); 735b80132b1SJiri Olsa } 736b80132b1SJiri Olsa 737f5e7150cSArnaldo Carvalho de Melo unsigned long perf_event_mlock_kb_in_pages(void) 738994a1f78SJiri Olsa { 739f5e7150cSArnaldo Carvalho de Melo unsigned long pages; 7408185e881SArnaldo Carvalho de Melo int max; 7418185e881SArnaldo Carvalho de Melo 7428185e881SArnaldo Carvalho de Melo if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { 7438185e881SArnaldo Carvalho de Melo /* 7448185e881SArnaldo Carvalho de Melo * Pick a once upon a time good value, i.e. things look 7458185e881SArnaldo Carvalho de Melo * strange since we can't read a sysctl value, but lets not 7468185e881SArnaldo Carvalho de Melo * die yet... 7478185e881SArnaldo Carvalho de Melo */ 7488185e881SArnaldo Carvalho de Melo max = 512; 7498185e881SArnaldo Carvalho de Melo } else { 7508185e881SArnaldo Carvalho de Melo max -= (page_size / 1024); 7518185e881SArnaldo Carvalho de Melo } 7528185e881SArnaldo Carvalho de Melo 7538185e881SArnaldo Carvalho de Melo pages = (max * 1024) / page_size; 7541be300f4SArnaldo Carvalho de Melo if (!is_power_of_2(pages)) 7551be300f4SArnaldo Carvalho de Melo pages = rounddown_pow_of_two(pages); 756f5e7150cSArnaldo Carvalho de Melo 757f5e7150cSArnaldo Carvalho de Melo return pages; 758f5e7150cSArnaldo Carvalho de Melo } 759f5e7150cSArnaldo Carvalho de Melo 7609521b5f2SJiri Olsa size_t evlist__mmap_size(unsigned long pages) 761f5e7150cSArnaldo Carvalho de Melo { 762f5e7150cSArnaldo Carvalho de Melo if (pages == UINT_MAX) 763f5e7150cSArnaldo Carvalho de Melo pages = perf_event_mlock_kb_in_pages(); 764f5e7150cSArnaldo Carvalho de Melo else if (!is_power_of_2(pages)) 765994a1f78SJiri Olsa return 0; 766994a1f78SJiri Olsa 767994a1f78SJiri Olsa return (pages + 1) * page_size; 768994a1f78SJiri Olsa } 769994a1f78SJiri Olsa 77033c2dcfdSDavid Ahern static long parse_pages_arg(const char *str, unsigned long min, 77133c2dcfdSDavid Ahern unsigned long max) 772994a1f78SJiri Olsa { 7732fbe4abeSAdrian Hunter unsigned long pages, val; 77427050f53SJiri Olsa static struct parse_tag tags[] = { 77527050f53SJiri Olsa { .tag = 'B', .mult = 1 }, 77627050f53SJiri Olsa { .tag = 'K', .mult = 1 << 10 }, 77727050f53SJiri Olsa { .tag = 'M', .mult = 1 << 20 }, 77827050f53SJiri Olsa { .tag = 'G', .mult = 1 << 30 }, 77927050f53SJiri Olsa { .tag = 0 }, 78027050f53SJiri Olsa }; 781994a1f78SJiri Olsa 7828973504bSDavid Ahern if (str == NULL) 78333c2dcfdSDavid Ahern return -EINVAL; 7848973504bSDavid Ahern 78527050f53SJiri Olsa val = parse_tag_value(str, tags); 7862fbe4abeSAdrian Hunter if (val != (unsigned long) -1) { 78727050f53SJiri Olsa /* we got file size value */ 78827050f53SJiri Olsa pages = PERF_ALIGN(val, page_size) / page_size; 78927050f53SJiri Olsa } else { 79027050f53SJiri Olsa /* we got pages count value */ 79127050f53SJiri Olsa char *eptr; 792994a1f78SJiri Olsa pages = strtoul(str, &eptr, 10); 79333c2dcfdSDavid Ahern if (*eptr != '\0') 79433c2dcfdSDavid Ahern return -EINVAL; 79527050f53SJiri Olsa } 796994a1f78SJiri Olsa 7972bcab6c1SAdrian Hunter if (pages == 0 && min == 0) { 79833c2dcfdSDavid Ahern /* leave number of pages at 0 */ 7991dbfa938SAdrian Hunter } else if (!is_power_of_2(pages)) { 8009808143bSJiri Olsa char buf[100]; 8019808143bSJiri Olsa 80233c2dcfdSDavid Ahern /* round pages up to next power of 2 */ 80391529834SArnaldo Carvalho de Melo pages = roundup_pow_of_two(pages); 8041dbfa938SAdrian Hunter if (!pages) 8051dbfa938SAdrian Hunter return -EINVAL; 8069808143bSJiri Olsa 8079808143bSJiri Olsa unit_number__scnprintf(buf, sizeof(buf), pages * page_size); 8089808143bSJiri Olsa pr_info("rounding mmap pages size to %s (%lu pages)\n", 8099808143bSJiri Olsa buf, pages); 8102fbe4abeSAdrian Hunter } 8112fbe4abeSAdrian Hunter 81233c2dcfdSDavid Ahern if (pages > max) 81333c2dcfdSDavid Ahern return -EINVAL; 81433c2dcfdSDavid Ahern 81533c2dcfdSDavid Ahern return pages; 81633c2dcfdSDavid Ahern } 81733c2dcfdSDavid Ahern 818e9db1310SAdrian Hunter int __perf_evlist__parse_mmap_pages(unsigned int *mmap_pages, const char *str) 81933c2dcfdSDavid Ahern { 82033c2dcfdSDavid Ahern unsigned long max = UINT_MAX; 82133c2dcfdSDavid Ahern long pages; 82233c2dcfdSDavid Ahern 823f5ae9c42SAdrian Hunter if (max > SIZE_MAX / page_size) 82433c2dcfdSDavid Ahern max = SIZE_MAX / page_size; 82533c2dcfdSDavid Ahern 82633c2dcfdSDavid Ahern pages = parse_pages_arg(str, 1, max); 82733c2dcfdSDavid Ahern if (pages < 0) { 82833c2dcfdSDavid Ahern pr_err("Invalid argument for --mmap_pages/-m\n"); 829994a1f78SJiri Olsa return -1; 830994a1f78SJiri Olsa } 831994a1f78SJiri Olsa 832994a1f78SJiri Olsa *mmap_pages = pages; 833994a1f78SJiri Olsa return 0; 834994a1f78SJiri Olsa } 835994a1f78SJiri Olsa 836e9db1310SAdrian Hunter int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, 837e9db1310SAdrian Hunter int unset __maybe_unused) 838e9db1310SAdrian Hunter { 839e9db1310SAdrian Hunter return __perf_evlist__parse_mmap_pages(opt->value, str); 840e9db1310SAdrian Hunter } 841e9db1310SAdrian Hunter 842c83fa7f2SAdrian Hunter /** 8439521b5f2SJiri Olsa * evlist__mmap_ex - Create mmaps to receive events. 844c83fa7f2SAdrian Hunter * @evlist: list of events 845c83fa7f2SAdrian Hunter * @pages: map length in pages 846c83fa7f2SAdrian Hunter * @overwrite: overwrite older events? 847718c602dSAdrian Hunter * @auxtrace_pages - auxtrace map length in pages 848718c602dSAdrian Hunter * @auxtrace_overwrite - overwrite older auxtrace data? 849f8a95309SArnaldo Carvalho de Melo * 850c83fa7f2SAdrian Hunter * If @overwrite is %false the user needs to signal event consumption using 8519521b5f2SJiri Olsa * perf_mmap__write_tail(). Using evlist__mmap_read() does this 852c83fa7f2SAdrian Hunter * automatically. 853f8a95309SArnaldo Carvalho de Melo * 854718c602dSAdrian Hunter * Similarly, if @auxtrace_overwrite is %false the user needs to signal data 855718c602dSAdrian Hunter * consumption using auxtrace_mmap__write_tail(). 856718c602dSAdrian Hunter * 857c83fa7f2SAdrian Hunter * Return: %0 on success, negative error code otherwise. 858f8a95309SArnaldo Carvalho de Melo */ 8599521b5f2SJiri Olsa int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, 8607a276ff6SWang Nan unsigned int auxtrace_pages, 86151255a8aSAlexey Budankov bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, 86251255a8aSAlexey Budankov int comp_level) 863f8a95309SArnaldo Carvalho de Melo { 86471f566a3SWang Nan /* 86571f566a3SWang Nan * Delay setting mp.prot: set it before calling perf_mmap__mmap. 86671f566a3SWang Nan * Its value is decided by evsel's write_backward. 86771f566a3SWang Nan * So &mp should not be passed through const pointer. 86871f566a3SWang Nan */ 869e440979fSJiri Olsa struct mmap_params mp = { 870e440979fSJiri Olsa .nr_cblocks = nr_cblocks, 871e440979fSJiri Olsa .affinity = affinity, 872e440979fSJiri Olsa .flush = flush, 873e440979fSJiri Olsa .comp_level = comp_level 874e440979fSJiri Olsa }; 875923d0f18SJiri Olsa struct perf_evlist_mmap_ops ops = { 8769abd2ab2SJiri Olsa .idx = perf_evlist__mmap_cb_idx, 877bb1b1885SJiri Olsa .get = perf_evlist__mmap_cb_get, 878b80132b1SJiri Olsa .mmap = perf_evlist__mmap_cb_mmap, 8799abd2ab2SJiri Olsa }; 88050a682ceSArnaldo Carvalho de Melo 881f6fa4375SJiri Olsa evlist->core.mmap_len = evlist__mmap_size(pages); 882f6fa4375SJiri Olsa pr_debug("mmap size %zuB\n", evlist->core.mmap_len); 883f8a95309SArnaldo Carvalho de Melo 884f6fa4375SJiri Olsa auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->core.mmap_len, 885718c602dSAdrian Hunter auxtrace_pages, auxtrace_overwrite); 886718c602dSAdrian Hunter 887923d0f18SJiri Olsa return perf_evlist__mmap_ops(&evlist->core, &ops, &mp.core); 888f8a95309SArnaldo Carvalho de Melo } 8897e2ed097SArnaldo Carvalho de Melo 8909521b5f2SJiri Olsa int evlist__mmap(struct evlist *evlist, unsigned int pages) 891718c602dSAdrian Hunter { 8929521b5f2SJiri Olsa return evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); 893718c602dSAdrian Hunter } 894718c602dSAdrian Hunter 89563503dbaSJiri Olsa int perf_evlist__create_maps(struct evlist *evlist, struct target *target) 8967e2ed097SArnaldo Carvalho de Melo { 897147c508fSJin Yao bool all_threads = (target->per_thread && target->system_wide); 898f854839bSJiri Olsa struct perf_cpu_map *cpus; 8999749b90eSJiri Olsa struct perf_thread_map *threads; 9007e2ed097SArnaldo Carvalho de Melo 901147c508fSJin Yao /* 902147c508fSJin Yao * If specify '-a' and '--per-thread' to perf record, perf record 903147c508fSJin Yao * will override '--per-thread'. target->per_thread = false and 904147c508fSJin Yao * target->system_wide = true. 905147c508fSJin Yao * 906147c508fSJin Yao * If specify '--per-thread' only to perf record, 907147c508fSJin Yao * target->per_thread = true and target->system_wide = false. 908147c508fSJin Yao * 909147c508fSJin Yao * So target->per_thread && target->system_wide is false. 910147c508fSJin Yao * For perf record, thread_map__new_str doesn't call 911147c508fSJin Yao * thread_map__new_all_cpus. That will keep perf record's 912147c508fSJin Yao * current behavior. 913147c508fSJin Yao * 914147c508fSJin Yao * For perf stat, it allows the case that target->per_thread and 915147c508fSJin Yao * target->system_wide are all true. It means to collect system-wide 916147c508fSJin Yao * per-thread data. thread_map__new_str will call 917147c508fSJin Yao * thread_map__new_all_cpus to enumerate all threads. 918147c508fSJin Yao */ 91973c0ca1eSJin Yao threads = thread_map__new_str(target->pid, target->tid, target->uid, 920147c508fSJin Yao all_threads); 92174bfd2b2SAdrian Hunter 92274bfd2b2SAdrian Hunter if (!threads) 9237e2ed097SArnaldo Carvalho de Melo return -1; 9247e2ed097SArnaldo Carvalho de Melo 9259c105fbcSDongsheng Yang if (target__uses_dummy_map(target)) 926397721e0SJiri Olsa cpus = perf_cpu_map__dummy_new(); 927879d77d0SNamhyung Kim else 9289c3516d1SJiri Olsa cpus = perf_cpu_map__new(target->cpu_list); 9297e2ed097SArnaldo Carvalho de Melo 93074bfd2b2SAdrian Hunter if (!cpus) 9317e2ed097SArnaldo Carvalho de Melo goto out_delete_threads; 9327e2ed097SArnaldo Carvalho de Melo 933ec903f26SJiri Olsa evlist->core.has_user_cpus = !!target->cpu_list; 934ec9a77a7SAdrian Hunter 935453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads); 936d5bc056eSAdrian Hunter 937d5bc056eSAdrian Hunter return 0; 9387e2ed097SArnaldo Carvalho de Melo 9397e2ed097SArnaldo Carvalho de Melo out_delete_threads: 9407836e52eSJiri Olsa perf_thread_map__put(threads); 9417e2ed097SArnaldo Carvalho de Melo return -1; 9427e2ed097SArnaldo Carvalho de Melo } 9437e2ed097SArnaldo Carvalho de Melo 94463503dbaSJiri Olsa void __perf_evlist__set_sample_bit(struct evlist *evlist, 94522c8a376SArnaldo Carvalho de Melo enum perf_event_sample_format bit) 94622c8a376SArnaldo Carvalho de Melo { 94732dcd021SJiri Olsa struct evsel *evsel; 94822c8a376SArnaldo Carvalho de Melo 949e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 95022c8a376SArnaldo Carvalho de Melo __perf_evsel__set_sample_bit(evsel, bit); 95122c8a376SArnaldo Carvalho de Melo } 95222c8a376SArnaldo Carvalho de Melo 95363503dbaSJiri Olsa void __perf_evlist__reset_sample_bit(struct evlist *evlist, 95422c8a376SArnaldo Carvalho de Melo enum perf_event_sample_format bit) 95522c8a376SArnaldo Carvalho de Melo { 95632dcd021SJiri Olsa struct evsel *evsel; 95722c8a376SArnaldo Carvalho de Melo 958e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 95922c8a376SArnaldo Carvalho de Melo __perf_evsel__reset_sample_bit(evsel, bit); 96022c8a376SArnaldo Carvalho de Melo } 96122c8a376SArnaldo Carvalho de Melo 96263503dbaSJiri Olsa int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) 9630a102479SFrederic Weisbecker { 96432dcd021SJiri Olsa struct evsel *evsel; 965745cefc5SArnaldo Carvalho de Melo int err = 0; 9660a102479SFrederic Weisbecker 967e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 968745cefc5SArnaldo Carvalho de Melo if (evsel->filter == NULL) 9690a102479SFrederic Weisbecker continue; 970745cefc5SArnaldo Carvalho de Melo 971d988d5eeSKan Liang /* 972d988d5eeSKan Liang * filters only work for tracepoint event, which doesn't have cpu limit. 973d988d5eeSKan Liang * So evlist and evsel should always be same. 974d988d5eeSKan Liang */ 975a00571fdSJiri Olsa err = perf_evsel__apply_filter(&evsel->core, evsel->filter); 97623d4aad4SArnaldo Carvalho de Melo if (err) { 97723d4aad4SArnaldo Carvalho de Melo *err_evsel = evsel; 978745cefc5SArnaldo Carvalho de Melo break; 9790a102479SFrederic Weisbecker } 98023d4aad4SArnaldo Carvalho de Melo } 9810a102479SFrederic Weisbecker 982745cefc5SArnaldo Carvalho de Melo return err; 983745cefc5SArnaldo Carvalho de Melo } 984745cefc5SArnaldo Carvalho de Melo 98563503dbaSJiri Olsa int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter) 986745cefc5SArnaldo Carvalho de Melo { 98732dcd021SJiri Olsa struct evsel *evsel; 988745cefc5SArnaldo Carvalho de Melo int err = 0; 989745cefc5SArnaldo Carvalho de Melo 99005cea449SArnaldo Carvalho de Melo if (filter == NULL) 99105cea449SArnaldo Carvalho de Melo return -1; 99205cea449SArnaldo Carvalho de Melo 993e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 9941fc632ceSJiri Olsa if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) 995fdf14720SWang Nan continue; 996fdf14720SWang Nan 99794ad89bcSArnaldo Carvalho de Melo err = perf_evsel__set_filter(evsel, filter); 998745cefc5SArnaldo Carvalho de Melo if (err) 999745cefc5SArnaldo Carvalho de Melo break; 1000745cefc5SArnaldo Carvalho de Melo } 1001745cefc5SArnaldo Carvalho de Melo 1002745cefc5SArnaldo Carvalho de Melo return err; 10030a102479SFrederic Weisbecker } 100474429964SFrederic Weisbecker 100553c92f73SArnaldo Carvalho de Melo int perf_evlist__append_tp_filter(struct evlist *evlist, const char *filter) 100653c92f73SArnaldo Carvalho de Melo { 100753c92f73SArnaldo Carvalho de Melo struct evsel *evsel; 100853c92f73SArnaldo Carvalho de Melo int err = 0; 100953c92f73SArnaldo Carvalho de Melo 101053c92f73SArnaldo Carvalho de Melo if (filter == NULL) 101153c92f73SArnaldo Carvalho de Melo return -1; 101253c92f73SArnaldo Carvalho de Melo 101353c92f73SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 101453c92f73SArnaldo Carvalho de Melo if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) 101553c92f73SArnaldo Carvalho de Melo continue; 101653c92f73SArnaldo Carvalho de Melo 101753c92f73SArnaldo Carvalho de Melo err = perf_evsel__append_tp_filter(evsel, filter); 101853c92f73SArnaldo Carvalho de Melo if (err) 101953c92f73SArnaldo Carvalho de Melo break; 102053c92f73SArnaldo Carvalho de Melo } 102153c92f73SArnaldo Carvalho de Melo 102253c92f73SArnaldo Carvalho de Melo return err; 102353c92f73SArnaldo Carvalho de Melo } 102453c92f73SArnaldo Carvalho de Melo 1025da949f50SArnaldo Carvalho de Melo char *asprintf__tp_filter_pids(size_t npids, pid_t *pids) 1026cfd70a26SArnaldo Carvalho de Melo { 1027cfd70a26SArnaldo Carvalho de Melo char *filter; 1028be199adaSArnaldo Carvalho de Melo size_t i; 1029cfd70a26SArnaldo Carvalho de Melo 1030be199adaSArnaldo Carvalho de Melo for (i = 0; i < npids; ++i) { 1031be199adaSArnaldo Carvalho de Melo if (i == 0) { 1032be199adaSArnaldo Carvalho de Melo if (asprintf(&filter, "common_pid != %d", pids[i]) < 0) 103305cea449SArnaldo Carvalho de Melo return NULL; 1034be199adaSArnaldo Carvalho de Melo } else { 1035be199adaSArnaldo Carvalho de Melo char *tmp; 1036be199adaSArnaldo Carvalho de Melo 1037be199adaSArnaldo Carvalho de Melo if (asprintf(&tmp, "%s && common_pid != %d", filter, pids[i]) < 0) 1038be199adaSArnaldo Carvalho de Melo goto out_free; 1039be199adaSArnaldo Carvalho de Melo 1040be199adaSArnaldo Carvalho de Melo free(filter); 1041be199adaSArnaldo Carvalho de Melo filter = tmp; 1042be199adaSArnaldo Carvalho de Melo } 1043be199adaSArnaldo Carvalho de Melo } 1044cfd70a26SArnaldo Carvalho de Melo 104505cea449SArnaldo Carvalho de Melo return filter; 1046be199adaSArnaldo Carvalho de Melo out_free: 1047cfd70a26SArnaldo Carvalho de Melo free(filter); 104805cea449SArnaldo Carvalho de Melo return NULL; 104905cea449SArnaldo Carvalho de Melo } 105005cea449SArnaldo Carvalho de Melo 105105cea449SArnaldo Carvalho de Melo int perf_evlist__set_tp_filter_pids(struct evlist *evlist, size_t npids, pid_t *pids) 105205cea449SArnaldo Carvalho de Melo { 105305cea449SArnaldo Carvalho de Melo char *filter = asprintf__tp_filter_pids(npids, pids); 105405cea449SArnaldo Carvalho de Melo int ret = perf_evlist__set_tp_filter(evlist, filter); 105505cea449SArnaldo Carvalho de Melo 105605cea449SArnaldo Carvalho de Melo free(filter); 1057cfd70a26SArnaldo Carvalho de Melo return ret; 1058cfd70a26SArnaldo Carvalho de Melo } 1059cfd70a26SArnaldo Carvalho de Melo 106063503dbaSJiri Olsa int perf_evlist__set_tp_filter_pid(struct evlist *evlist, pid_t pid) 1061be199adaSArnaldo Carvalho de Melo { 10627ad92a33SArnaldo Carvalho de Melo return perf_evlist__set_tp_filter_pids(evlist, 1, &pid); 1063be199adaSArnaldo Carvalho de Melo } 1064be199adaSArnaldo Carvalho de Melo 10651827ab5bSArnaldo Carvalho de Melo int perf_evlist__append_tp_filter_pids(struct evlist *evlist, size_t npids, pid_t *pids) 10661827ab5bSArnaldo Carvalho de Melo { 10671827ab5bSArnaldo Carvalho de Melo char *filter = asprintf__tp_filter_pids(npids, pids); 10681827ab5bSArnaldo Carvalho de Melo int ret = perf_evlist__append_tp_filter(evlist, filter); 10691827ab5bSArnaldo Carvalho de Melo 10701827ab5bSArnaldo Carvalho de Melo free(filter); 10711827ab5bSArnaldo Carvalho de Melo return ret; 10721827ab5bSArnaldo Carvalho de Melo } 10731827ab5bSArnaldo Carvalho de Melo 10741827ab5bSArnaldo Carvalho de Melo int perf_evlist__append_tp_filter_pid(struct evlist *evlist, pid_t pid) 10751827ab5bSArnaldo Carvalho de Melo { 10761827ab5bSArnaldo Carvalho de Melo return perf_evlist__append_tp_filter_pids(evlist, 1, &pid); 10771827ab5bSArnaldo Carvalho de Melo } 10781827ab5bSArnaldo Carvalho de Melo 107963503dbaSJiri Olsa bool perf_evlist__valid_sample_type(struct evlist *evlist) 108074429964SFrederic Weisbecker { 108132dcd021SJiri Olsa struct evsel *pos; 1082c2a70653SArnaldo Carvalho de Melo 10836484d2f9SJiri Olsa if (evlist->core.nr_entries == 1) 108475562573SAdrian Hunter return true; 108575562573SAdrian Hunter 108675562573SAdrian Hunter if (evlist->id_pos < 0 || evlist->is_pos < 0) 108775562573SAdrian Hunter return false; 108875562573SAdrian Hunter 1089e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 109075562573SAdrian Hunter if (pos->id_pos != evlist->id_pos || 109175562573SAdrian Hunter pos->is_pos != evlist->is_pos) 1092c2a70653SArnaldo Carvalho de Melo return false; 109374429964SFrederic Weisbecker } 109474429964SFrederic Weisbecker 1095c2a70653SArnaldo Carvalho de Melo return true; 1096c2a70653SArnaldo Carvalho de Melo } 1097c2a70653SArnaldo Carvalho de Melo 109863503dbaSJiri Olsa u64 __perf_evlist__combined_sample_type(struct evlist *evlist) 1099c2a70653SArnaldo Carvalho de Melo { 110032dcd021SJiri Olsa struct evsel *evsel; 110175562573SAdrian Hunter 110275562573SAdrian Hunter if (evlist->combined_sample_type) 110375562573SAdrian Hunter return evlist->combined_sample_type; 110475562573SAdrian Hunter 1105e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 11061fc632ceSJiri Olsa evlist->combined_sample_type |= evsel->core.attr.sample_type; 110775562573SAdrian Hunter 110875562573SAdrian Hunter return evlist->combined_sample_type; 110975562573SAdrian Hunter } 111075562573SAdrian Hunter 111163503dbaSJiri Olsa u64 perf_evlist__combined_sample_type(struct evlist *evlist) 111275562573SAdrian Hunter { 111375562573SAdrian Hunter evlist->combined_sample_type = 0; 111475562573SAdrian Hunter return __perf_evlist__combined_sample_type(evlist); 1115c2a70653SArnaldo Carvalho de Melo } 1116c2a70653SArnaldo Carvalho de Melo 111763503dbaSJiri Olsa u64 perf_evlist__combined_branch_type(struct evlist *evlist) 111898df858eSAndi Kleen { 111932dcd021SJiri Olsa struct evsel *evsel; 112098df858eSAndi Kleen u64 branch_type = 0; 112198df858eSAndi Kleen 1122e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) 11231fc632ceSJiri Olsa branch_type |= evsel->core.attr.branch_sample_type; 112498df858eSAndi Kleen return branch_type; 112598df858eSAndi Kleen } 112698df858eSAndi Kleen 112763503dbaSJiri Olsa bool perf_evlist__valid_read_format(struct evlist *evlist) 11289ede473cSJiri Olsa { 1129515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist), *pos = first; 11301fc632ceSJiri Olsa u64 read_format = first->core.attr.read_format; 11311fc632ceSJiri Olsa u64 sample_type = first->core.attr.sample_type; 11329ede473cSJiri Olsa 1133e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, pos) { 113494d3820fSAdrian Hunter if (read_format != pos->core.attr.read_format) { 113594d3820fSAdrian Hunter pr_debug("Read format differs %#" PRIx64 " vs %#" PRIx64 "\n", 113694d3820fSAdrian Hunter read_format, (u64)pos->core.attr.read_format); 113794d3820fSAdrian Hunter } 11389ede473cSJiri Olsa } 11399ede473cSJiri Olsa 11409ede473cSJiri Olsa /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */ 11419ede473cSJiri Olsa if ((sample_type & PERF_SAMPLE_READ) && 11429ede473cSJiri Olsa !(read_format & PERF_FORMAT_ID)) { 11439ede473cSJiri Olsa return false; 11449ede473cSJiri Olsa } 11459ede473cSJiri Olsa 11469ede473cSJiri Olsa return true; 11479ede473cSJiri Olsa } 11489ede473cSJiri Olsa 114963503dbaSJiri Olsa u16 perf_evlist__id_hdr_size(struct evlist *evlist) 115081e36bffSArnaldo Carvalho de Melo { 1151515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist); 115281e36bffSArnaldo Carvalho de Melo struct perf_sample *data; 115381e36bffSArnaldo Carvalho de Melo u64 sample_type; 115481e36bffSArnaldo Carvalho de Melo u16 size = 0; 115581e36bffSArnaldo Carvalho de Melo 11561fc632ceSJiri Olsa if (!first->core.attr.sample_id_all) 115781e36bffSArnaldo Carvalho de Melo goto out; 115881e36bffSArnaldo Carvalho de Melo 11591fc632ceSJiri Olsa sample_type = first->core.attr.sample_type; 116081e36bffSArnaldo Carvalho de Melo 116181e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_TID) 116281e36bffSArnaldo Carvalho de Melo size += sizeof(data->tid) * 2; 116381e36bffSArnaldo Carvalho de Melo 116481e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_TIME) 116581e36bffSArnaldo Carvalho de Melo size += sizeof(data->time); 116681e36bffSArnaldo Carvalho de Melo 116781e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_ID) 116881e36bffSArnaldo Carvalho de Melo size += sizeof(data->id); 116981e36bffSArnaldo Carvalho de Melo 117081e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_STREAM_ID) 117181e36bffSArnaldo Carvalho de Melo size += sizeof(data->stream_id); 117281e36bffSArnaldo Carvalho de Melo 117381e36bffSArnaldo Carvalho de Melo if (sample_type & PERF_SAMPLE_CPU) 117481e36bffSArnaldo Carvalho de Melo size += sizeof(data->cpu) * 2; 117575562573SAdrian Hunter 117675562573SAdrian Hunter if (sample_type & PERF_SAMPLE_IDENTIFIER) 117775562573SAdrian Hunter size += sizeof(data->id); 117881e36bffSArnaldo Carvalho de Melo out: 117981e36bffSArnaldo Carvalho de Melo return size; 118081e36bffSArnaldo Carvalho de Melo } 118181e36bffSArnaldo Carvalho de Melo 118263503dbaSJiri Olsa bool perf_evlist__valid_sample_id_all(struct evlist *evlist) 1183c2a70653SArnaldo Carvalho de Melo { 1184515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist), *pos = first; 1185c2a70653SArnaldo Carvalho de Melo 1186e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_continue(evlist, pos) { 11871fc632ceSJiri Olsa if (first->core.attr.sample_id_all != pos->core.attr.sample_id_all) 1188c2a70653SArnaldo Carvalho de Melo return false; 1189c2a70653SArnaldo Carvalho de Melo } 1190c2a70653SArnaldo Carvalho de Melo 1191c2a70653SArnaldo Carvalho de Melo return true; 119274429964SFrederic Weisbecker } 119374429964SFrederic Weisbecker 119463503dbaSJiri Olsa bool perf_evlist__sample_id_all(struct evlist *evlist) 119574429964SFrederic Weisbecker { 1196515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist); 11971fc632ceSJiri Olsa return first->core.attr.sample_id_all; 119874429964SFrederic Weisbecker } 119981cce8deSArnaldo Carvalho de Melo 120063503dbaSJiri Olsa void perf_evlist__set_selected(struct evlist *evlist, 120132dcd021SJiri Olsa struct evsel *evsel) 120281cce8deSArnaldo Carvalho de Melo { 120381cce8deSArnaldo Carvalho de Melo evlist->selected = evsel; 120481cce8deSArnaldo Carvalho de Melo } 1205727ab04eSArnaldo Carvalho de Melo 1206750b4edeSJiri Olsa void evlist__close(struct evlist *evlist) 1207a74b4b66SNamhyung Kim { 120832dcd021SJiri Olsa struct evsel *evsel; 12097736627bSAndi Kleen struct affinity affinity; 12107736627bSAndi Kleen int cpu, i; 1211a74b4b66SNamhyung Kim 12127736627bSAndi Kleen /* 12137736627bSAndi Kleen * With perf record core.cpus is usually NULL. 12147736627bSAndi Kleen * Use the old method to handle this for now. 12157736627bSAndi Kleen */ 12167736627bSAndi Kleen if (!evlist->core.cpus) { 1217475fb533SAndi Kleen evlist__for_each_entry_reverse(evlist, evsel) 121888761fa1SJiri Olsa evsel__close(evsel); 12197736627bSAndi Kleen return; 12207736627bSAndi Kleen } 12217736627bSAndi Kleen 12227736627bSAndi Kleen if (affinity__setup(&affinity) < 0) 12237736627bSAndi Kleen return; 12247736627bSAndi Kleen evlist__for_each_cpu(evlist, i, cpu) { 12257736627bSAndi Kleen affinity__set(&affinity, cpu); 12267736627bSAndi Kleen 12277736627bSAndi Kleen evlist__for_each_entry_reverse(evlist, evsel) { 12287736627bSAndi Kleen if (evsel__cpu_iter_skip(evsel, cpu)) 12297736627bSAndi Kleen continue; 12307736627bSAndi Kleen perf_evsel__close_cpu(&evsel->core, evsel->cpu_iter - 1); 12317736627bSAndi Kleen } 12327736627bSAndi Kleen } 12337736627bSAndi Kleen affinity__cleanup(&affinity); 12347736627bSAndi Kleen evlist__for_each_entry_reverse(evlist, evsel) { 12357736627bSAndi Kleen perf_evsel__free_fd(&evsel->core); 12367736627bSAndi Kleen perf_evsel__free_id(&evsel->core); 12377736627bSAndi Kleen } 1238a74b4b66SNamhyung Kim } 1239a74b4b66SNamhyung Kim 124063503dbaSJiri Olsa static int perf_evlist__create_syswide_maps(struct evlist *evlist) 12414112eb18SArnaldo Carvalho de Melo { 1242f854839bSJiri Olsa struct perf_cpu_map *cpus; 12439749b90eSJiri Olsa struct perf_thread_map *threads; 12444112eb18SArnaldo Carvalho de Melo int err = -ENOMEM; 12454112eb18SArnaldo Carvalho de Melo 12464112eb18SArnaldo Carvalho de Melo /* 12474112eb18SArnaldo Carvalho de Melo * Try reading /sys/devices/system/cpu/online to get 12484112eb18SArnaldo Carvalho de Melo * an all cpus map. 12494112eb18SArnaldo Carvalho de Melo * 12504112eb18SArnaldo Carvalho de Melo * FIXME: -ENOMEM is the best we can do here, the cpu_map 12514112eb18SArnaldo Carvalho de Melo * code needs an overhaul to properly forward the 12524112eb18SArnaldo Carvalho de Melo * error, and we may not want to do that fallback to a 12534112eb18SArnaldo Carvalho de Melo * default cpu identity map :-\ 12544112eb18SArnaldo Carvalho de Melo */ 12559c3516d1SJiri Olsa cpus = perf_cpu_map__new(NULL); 12568c0498b6SAdrian Hunter if (!cpus) 12574112eb18SArnaldo Carvalho de Melo goto out; 12584112eb18SArnaldo Carvalho de Melo 12594b49cce2SJiri Olsa threads = perf_thread_map__new_dummy(); 12608c0498b6SAdrian Hunter if (!threads) 12618c0498b6SAdrian Hunter goto out_put; 12624112eb18SArnaldo Carvalho de Melo 1263453fa030SJiri Olsa perf_evlist__set_maps(&evlist->core, cpus, threads); 12644112eb18SArnaldo Carvalho de Melo out: 12654112eb18SArnaldo Carvalho de Melo return err; 12668c0498b6SAdrian Hunter out_put: 126738f01d8dSJiri Olsa perf_cpu_map__put(cpus); 12684112eb18SArnaldo Carvalho de Melo goto out; 12694112eb18SArnaldo Carvalho de Melo } 12704112eb18SArnaldo Carvalho de Melo 1271474ddc4cSJiri Olsa int evlist__open(struct evlist *evlist) 1272727ab04eSArnaldo Carvalho de Melo { 127332dcd021SJiri Olsa struct evsel *evsel; 1274a74b4b66SNamhyung Kim int err; 1275727ab04eSArnaldo Carvalho de Melo 12764112eb18SArnaldo Carvalho de Melo /* 12774112eb18SArnaldo Carvalho de Melo * Default: one fd per CPU, all threads, aka systemwide 12784112eb18SArnaldo Carvalho de Melo * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL 12794112eb18SArnaldo Carvalho de Melo */ 128003617c22SJiri Olsa if (evlist->core.threads == NULL && evlist->core.cpus == NULL) { 12814112eb18SArnaldo Carvalho de Melo err = perf_evlist__create_syswide_maps(evlist); 12824112eb18SArnaldo Carvalho de Melo if (err < 0) 12834112eb18SArnaldo Carvalho de Melo goto out_err; 12844112eb18SArnaldo Carvalho de Melo } 12854112eb18SArnaldo Carvalho de Melo 1286733cd2feSAdrian Hunter perf_evlist__update_id_pos(evlist); 1287733cd2feSAdrian Hunter 1288e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 1289af663bd0SJiri Olsa err = evsel__open(evsel, evsel->core.cpus, evsel->core.threads); 1290727ab04eSArnaldo Carvalho de Melo if (err < 0) 1291727ab04eSArnaldo Carvalho de Melo goto out_err; 1292727ab04eSArnaldo Carvalho de Melo } 1293727ab04eSArnaldo Carvalho de Melo 1294727ab04eSArnaldo Carvalho de Melo return 0; 1295727ab04eSArnaldo Carvalho de Melo out_err: 1296750b4edeSJiri Olsa evlist__close(evlist); 129741c21a68SNamhyung Kim errno = -err; 1298727ab04eSArnaldo Carvalho de Melo return err; 1299727ab04eSArnaldo Carvalho de Melo } 130035b9d88eSArnaldo Carvalho de Melo 130163503dbaSJiri Olsa int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, 130255e162eaSNamhyung Kim const char *argv[], bool pipe_output, 1303735f7e0bSArnaldo Carvalho de Melo void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) 130435b9d88eSArnaldo Carvalho de Melo { 130535b9d88eSArnaldo Carvalho de Melo int child_ready_pipe[2], go_pipe[2]; 130635b9d88eSArnaldo Carvalho de Melo char bf; 130735b9d88eSArnaldo Carvalho de Melo 130835b9d88eSArnaldo Carvalho de Melo if (pipe(child_ready_pipe) < 0) { 130935b9d88eSArnaldo Carvalho de Melo perror("failed to create 'ready' pipe"); 131035b9d88eSArnaldo Carvalho de Melo return -1; 131135b9d88eSArnaldo Carvalho de Melo } 131235b9d88eSArnaldo Carvalho de Melo 131335b9d88eSArnaldo Carvalho de Melo if (pipe(go_pipe) < 0) { 131435b9d88eSArnaldo Carvalho de Melo perror("failed to create 'go' pipe"); 131535b9d88eSArnaldo Carvalho de Melo goto out_close_ready_pipe; 131635b9d88eSArnaldo Carvalho de Melo } 131735b9d88eSArnaldo Carvalho de Melo 131835b9d88eSArnaldo Carvalho de Melo evlist->workload.pid = fork(); 131935b9d88eSArnaldo Carvalho de Melo if (evlist->workload.pid < 0) { 132035b9d88eSArnaldo Carvalho de Melo perror("failed to fork"); 132135b9d88eSArnaldo Carvalho de Melo goto out_close_pipes; 132235b9d88eSArnaldo Carvalho de Melo } 132335b9d88eSArnaldo Carvalho de Melo 132435b9d88eSArnaldo Carvalho de Melo if (!evlist->workload.pid) { 13255f1c4225SArnaldo Carvalho de Melo int ret; 13265f1c4225SArnaldo Carvalho de Melo 1327119fa3c9SNamhyung Kim if (pipe_output) 132835b9d88eSArnaldo Carvalho de Melo dup2(2, 1); 132935b9d88eSArnaldo Carvalho de Melo 13300817df08SDavid Ahern signal(SIGTERM, SIG_DFL); 13310817df08SDavid Ahern 133235b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 133335b9d88eSArnaldo Carvalho de Melo close(go_pipe[1]); 133435b9d88eSArnaldo Carvalho de Melo fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 133535b9d88eSArnaldo Carvalho de Melo 133635b9d88eSArnaldo Carvalho de Melo /* 133735b9d88eSArnaldo Carvalho de Melo * Tell the parent we're ready to go 133835b9d88eSArnaldo Carvalho de Melo */ 133935b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 134035b9d88eSArnaldo Carvalho de Melo 134135b9d88eSArnaldo Carvalho de Melo /* 134235b9d88eSArnaldo Carvalho de Melo * Wait until the parent tells us to go. 134335b9d88eSArnaldo Carvalho de Melo */ 13445f1c4225SArnaldo Carvalho de Melo ret = read(go_pipe[0], &bf, 1); 13455f1c4225SArnaldo Carvalho de Melo /* 13465f1c4225SArnaldo Carvalho de Melo * The parent will ask for the execvp() to be performed by 13475f1c4225SArnaldo Carvalho de Melo * writing exactly one byte, in workload.cork_fd, usually via 13485f1c4225SArnaldo Carvalho de Melo * perf_evlist__start_workload(). 13495f1c4225SArnaldo Carvalho de Melo * 135020f86fc1SArnaldo Carvalho de Melo * For cancelling the workload without actually running it, 13515f1c4225SArnaldo Carvalho de Melo * the parent will just close workload.cork_fd, without writing 13525f1c4225SArnaldo Carvalho de Melo * anything, i.e. read will return zero and we just exit() 13535f1c4225SArnaldo Carvalho de Melo * here. 13545f1c4225SArnaldo Carvalho de Melo */ 13555f1c4225SArnaldo Carvalho de Melo if (ret != 1) { 13565f1c4225SArnaldo Carvalho de Melo if (ret == -1) 135735b9d88eSArnaldo Carvalho de Melo perror("unable to read pipe"); 13585f1c4225SArnaldo Carvalho de Melo exit(ret); 13595f1c4225SArnaldo Carvalho de Melo } 136035b9d88eSArnaldo Carvalho de Melo 136135b9d88eSArnaldo Carvalho de Melo execvp(argv[0], (char **)argv); 136235b9d88eSArnaldo Carvalho de Melo 1363735f7e0bSArnaldo Carvalho de Melo if (exec_error) { 1364f33cbe72SArnaldo Carvalho de Melo union sigval val; 1365f33cbe72SArnaldo Carvalho de Melo 1366f33cbe72SArnaldo Carvalho de Melo val.sival_int = errno; 1367f33cbe72SArnaldo Carvalho de Melo if (sigqueue(getppid(), SIGUSR1, val)) 136835b9d88eSArnaldo Carvalho de Melo perror(argv[0]); 1369f33cbe72SArnaldo Carvalho de Melo } else 1370f33cbe72SArnaldo Carvalho de Melo perror(argv[0]); 137135b9d88eSArnaldo Carvalho de Melo exit(-1); 137235b9d88eSArnaldo Carvalho de Melo } 137335b9d88eSArnaldo Carvalho de Melo 1374735f7e0bSArnaldo Carvalho de Melo if (exec_error) { 1375735f7e0bSArnaldo Carvalho de Melo struct sigaction act = { 1376735f7e0bSArnaldo Carvalho de Melo .sa_flags = SA_SIGINFO, 1377735f7e0bSArnaldo Carvalho de Melo .sa_sigaction = exec_error, 1378735f7e0bSArnaldo Carvalho de Melo }; 1379735f7e0bSArnaldo Carvalho de Melo sigaction(SIGUSR1, &act, NULL); 1380735f7e0bSArnaldo Carvalho de Melo } 1381735f7e0bSArnaldo Carvalho de Melo 13821aaf63b1SArnaldo Carvalho de Melo if (target__none(target)) { 138303617c22SJiri Olsa if (evlist->core.threads == NULL) { 13841aaf63b1SArnaldo Carvalho de Melo fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", 13851aaf63b1SArnaldo Carvalho de Melo __func__, __LINE__); 13861aaf63b1SArnaldo Carvalho de Melo goto out_close_pipes; 13871aaf63b1SArnaldo Carvalho de Melo } 138803617c22SJiri Olsa perf_thread_map__set_pid(evlist->core.threads, 0, evlist->workload.pid); 13891aaf63b1SArnaldo Carvalho de Melo } 139035b9d88eSArnaldo Carvalho de Melo 139135b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 139235b9d88eSArnaldo Carvalho de Melo close(go_pipe[0]); 139335b9d88eSArnaldo Carvalho de Melo /* 139435b9d88eSArnaldo Carvalho de Melo * wait for child to settle 139535b9d88eSArnaldo Carvalho de Melo */ 139635b9d88eSArnaldo Carvalho de Melo if (read(child_ready_pipe[0], &bf, 1) == -1) { 139735b9d88eSArnaldo Carvalho de Melo perror("unable to read pipe"); 139835b9d88eSArnaldo Carvalho de Melo goto out_close_pipes; 139935b9d88eSArnaldo Carvalho de Melo } 140035b9d88eSArnaldo Carvalho de Melo 1401bcf3145fSNamhyung Kim fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); 140235b9d88eSArnaldo Carvalho de Melo evlist->workload.cork_fd = go_pipe[1]; 140335b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 140435b9d88eSArnaldo Carvalho de Melo return 0; 140535b9d88eSArnaldo Carvalho de Melo 140635b9d88eSArnaldo Carvalho de Melo out_close_pipes: 140735b9d88eSArnaldo Carvalho de Melo close(go_pipe[0]); 140835b9d88eSArnaldo Carvalho de Melo close(go_pipe[1]); 140935b9d88eSArnaldo Carvalho de Melo out_close_ready_pipe: 141035b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[0]); 141135b9d88eSArnaldo Carvalho de Melo close(child_ready_pipe[1]); 141235b9d88eSArnaldo Carvalho de Melo return -1; 141335b9d88eSArnaldo Carvalho de Melo } 141435b9d88eSArnaldo Carvalho de Melo 141563503dbaSJiri Olsa int perf_evlist__start_workload(struct evlist *evlist) 141635b9d88eSArnaldo Carvalho de Melo { 141735b9d88eSArnaldo Carvalho de Melo if (evlist->workload.cork_fd > 0) { 1418b3824404SDavid Ahern char bf = 0; 1419bcf3145fSNamhyung Kim int ret; 142035b9d88eSArnaldo Carvalho de Melo /* 142135b9d88eSArnaldo Carvalho de Melo * Remove the cork, let it rip! 142235b9d88eSArnaldo Carvalho de Melo */ 1423bcf3145fSNamhyung Kim ret = write(evlist->workload.cork_fd, &bf, 1); 1424bcf3145fSNamhyung Kim if (ret < 0) 1425e978be9eSSoramichi Akiyama perror("unable to write to pipe"); 1426bcf3145fSNamhyung Kim 1427bcf3145fSNamhyung Kim close(evlist->workload.cork_fd); 1428bcf3145fSNamhyung Kim return ret; 142935b9d88eSArnaldo Carvalho de Melo } 143035b9d88eSArnaldo Carvalho de Melo 143135b9d88eSArnaldo Carvalho de Melo return 0; 143235b9d88eSArnaldo Carvalho de Melo } 1433cb0b29e0SArnaldo Carvalho de Melo 143463503dbaSJiri Olsa int perf_evlist__parse_sample(struct evlist *evlist, union perf_event *event, 14350807d2d8SArnaldo Carvalho de Melo struct perf_sample *sample) 1436cb0b29e0SArnaldo Carvalho de Melo { 143732dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 143875562573SAdrian Hunter 143975562573SAdrian Hunter if (!evsel) 144075562573SAdrian Hunter return -EFAULT; 14410807d2d8SArnaldo Carvalho de Melo return perf_evsel__parse_sample(evsel, event, sample); 1442cb0b29e0SArnaldo Carvalho de Melo } 144378f067b3SArnaldo Carvalho de Melo 144463503dbaSJiri Olsa int perf_evlist__parse_sample_timestamp(struct evlist *evlist, 144501468120SJiri Olsa union perf_event *event, 144601468120SJiri Olsa u64 *timestamp) 144701468120SJiri Olsa { 144832dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 144901468120SJiri Olsa 145001468120SJiri Olsa if (!evsel) 145101468120SJiri Olsa return -EFAULT; 145201468120SJiri Olsa return perf_evsel__parse_sample_timestamp(evsel, event, timestamp); 145301468120SJiri Olsa } 145401468120SJiri Olsa 145563503dbaSJiri Olsa int perf_evlist__strerror_open(struct evlist *evlist, 1456a8f23d8fSArnaldo Carvalho de Melo int err, char *buf, size_t size) 1457a8f23d8fSArnaldo Carvalho de Melo { 1458a8f23d8fSArnaldo Carvalho de Melo int printed, value; 1459c8b5f2c9SArnaldo Carvalho de Melo char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); 1460a8f23d8fSArnaldo Carvalho de Melo 1461a8f23d8fSArnaldo Carvalho de Melo switch (err) { 1462a8f23d8fSArnaldo Carvalho de Melo case EACCES: 1463a8f23d8fSArnaldo Carvalho de Melo case EPERM: 1464a8f23d8fSArnaldo Carvalho de Melo printed = scnprintf(buf, size, 1465a8f23d8fSArnaldo Carvalho de Melo "Error:\t%s.\n" 1466a8f23d8fSArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); 1467a8f23d8fSArnaldo Carvalho de Melo 14681a47245dSAdrian Hunter value = perf_event_paranoid(); 1469a8f23d8fSArnaldo Carvalho de Melo 1470a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, "\nHint:\t"); 1471a8f23d8fSArnaldo Carvalho de Melo 1472a8f23d8fSArnaldo Carvalho de Melo if (value >= 2) { 1473a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1474a8f23d8fSArnaldo Carvalho de Melo "For your workloads it needs to be <= 1\nHint:\t"); 1475a8f23d8fSArnaldo Carvalho de Melo } 1476a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 14775229e366SArnaldo Carvalho de Melo "For system wide tracing it needs to be set to -1.\n"); 1478a8f23d8fSArnaldo Carvalho de Melo 1479a8f23d8fSArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 14805229e366SArnaldo Carvalho de Melo "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n" 14815229e366SArnaldo Carvalho de Melo "Hint:\tThe current value is %d.", value); 1482a8f23d8fSArnaldo Carvalho de Melo break; 1483d9aade7fSArnaldo Carvalho de Melo case EINVAL: { 1484515dbe48SJiri Olsa struct evsel *first = evlist__first(evlist); 1485d9aade7fSArnaldo Carvalho de Melo int max_freq; 1486d9aade7fSArnaldo Carvalho de Melo 1487d9aade7fSArnaldo Carvalho de Melo if (sysctl__read_int("kernel/perf_event_max_sample_rate", &max_freq) < 0) 1488d9aade7fSArnaldo Carvalho de Melo goto out_default; 1489d9aade7fSArnaldo Carvalho de Melo 14901fc632ceSJiri Olsa if (first->core.attr.sample_freq < (u64)max_freq) 1491d9aade7fSArnaldo Carvalho de Melo goto out_default; 1492d9aade7fSArnaldo Carvalho de Melo 1493d9aade7fSArnaldo Carvalho de Melo printed = scnprintf(buf, size, 1494d9aade7fSArnaldo Carvalho de Melo "Error:\t%s.\n" 1495d9aade7fSArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_max_sample_rate.\n" 1496d9aade7fSArnaldo Carvalho de Melo "Hint:\tThe current value is %d and %" PRIu64 " is being requested.", 14971fc632ceSJiri Olsa emsg, max_freq, first->core.attr.sample_freq); 1498d9aade7fSArnaldo Carvalho de Melo break; 1499d9aade7fSArnaldo Carvalho de Melo } 1500a8f23d8fSArnaldo Carvalho de Melo default: 1501d9aade7fSArnaldo Carvalho de Melo out_default: 1502a8f23d8fSArnaldo Carvalho de Melo scnprintf(buf, size, "%s", emsg); 1503a8f23d8fSArnaldo Carvalho de Melo break; 1504a8f23d8fSArnaldo Carvalho de Melo } 1505a8f23d8fSArnaldo Carvalho de Melo 1506a8f23d8fSArnaldo Carvalho de Melo return 0; 1507a8f23d8fSArnaldo Carvalho de Melo } 1508a025e4f0SAdrian Hunter 150963503dbaSJiri Olsa int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) 1510956fa571SArnaldo Carvalho de Melo { 1511c8b5f2c9SArnaldo Carvalho de Melo char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); 1512f6fa4375SJiri Olsa int pages_attempted = evlist->core.mmap_len / 1024, pages_max_per_user, printed = 0; 1513956fa571SArnaldo Carvalho de Melo 1514956fa571SArnaldo Carvalho de Melo switch (err) { 1515956fa571SArnaldo Carvalho de Melo case EPERM: 1516e5d4a290SArnaldo Carvalho de Melo sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); 1517e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1518e965bea1SArnaldo Carvalho de Melo "Error:\t%s.\n" 1519956fa571SArnaldo Carvalho de Melo "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" 1520e965bea1SArnaldo Carvalho de Melo "Hint:\tTried using %zd kB.\n", 1521e5d4a290SArnaldo Carvalho de Melo emsg, pages_max_per_user, pages_attempted); 1522e965bea1SArnaldo Carvalho de Melo 1523e965bea1SArnaldo Carvalho de Melo if (pages_attempted >= pages_max_per_user) { 1524e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1525e965bea1SArnaldo Carvalho de Melo "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", 1526e965bea1SArnaldo Carvalho de Melo pages_max_per_user + pages_attempted); 1527e965bea1SArnaldo Carvalho de Melo } 1528e965bea1SArnaldo Carvalho de Melo 1529e965bea1SArnaldo Carvalho de Melo printed += scnprintf(buf + printed, size - printed, 1530e965bea1SArnaldo Carvalho de Melo "Hint:\tTry using a smaller -m/--mmap-pages value."); 1531956fa571SArnaldo Carvalho de Melo break; 1532956fa571SArnaldo Carvalho de Melo default: 1533956fa571SArnaldo Carvalho de Melo scnprintf(buf, size, "%s", emsg); 1534956fa571SArnaldo Carvalho de Melo break; 1535956fa571SArnaldo Carvalho de Melo } 1536956fa571SArnaldo Carvalho de Melo 1537956fa571SArnaldo Carvalho de Melo return 0; 1538956fa571SArnaldo Carvalho de Melo } 1539956fa571SArnaldo Carvalho de Melo 154063503dbaSJiri Olsa void perf_evlist__to_front(struct evlist *evlist, 154132dcd021SJiri Olsa struct evsel *move_evsel) 1542a025e4f0SAdrian Hunter { 154332dcd021SJiri Olsa struct evsel *evsel, *n; 1544a025e4f0SAdrian Hunter LIST_HEAD(move); 1545a025e4f0SAdrian Hunter 1546515dbe48SJiri Olsa if (move_evsel == evlist__first(evlist)) 1547a025e4f0SAdrian Hunter return; 1548a025e4f0SAdrian Hunter 1549e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry_safe(evlist, n, evsel) { 1550a025e4f0SAdrian Hunter if (evsel->leader == move_evsel->leader) 1551b27c4eceSJiri Olsa list_move_tail(&evsel->core.node, &move); 1552a025e4f0SAdrian Hunter } 1553a025e4f0SAdrian Hunter 1554ce9036a6SJiri Olsa list_splice(&move, &evlist->core.entries); 1555a025e4f0SAdrian Hunter } 155660b0896cSAdrian Hunter 155763503dbaSJiri Olsa void perf_evlist__set_tracking_event(struct evlist *evlist, 155832dcd021SJiri Olsa struct evsel *tracking_evsel) 155960b0896cSAdrian Hunter { 156032dcd021SJiri Olsa struct evsel *evsel; 156160b0896cSAdrian Hunter 156260b0896cSAdrian Hunter if (tracking_evsel->tracking) 156360b0896cSAdrian Hunter return; 156460b0896cSAdrian Hunter 1565e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 156660b0896cSAdrian Hunter if (evsel != tracking_evsel) 156760b0896cSAdrian Hunter evsel->tracking = false; 156860b0896cSAdrian Hunter } 156960b0896cSAdrian Hunter 157060b0896cSAdrian Hunter tracking_evsel->tracking = true; 157160b0896cSAdrian Hunter } 15727630b3e2SWang Nan 157332dcd021SJiri Olsa struct evsel * 157463503dbaSJiri Olsa perf_evlist__find_evsel_by_str(struct evlist *evlist, 15757630b3e2SWang Nan const char *str) 15767630b3e2SWang Nan { 157732dcd021SJiri Olsa struct evsel *evsel; 15787630b3e2SWang Nan 1579e5cadb93SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 15807630b3e2SWang Nan if (!evsel->name) 15817630b3e2SWang Nan continue; 15827630b3e2SWang Nan if (strcmp(str, evsel->name) == 0) 15837630b3e2SWang Nan return evsel; 15847630b3e2SWang Nan } 15857630b3e2SWang Nan 15867630b3e2SWang Nan return NULL; 15877630b3e2SWang Nan } 158854cc54deSWang Nan 158963503dbaSJiri Olsa void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, 159054cc54deSWang Nan enum bkw_mmap_state state) 159154cc54deSWang Nan { 159254cc54deSWang Nan enum bkw_mmap_state old_state = evlist->bkw_mmap_state; 159354cc54deSWang Nan enum action { 159454cc54deSWang Nan NONE, 159554cc54deSWang Nan PAUSE, 159654cc54deSWang Nan RESUME, 159754cc54deSWang Nan } action = NONE; 159854cc54deSWang Nan 15990b72d69aSWang Nan if (!evlist->overwrite_mmap) 160054cc54deSWang Nan return; 160154cc54deSWang Nan 160254cc54deSWang Nan switch (old_state) { 160354cc54deSWang Nan case BKW_MMAP_NOTREADY: { 160454cc54deSWang Nan if (state != BKW_MMAP_RUNNING) 1605dd8bd53aSLuis de Bethencourt goto state_err; 160654cc54deSWang Nan break; 160754cc54deSWang Nan } 160854cc54deSWang Nan case BKW_MMAP_RUNNING: { 160954cc54deSWang Nan if (state != BKW_MMAP_DATA_PENDING) 161054cc54deSWang Nan goto state_err; 161154cc54deSWang Nan action = PAUSE; 161254cc54deSWang Nan break; 161354cc54deSWang Nan } 161454cc54deSWang Nan case BKW_MMAP_DATA_PENDING: { 161554cc54deSWang Nan if (state != BKW_MMAP_EMPTY) 161654cc54deSWang Nan goto state_err; 161754cc54deSWang Nan break; 161854cc54deSWang Nan } 161954cc54deSWang Nan case BKW_MMAP_EMPTY: { 162054cc54deSWang Nan if (state != BKW_MMAP_RUNNING) 162154cc54deSWang Nan goto state_err; 162254cc54deSWang Nan action = RESUME; 162354cc54deSWang Nan break; 162454cc54deSWang Nan } 162554cc54deSWang Nan default: 162654cc54deSWang Nan WARN_ONCE(1, "Shouldn't get there\n"); 162754cc54deSWang Nan } 162854cc54deSWang Nan 162954cc54deSWang Nan evlist->bkw_mmap_state = state; 163054cc54deSWang Nan 163154cc54deSWang Nan switch (action) { 163254cc54deSWang Nan case PAUSE: 163354cc54deSWang Nan perf_evlist__pause(evlist); 163454cc54deSWang Nan break; 163554cc54deSWang Nan case RESUME: 163654cc54deSWang Nan perf_evlist__resume(evlist); 163754cc54deSWang Nan break; 163854cc54deSWang Nan case NONE: 163954cc54deSWang Nan default: 164054cc54deSWang Nan break; 164154cc54deSWang Nan } 164254cc54deSWang Nan 164354cc54deSWang Nan state_err: 164454cc54deSWang Nan return; 164554cc54deSWang Nan } 164607d6f446SArnaldo Carvalho de Melo 164763503dbaSJiri Olsa bool perf_evlist__exclude_kernel(struct evlist *evlist) 164807d6f446SArnaldo Carvalho de Melo { 164932dcd021SJiri Olsa struct evsel *evsel; 165007d6f446SArnaldo Carvalho de Melo 165107d6f446SArnaldo Carvalho de Melo evlist__for_each_entry(evlist, evsel) { 16521fc632ceSJiri Olsa if (!evsel->core.attr.exclude_kernel) 165307d6f446SArnaldo Carvalho de Melo return false; 165407d6f446SArnaldo Carvalho de Melo } 165507d6f446SArnaldo Carvalho de Melo 165607d6f446SArnaldo Carvalho de Melo return true; 165707d6f446SArnaldo Carvalho de Melo } 1658e2bdbe80SJin Yao 1659e2bdbe80SJin Yao /* 1660e2bdbe80SJin Yao * Events in data file are not collect in groups, but we still want 1661e2bdbe80SJin Yao * the group display. Set the artificial group and set the leader's 1662e2bdbe80SJin Yao * forced_leader flag to notify the display code. 1663e2bdbe80SJin Yao */ 166463503dbaSJiri Olsa void perf_evlist__force_leader(struct evlist *evlist) 1665e2bdbe80SJin Yao { 1666e2bdbe80SJin Yao if (!evlist->nr_groups) { 1667515dbe48SJiri Olsa struct evsel *leader = evlist__first(evlist); 1668e2bdbe80SJin Yao 1669e2bdbe80SJin Yao perf_evlist__set_leader(evlist); 1670e2bdbe80SJin Yao leader->forced_leader = true; 1671e2bdbe80SJin Yao } 1672e2bdbe80SJin Yao } 1673c3537fc2SAndi Kleen 167463503dbaSJiri Olsa struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, 16754804e011SAndi Kleen struct evsel *evsel, 16764804e011SAndi Kleen bool close) 1677c3537fc2SAndi Kleen { 167832dcd021SJiri Olsa struct evsel *c2, *leader; 1679c3537fc2SAndi Kleen bool is_open = true; 1680c3537fc2SAndi Kleen 1681c3537fc2SAndi Kleen leader = evsel->leader; 1682c3537fc2SAndi Kleen pr_debug("Weak group for %s/%d failed\n", 16835643b1a5SJiri Olsa leader->name, leader->core.nr_members); 1684c3537fc2SAndi Kleen 1685c3537fc2SAndi Kleen /* 1686c3537fc2SAndi Kleen * for_each_group_member doesn't work here because it doesn't 1687c3537fc2SAndi Kleen * include the first entry. 1688c3537fc2SAndi Kleen */ 1689c3537fc2SAndi Kleen evlist__for_each_entry(evsel_list, c2) { 1690c3537fc2SAndi Kleen if (c2 == evsel) 1691c3537fc2SAndi Kleen is_open = false; 1692c3537fc2SAndi Kleen if (c2->leader == leader) { 16934804e011SAndi Kleen if (is_open && close) 16945a40e199SAndi Kleen perf_evsel__close(&c2->core); 1695c3537fc2SAndi Kleen c2->leader = c2; 16965643b1a5SJiri Olsa c2->core.nr_members = 0; 16974804e011SAndi Kleen /* 16984804e011SAndi Kleen * Set this for all former members of the group 16994804e011SAndi Kleen * to indicate they get reopened. 17004804e011SAndi Kleen */ 17014804e011SAndi Kleen c2->reset_group = true; 1702c3537fc2SAndi Kleen } 1703c3537fc2SAndi Kleen } 1704c3537fc2SAndi Kleen return leader; 1705c3537fc2SAndi Kleen } 1706657ee553SSong Liu 170763503dbaSJiri Olsa int perf_evlist__add_sb_event(struct evlist **evlist, 1708657ee553SSong Liu struct perf_event_attr *attr, 1709657ee553SSong Liu perf_evsel__sb_cb_t cb, 1710657ee553SSong Liu void *data) 1711657ee553SSong Liu { 171232dcd021SJiri Olsa struct evsel *evsel; 1713657ee553SSong Liu bool new_evlist = (*evlist) == NULL; 1714657ee553SSong Liu 1715657ee553SSong Liu if (*evlist == NULL) 17160f98b11cSJiri Olsa *evlist = evlist__new(); 1717657ee553SSong Liu if (*evlist == NULL) 1718657ee553SSong Liu return -1; 1719657ee553SSong Liu 1720657ee553SSong Liu if (!attr->sample_id_all) { 1721657ee553SSong Liu pr_warning("enabling sample_id_all for all side band events\n"); 1722657ee553SSong Liu attr->sample_id_all = 1; 1723657ee553SSong Liu } 1724657ee553SSong Liu 17256484d2f9SJiri Olsa evsel = perf_evsel__new_idx(attr, (*evlist)->core.nr_entries); 1726657ee553SSong Liu if (!evsel) 1727657ee553SSong Liu goto out_err; 1728657ee553SSong Liu 1729657ee553SSong Liu evsel->side_band.cb = cb; 1730657ee553SSong Liu evsel->side_band.data = data; 1731a1cf3a75SJiri Olsa evlist__add(*evlist, evsel); 1732657ee553SSong Liu return 0; 1733657ee553SSong Liu 1734657ee553SSong Liu out_err: 1735657ee553SSong Liu if (new_evlist) { 1736c12995a5SJiri Olsa evlist__delete(*evlist); 1737657ee553SSong Liu *evlist = NULL; 1738657ee553SSong Liu } 1739657ee553SSong Liu return -1; 1740657ee553SSong Liu } 1741657ee553SSong Liu 1742657ee553SSong Liu static void *perf_evlist__poll_thread(void *arg) 1743657ee553SSong Liu { 174463503dbaSJiri Olsa struct evlist *evlist = arg; 1745657ee553SSong Liu bool draining = false; 1746adc6257cSJiri Olsa int i, done = 0; 1747b397f846SArnaldo Carvalho de Melo /* 1748b397f846SArnaldo Carvalho de Melo * In order to read symbols from other namespaces perf to needs to call 1749b397f846SArnaldo Carvalho de Melo * setns(2). This isn't permitted if the struct_fs has multiple users. 1750b397f846SArnaldo Carvalho de Melo * unshare(2) the fs so that we may continue to setns into namespaces 1751b397f846SArnaldo Carvalho de Melo * that we're observing when, for instance, reading the build-ids at 1752b397f846SArnaldo Carvalho de Melo * the end of a 'perf record' session. 1753b397f846SArnaldo Carvalho de Melo */ 1754b397f846SArnaldo Carvalho de Melo unshare(CLONE_FS); 1755657ee553SSong Liu 1756adc6257cSJiri Olsa while (!done) { 1757adc6257cSJiri Olsa bool got_data = false; 1758adc6257cSJiri Olsa 1759adc6257cSJiri Olsa if (evlist->thread.done) 1760657ee553SSong Liu draining = true; 1761657ee553SSong Liu 1762657ee553SSong Liu if (!draining) 176380ab2987SJiri Olsa evlist__poll(evlist, 1000); 1764657ee553SSong Liu 1765c976ee11SJiri Olsa for (i = 0; i < evlist->core.nr_mmaps; i++) { 1766a5830532SJiri Olsa struct mmap *map = &evlist->mmap[i]; 1767657ee553SSong Liu union perf_event *event; 1768657ee553SSong Liu 17697c4d4182SJiri Olsa if (perf_mmap__read_init(&map->core)) 1770657ee553SSong Liu continue; 1771151ed5d7SJiri Olsa while ((event = perf_mmap__read_event(&map->core)) != NULL) { 177232dcd021SJiri Olsa struct evsel *evsel = perf_evlist__event2evsel(evlist, event); 1773657ee553SSong Liu 1774657ee553SSong Liu if (evsel && evsel->side_band.cb) 1775657ee553SSong Liu evsel->side_band.cb(event, evsel->side_band.data); 1776657ee553SSong Liu else 1777657ee553SSong Liu pr_warning("cannot locate proper evsel for the side band event\n"); 1778657ee553SSong Liu 17797728fa0cSJiri Olsa perf_mmap__consume(&map->core); 1780adc6257cSJiri Olsa got_data = true; 1781657ee553SSong Liu } 178232fdc2caSJiri Olsa perf_mmap__read_done(&map->core); 1783657ee553SSong Liu } 1784adc6257cSJiri Olsa 1785adc6257cSJiri Olsa if (draining && !got_data) 1786adc6257cSJiri Olsa break; 1787657ee553SSong Liu } 1788657ee553SSong Liu return NULL; 1789657ee553SSong Liu } 1790657ee553SSong Liu 179163503dbaSJiri Olsa int perf_evlist__start_sb_thread(struct evlist *evlist, 1792657ee553SSong Liu struct target *target) 1793657ee553SSong Liu { 179432dcd021SJiri Olsa struct evsel *counter; 1795657ee553SSong Liu 1796657ee553SSong Liu if (!evlist) 1797657ee553SSong Liu return 0; 1798657ee553SSong Liu 1799657ee553SSong Liu if (perf_evlist__create_maps(evlist, target)) 1800657ee553SSong Liu goto out_delete_evlist; 1801657ee553SSong Liu 1802657ee553SSong Liu evlist__for_each_entry(evlist, counter) { 1803f72f901dSJiri Olsa if (evsel__open(counter, evlist->core.cpus, 180403617c22SJiri Olsa evlist->core.threads) < 0) 1805657ee553SSong Liu goto out_delete_evlist; 1806657ee553SSong Liu } 1807657ee553SSong Liu 18089521b5f2SJiri Olsa if (evlist__mmap(evlist, UINT_MAX)) 1809657ee553SSong Liu goto out_delete_evlist; 1810657ee553SSong Liu 1811657ee553SSong Liu evlist__for_each_entry(evlist, counter) { 1812ec7f24efSJiri Olsa if (evsel__enable(counter)) 1813657ee553SSong Liu goto out_delete_evlist; 1814657ee553SSong Liu } 1815657ee553SSong Liu 1816657ee553SSong Liu evlist->thread.done = 0; 1817657ee553SSong Liu if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist)) 1818657ee553SSong Liu goto out_delete_evlist; 1819657ee553SSong Liu 1820657ee553SSong Liu return 0; 1821657ee553SSong Liu 1822657ee553SSong Liu out_delete_evlist: 1823c12995a5SJiri Olsa evlist__delete(evlist); 1824657ee553SSong Liu evlist = NULL; 1825657ee553SSong Liu return -1; 1826657ee553SSong Liu } 1827657ee553SSong Liu 182863503dbaSJiri Olsa void perf_evlist__stop_sb_thread(struct evlist *evlist) 1829657ee553SSong Liu { 1830657ee553SSong Liu if (!evlist) 1831657ee553SSong Liu return; 1832657ee553SSong Liu evlist->thread.done = 1; 1833657ee553SSong Liu pthread_join(evlist->thread.th, NULL); 1834c12995a5SJiri Olsa evlist__delete(evlist); 1835657ee553SSong Liu } 1836