diff options
Diffstat (limited to 'tools/perf/util/evlist.c')
| -rw-r--r-- | tools/perf/util/evlist.c | 511 |
1 files changed, 304 insertions, 207 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 1a238b245b3a..c3d784727810 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -5,67 +5,70 @@ * Parts came from builtin-{top,stat,record}.c, see those files for further * copyright notes. */ -#include <api/fs/fs.h> +#include "evlist.h" + #include <errno.h> #include <inttypes.h> -#include <poll.h> -#include "cpumap.h" -#include "util/mmap.h" -#include "thread_map.h" -#include "target.h" -#include "dwarf-regs.h" -#include "evlist.h" -#include "evsel.h" -#include "record.h" -#include "debug.h" -#include "units.h" -#include "bpf_counter.h" -#include <internal/lib.h> // page_size -#include "affinity.h" -#include "../perf.h" -#include "asm/bug.h" -#include "bpf-event.h" -#include "util/event.h" -#include "util/string2.h" -#include "util/perf_api_probe.h" -#include "util/evsel_fprintf.h" -#include "util/pmu.h" -#include "util/sample.h" -#include "util/bpf-filter.h" -#include "util/stat.h" -#include "util/util.h" -#include "util/env.h" -#include "util/intel-tpebs.h" -#include "util/metricgroup.h" -#include "util/strbuf.h" #include <signal.h> -#include <unistd.h> -#include <sched.h> #include <stdlib.h> - -#include "parse-events.h" -#include <subcmd/parse-options.h> +#include <string.h> #include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/prctl.h> -#include <sys/timerfd.h> -#include <sys/wait.h> - #include <linux/bitops.h> +#include <linux/err.h> #include <linux/hash.h> #include <linux/log2.h> -#include <linux/err.h> #include <linux/string.h> #include <linux/time64.h> #include <linux/zalloc.h> +#include <poll.h> +#include <sched.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/prctl.h> +#include <sys/timerfd.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <api/fs/fs.h> +#include <internal/lib.h> // page_size +#include <internal/rc_check.h> +#include <internal/xyarray.h> +#include <perf/cpumap.h> #include <perf/evlist.h> #include <perf/evsel.h> -#include <perf/cpumap.h> #include <perf/mmap.h> +#include <subcmd/parse-options.h> -#include <internal/xyarray.h> +#include "../perf.h" +#include "affinity.h" +#include "asm/bug.h" +#include "bpf-event.h" +#include "bpf-filter.h" +#include "bpf_counter.h" +#include "cpumap.h" +#include "debug.h" +#include "dwarf-regs.h" +#include "env.h" +#include "event.h" +#include "evsel.h" +#include "evsel_fprintf.h" +#include "intel-tpebs.h" +#include "metricgroup.h" +#include "mmap.h" +#include "parse-events.h" +#include "perf_api_probe.h" +#include "pmu.h" +#include "pmus.h" +#include "record.h" +#include "sample.h" +#include "stat.h" +#include "strbuf.h" +#include "string2.h" +#include "target.h" +#include "thread_map.h" +#include "units.h" +#include "util.h" #ifdef LACKS_SIGQUEUE_PROTOTYPE int sigqueue(pid_t pid, int sig, const union sigval value); @@ -74,29 +77,31 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) -void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads) -{ - perf_evlist__init(&evlist->core); - perf_evlist__set_maps(&evlist->core, cpus, threads); - evlist->workload.pid = -1; - evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; - evlist->ctl_fd.fd = -1; - evlist->ctl_fd.ack = -1; - evlist->ctl_fd.pos = -1; - evlist->nr_br_cntr = -1; - metricgroup__rblist_init(&evlist->metric_events); - INIT_LIST_HEAD(&evlist->deferred_samples); -} +static void event_enable_timer__exit(struct event_enable_timer **ep); struct evlist *evlist__new(void) { - struct evlist *evlist = zalloc(sizeof(*evlist)); - - if (evlist != NULL) - evlist__init(evlist, NULL, NULL); - - return evlist; + struct evlist *result; + RC_STRUCT(evlist) *evlist; + + evlist = zalloc(sizeof(*evlist)); + if (ADD_RC_CHK(result, evlist)) { + perf_evlist__init(evlist__core(result)); + perf_evlist__set_maps(evlist__core(result), /*cpus=*/NULL, /*threads=*/NULL); + evlist__set_workload_pid(result, -1); + evlist__set_bkw_mmap_state(result, BKW_MMAP_NOTREADY); + evlist__set_ctl_fd_fd(result, -1); + evlist__set_ctl_fd_ack(result, -1); + evlist__set_ctl_fd_pos(result, -1); + evlist__set_nr_br_cntr(result, -1); + metricgroup__rblist_init(evlist__metric_events(result)); + INIT_LIST_HEAD(&evlist->deferred_samples); + refcount_set(evlist__refcnt(result), 1); + } else { + free(evlist); + result = NULL; + } + return result; } struct evlist *evlist__new_default(const struct target *target, bool sample_callchains) @@ -104,7 +109,6 @@ struct evlist *evlist__new_default(const struct target *target, bool sample_call struct evlist *evlist = evlist__new(); bool can_profile_kernel; struct perf_pmu *pmu = NULL; - struct evsel *evsel; char buf[256]; int err; @@ -131,14 +135,16 @@ struct evlist *evlist__new_default(const struct target *target, bool sample_call } /* If there is only 1 event a sample identifier isn't necessary. */ - if (evlist->core.nr_entries > 1) { + if (evlist__nr_entries(evlist) > 1) { + struct evsel *evsel; + evlist__for_each_entry(evlist, evsel) evsel__set_sample_id(evsel, /*can_sample_identifier=*/false); } return evlist; out_err: - evlist__delete(evlist); + evlist__put(evlist); return NULL; } @@ -147,13 +153,23 @@ struct evlist *evlist__new_dummy(void) struct evlist *evlist = evlist__new(); if (evlist && evlist__add_dummy(evlist)) { - evlist__delete(evlist); + evlist__put(evlist); evlist = NULL; } return evlist; } +struct evlist *evlist__get(struct evlist *evlist) +{ + struct evlist *result; + + if (RC_CHK_GET(result, evlist)) + refcount_inc(evlist__refcnt(evlist)); + + return result; +} + /** * evlist__set_id_pos - set the positions of event ids. * @evlist: selected event list @@ -165,8 +181,8 @@ void evlist__set_id_pos(struct evlist *evlist) { struct evsel *first = evlist__first(evlist); - evlist->id_pos = first->id_pos; - evlist->is_pos = first->is_pos; + RC_CHK_ACCESS(evlist)->id_pos = first->id_pos; + RC_CHK_ACCESS(evlist)->is_pos = first->is_pos; } static void evlist__update_id_pos(struct evlist *evlist) @@ -185,49 +201,85 @@ static void evlist__purge(struct evlist *evlist) evlist__for_each_entry_safe(evlist, n, pos) { list_del_init(&pos->core.node); + if (pos->evlist) { + if (!RC_CHK_EQUAL(pos->evlist, evlist)) { + evlist__put(pos->evlist); + } else { + refcount_dec_and_test(evlist__refcnt(pos->evlist)); + RC_CHK_PUT(pos->evlist); + } + } pos->evlist = NULL; - evsel__delete(pos); + evsel__put(pos); } - evlist->core.nr_entries = 0; + evlist__core(evlist)->nr_entries = 0; } -void evlist__exit(struct evlist *evlist) +static void evlist__exit(struct evlist *evlist) { - metricgroup__rblist_exit(&evlist->metric_events); - event_enable_timer__exit(&evlist->eet); - zfree(&evlist->mmap); - zfree(&evlist->overwrite_mmap); - perf_evlist__exit(&evlist->core); + metricgroup__rblist_exit(evlist__metric_events(evlist)); + event_enable_timer__exit(&RC_CHK_ACCESS(evlist)->eet); + free(evlist__mmap(evlist)); + free(evlist__overwrite_mmap(evlist)); + perf_evlist__exit(evlist__core(evlist)); } -void evlist__delete(struct evlist *evlist) +void evlist__put(struct evlist *evlist) { + struct evsel *evsel; + unsigned int count, ref_cnt; + if (evlist == NULL) return; + if (refcount_dec_and_test(evlist__refcnt(evlist))) + goto out_delete; + +retry: + count = refcount_read(evlist__refcnt(evlist)); + ref_cnt = count; + evlist__for_each_entry(evlist, evsel) { + if (RC_CHK_EQUAL(evsel->evlist, evlist) && count && + refcount_read(&evsel->refcnt) == 1) + count--; + } + if (refcount_read(evlist__refcnt(evlist)) != ref_cnt) + goto retry; + + if (count != 0) { + /* + * Not the last reference except for back references from + * evsels. + */ + RC_CHK_PUT(evlist); + return; + } +out_delete: evlist__free_stats(evlist); - evlist__munmap(evlist); + evlist__do_munmap(evlist); evlist__close(evlist); evlist__purge(evlist); evlist__exit(evlist); - free(evlist); + RC_CHK_FREE(evlist); } void evlist__add(struct evlist *evlist, struct evsel *entry) { - perf_evlist__add(&evlist->core, &entry->core); - entry->evlist = evlist; + perf_evlist__add(evlist__core(evlist), &entry->core); + evlist__put(entry->evlist); + entry->evlist = evlist__get(evlist); entry->tracking = !entry->core.idx; - if (evlist->core.nr_entries == 1) + if (evlist__nr_entries(evlist) == 1) evlist__set_id_pos(evlist); } void evlist__remove(struct evlist *evlist, struct evsel *evsel) { + perf_evlist__remove(evlist__core(evlist), &evsel->core); + evlist__put(evsel->evlist); evsel->evlist = NULL; - perf_evlist__remove(&evlist->core, &evsel->core); } void evlist__splice_list_tail(struct evlist *evlist, struct list_head *list) @@ -276,7 +328,7 @@ out: static void evlist__set_leader(struct evlist *evlist) { - perf_evlist__set_leader(&evlist->core); + perf_evlist__set_leader(evlist__core(evlist)); } static struct evsel *evlist__dummy_event(struct evlist *evlist) @@ -290,7 +342,7 @@ static struct evsel *evlist__dummy_event(struct evlist *evlist) .sample_period = 1, }; - return evsel__new_idx(&attr, evlist->core.nr_entries); + return evsel__new_idx(&attr, evlist__nr_entries(evlist)); } int evlist__add_dummy(struct evlist *evlist) @@ -379,8 +431,8 @@ static bool evlist__use_affinity(struct evlist *evlist) struct perf_cpu_map *used_cpus = NULL; bool ret = false; - if (evlist->no_affinity || !evlist->core.user_requested_cpus || - cpu_map__is_dummy(evlist->core.user_requested_cpus)) + if (evlist__no_affinity(evlist) || !evlist__core(evlist)->user_requested_cpus || + cpu_map__is_dummy(evlist__core(evlist)->user_requested_cpus)) return false; evlist__for_each_entry(evlist, pos) { @@ -435,7 +487,7 @@ void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evlist *e .evsel = NULL, .cpu_map_idx = 0, .evlist_cpu_map_idx = 0, - .evlist_cpu_map_nr = perf_cpu_map__nr(evlist->core.all_cpus), + .evlist_cpu_map_nr = perf_cpu_map__nr(evlist__core(evlist)->all_cpus), .cpu = (struct perf_cpu){ .cpu = -1}, .affinity = NULL, }; @@ -451,7 +503,7 @@ void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evlist *e itr->affinity = &itr->saved_affinity; } itr->evsel = evlist__first(evlist); - itr->cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0); + itr->cpu = perf_cpu_map__cpu(evlist__core(evlist)->all_cpus, 0); if (itr->affinity) affinity__set(itr->affinity, itr->cpu.cpu); itr->cpu_map_idx = perf_cpu_map__idx(itr->evsel->core.cpus, itr->cpu); @@ -486,7 +538,7 @@ void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr) if (evlist_cpu_itr->evlist_cpu_map_idx < evlist_cpu_itr->evlist_cpu_map_nr) { evlist_cpu_itr->evsel = evlist__first(evlist_cpu_itr->container); evlist_cpu_itr->cpu = - perf_cpu_map__cpu(evlist_cpu_itr->container->core.all_cpus, + perf_cpu_map__cpu(evlist__core(evlist_cpu_itr->container)->all_cpus, evlist_cpu_itr->evlist_cpu_map_idx); if (evlist_cpu_itr->affinity) affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu.cpu); @@ -513,7 +565,7 @@ static int evsel__strcmp(struct evsel *pos, char *evsel_name) return !evsel__name_is(pos, evsel_name); } -static int evlist__is_enabled(struct evlist *evlist) +static bool evlist__is_enabled(struct evlist *evlist) { struct evsel *pos; @@ -570,10 +622,7 @@ static void __evlist__disable(struct evlist *evlist, char *evsel_name, bool excl * If we disabled only single event, we need to check * the enabled state of the evlist manually. */ - if (evsel_name) - evlist->enabled = evlist__is_enabled(evlist); - else - evlist->enabled = false; + evlist__set_enabled(evlist, evsel_name ? evlist__is_enabled(evlist) : false); } void evlist__disable(struct evlist *evlist) @@ -624,7 +673,7 @@ static void __evlist__enable(struct evlist *evlist, char *evsel_name, bool excl_ * so the toggle can work properly and toggle to * 'disabled' state. */ - evlist->enabled = true; + evlist__set_enabled(evlist, true); } void evlist__enable(struct evlist *evlist) @@ -644,23 +693,24 @@ void evlist__enable_evsel(struct evlist *evlist, char *evsel_name) void evlist__toggle_enable(struct evlist *evlist) { - (evlist->enabled ? evlist__disable : evlist__enable)(evlist); + (evlist__enabled(evlist) ? evlist__disable : evlist__enable)(evlist); } int evlist__add_pollfd(struct evlist *evlist, int fd) { - return perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN, fdarray_flag__default); + return perf_evlist__add_pollfd(evlist__core(evlist), fd, NULL, POLLIN, + fdarray_flag__default); } int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) { - return perf_evlist__filter_pollfd(&evlist->core, revents_and_mask); + return perf_evlist__filter_pollfd(evlist__core(evlist), revents_and_mask); } #ifdef HAVE_EVENTFD_SUPPORT int evlist__add_wakeup_eventfd(struct evlist *evlist, int fd) { - return perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN, + return perf_evlist__add_pollfd(evlist__core(evlist), fd, NULL, POLLIN, fdarray_flag__nonfilterable | fdarray_flag__non_perf_event); } @@ -668,7 +718,7 @@ int evlist__add_wakeup_eventfd(struct evlist *evlist, int fd) int evlist__poll(struct evlist *evlist, int timeout) { - return perf_evlist__poll(&evlist->core, timeout); + return perf_evlist__poll(evlist__core(evlist), timeout); } struct perf_sample_id *evlist__id2sid(struct evlist *evlist, u64 id) @@ -678,7 +728,7 @@ struct perf_sample_id *evlist__id2sid(struct evlist *evlist, u64 id) int hash; hash = hash_64(id, PERF_EVLIST__HLIST_BITS); - head = &evlist->core.heads[hash]; + head = &evlist__core(evlist)->heads[hash]; hlist_for_each_entry(sid, head, node) if (sid->id == id) @@ -691,7 +741,7 @@ struct evsel *evlist__id2evsel(struct evlist *evlist, u64 id) { struct perf_sample_id *sid; - if (evlist->core.nr_entries == 1 || !id) + if (evlist__nr_entries(evlist) == 1 || !id) return evlist__first(evlist); sid = evlist__id2sid(evlist, id); @@ -726,13 +776,13 @@ static int evlist__event2id(struct evlist *evlist, union perf_event *event, u64 n = (event->header.size - sizeof(event->header)) >> 3; if (event->header.type == PERF_RECORD_SAMPLE) { - if (evlist->id_pos >= n) + if (evlist__id_pos(evlist) >= n) return -1; - *id = array[evlist->id_pos]; + *id = array[evlist__id_pos(evlist)]; } else { - if (evlist->is_pos > n) + if (evlist__is_pos(evlist) > n) return -1; - n -= evlist->is_pos; + n -= evlist__is_pos(evlist); *id = array[n]; } return 0; @@ -746,7 +796,7 @@ struct evsel *evlist__event2evsel(struct evlist *evlist, union perf_event *event int hash; u64 id; - if (evlist->core.nr_entries == 1) + if (evlist__nr_entries(evlist) == 1) return first; if (!first->core.attr.sample_id_all && @@ -761,7 +811,7 @@ struct evsel *evlist__event2evsel(struct evlist *evlist, union perf_event *event return first; hash = hash_64(id, PERF_EVLIST__HLIST_BITS); - head = &evlist->core.heads[hash]; + head = &evlist__core(evlist)->heads[hash]; hlist_for_each_entry(sid, head, node) { if (sid->id == id) @@ -774,11 +824,11 @@ static int evlist__set_paused(struct evlist *evlist, bool value) { int i; - if (!evlist->overwrite_mmap) + if (!evlist__overwrite_mmap(evlist)) return 0; - for (i = 0; i < evlist->core.nr_mmaps; i++) { - int fd = evlist->overwrite_mmap[i].core.fd; + for (i = 0; i < evlist__core(evlist)->nr_mmaps; i++) { + int fd = evlist__overwrite_mmap(evlist)[i].core.fd; int err; if (fd < 0) @@ -804,20 +854,20 @@ static void evlist__munmap_nofree(struct evlist *evlist) { int i; - if (evlist->mmap) - for (i = 0; i < evlist->core.nr_mmaps; i++) - perf_mmap__munmap(&evlist->mmap[i].core); + if (evlist__mmap(evlist)) + for (i = 0; i < evlist__core(evlist)->nr_mmaps; i++) + perf_mmap__munmap(&evlist__mmap(evlist)[i].core); - if (evlist->overwrite_mmap) - for (i = 0; i < evlist->core.nr_mmaps; i++) - perf_mmap__munmap(&evlist->overwrite_mmap[i].core); + if (evlist__overwrite_mmap(evlist)) + for (i = 0; i < evlist__core(evlist)->nr_mmaps; i++) + perf_mmap__munmap(&evlist__overwrite_mmap(evlist)[i].core); } -void evlist__munmap(struct evlist *evlist) +void evlist__do_munmap(struct evlist *evlist) { evlist__munmap_nofree(evlist); - zfree(&evlist->mmap); - zfree(&evlist->overwrite_mmap); + zfree(&RC_CHK_ACCESS(evlist)->mmap); + zfree(&RC_CHK_ACCESS(evlist)->overwrite_mmap); } static void perf_mmap__unmap_cb(struct perf_mmap *map) @@ -831,12 +881,12 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, bool overwrite) { int i; - struct mmap *map = calloc(evlist->core.nr_mmaps, sizeof(struct mmap)); + struct mmap *map = calloc(evlist__core(evlist)->nr_mmaps, sizeof(struct mmap)); if (!map) return NULL; - for (i = 0; i < evlist->core.nr_mmaps; i++) { + for (i = 0; i < evlist__core(evlist)->nr_mmaps; i++) { struct perf_mmap *prev = i ? &map[i - 1].core : NULL; /* @@ -854,41 +904,73 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, return map; } +static struct evlist *from_list_start(struct perf_evlist *core) +{ +#ifdef REFCNT_CHECKING + RC_STRUCT(evlist) *core_evlist = container_of(core, RC_STRUCT(evlist), core); + struct evlist *evlist; + + if (ADD_RC_CHK(evlist, core_evlist)) + refcount_inc(evlist__refcnt(evlist)); + + return evlist; +#else + return container_of(core, struct evlist, core); +#endif +} + +static void from_list_end(struct evlist *evlist __maybe_unused) +{ +#ifdef REFCNT_CHECKING + evlist__put(evlist); +#endif +} + static void perf_evlist__mmap_cb_idx(struct perf_evlist *_evlist, struct perf_evsel *_evsel, struct perf_mmap_param *_mp, int idx) { - struct evlist *evlist = container_of(_evlist, struct evlist, core); + struct evlist *evlist = from_list_start(_evlist); struct mmap_params *mp = container_of(_mp, struct mmap_params, core); struct evsel *evsel = container_of(_evsel, struct evsel, core); + if (!evlist) + return; + auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, evsel, idx); + + from_list_end(evlist); } static struct perf_mmap* perf_evlist__mmap_cb_get(struct perf_evlist *_evlist, bool overwrite, int idx) { - struct evlist *evlist = container_of(_evlist, struct evlist, core); + struct evlist *evlist = from_list_start(_evlist); struct mmap *maps; - maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; + if (!evlist) + return NULL; + + maps = overwrite ? evlist__overwrite_mmap(evlist) : evlist__mmap(evlist); if (!maps) { maps = evlist__alloc_mmap(evlist, overwrite); - if (!maps) + if (!maps) { + from_list_end(evlist); return NULL; + } if (overwrite) { - evlist->overwrite_mmap = maps; - if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY) + RC_CHK_ACCESS(evlist)->overwrite_mmap = maps; + if (evlist__bkw_mmap_state(evlist) == BKW_MMAP_NOTREADY) evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); } else { - evlist->mmap = maps; + RC_CHK_ACCESS(evlist)->mmap = maps; } } - + from_list_end(evlist); return &maps[idx].core; } @@ -1045,16 +1127,16 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, .mmap = perf_evlist__mmap_cb_mmap, }; - evlist->core.mmap_len = evlist__mmap_size(pages); - pr_debug("mmap size %zuB\n", evlist->core.mmap_len); + evlist__core(evlist)->mmap_len = evlist__mmap_size(pages); + pr_debug("mmap size %zuB\n", evlist__core(evlist)->mmap_len); - auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->core.mmap_len, + auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist__core(evlist)->mmap_len, auxtrace_pages, auxtrace_overwrite); - return perf_evlist__mmap_ops(&evlist->core, &ops, &mp.core); + return perf_evlist__mmap_ops(evlist__core(evlist), &ops, &mp.core); } -int evlist__mmap(struct evlist *evlist, unsigned int pages) +int evlist__do_mmap(struct evlist *evlist, unsigned int pages) { return evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); } @@ -1096,9 +1178,9 @@ int evlist__create_maps(struct evlist *evlist, struct target *target) if (!cpus) goto out_delete_threads; - evlist->core.has_user_cpus = !!target->cpu_list; + evlist__core(evlist)->has_user_cpus = !!target->cpu_list; - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); /* as evlist now has references, put count here */ perf_cpu_map__put(cpus); @@ -1238,15 +1320,15 @@ bool evlist__valid_sample_type(struct evlist *evlist) { struct evsel *pos; - if (evlist->core.nr_entries == 1) + if (evlist__nr_entries(evlist) == 1) return true; - if (evlist->id_pos < 0 || evlist->is_pos < 0) + if (evlist__id_pos(evlist) < 0 || evlist__is_pos(evlist) < 0) return false; evlist__for_each_entry(evlist, pos) { - if (pos->id_pos != evlist->id_pos || - pos->is_pos != evlist->is_pos) + if (pos->id_pos != evlist__id_pos(evlist) || + pos->is_pos != evlist__is_pos(evlist)) return false; } @@ -1257,18 +1339,18 @@ u64 __evlist__combined_sample_type(struct evlist *evlist) { struct evsel *evsel; - if (evlist->combined_sample_type) - return evlist->combined_sample_type; + if (RC_CHK_ACCESS(evlist)->combined_sample_type) + return RC_CHK_ACCESS(evlist)->combined_sample_type; evlist__for_each_entry(evlist, evsel) - evlist->combined_sample_type |= evsel->core.attr.sample_type; + RC_CHK_ACCESS(evlist)->combined_sample_type |= evsel->core.attr.sample_type; - return evlist->combined_sample_type; + return RC_CHK_ACCESS(evlist)->combined_sample_type; } u64 evlist__combined_sample_type(struct evlist *evlist) { - evlist->combined_sample_type = 0; + RC_CHK_ACCESS(evlist)->combined_sample_type = 0; return __evlist__combined_sample_type(evlist); } @@ -1345,7 +1427,7 @@ void evlist__update_br_cntr(struct evlist *evlist) evlist__new_abbr_name(evsel->abbr_name); } } - evlist->nr_br_cntr = i; + evlist__set_nr_br_cntr(evlist, i); } bool evlist__valid_read_format(struct evlist *evlist) @@ -1395,11 +1477,6 @@ bool evlist__sample_id_all(struct evlist *evlist) return first->core.attr.sample_id_all; } -void evlist__set_selected(struct evlist *evlist, struct evsel *evsel) -{ - evlist->selected = evsel; -} - void evlist__close(struct evlist *evlist) { struct evsel *evsel; @@ -1416,7 +1493,7 @@ void evlist__close(struct evlist *evlist) perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(&evsel->core); } - perf_evlist__reset_id_hash(&evlist->core); + perf_evlist__reset_id_hash(evlist__core(evlist)); } static int evlist__create_syswide_maps(struct evlist *evlist) @@ -1443,7 +1520,7 @@ static int evlist__create_syswide_maps(struct evlist *evlist) return -ENOMEM; } - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); perf_thread_map__put(threads); perf_cpu_map__put(cpus); return 0; @@ -1458,7 +1535,8 @@ int evlist__open(struct evlist *evlist) * Default: one fd per CPU, all threads, aka systemwide * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL */ - if (evlist->core.threads == NULL && evlist->core.user_requested_cpus == NULL) { + if (evlist__core(evlist)->threads == NULL && + evlist__core(evlist)->user_requested_cpus == NULL) { err = evlist__create_syswide_maps(evlist); if (err < 0) goto out_err; @@ -1485,7 +1563,21 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const int child_ready_pipe[2], go_pipe[2]; char bf; - evlist->workload.cork_fd = -1; + if (target__none(target)) { + const char *cmd = strrchr(argv[0], '/'); + + if (cmd) + cmd++; + else + cmd = argv[0]; + + if (!strcmp(cmd, "sleep")) { + ui__warning("workload '%s' specified without the system-wide (-a) option\n", + cmd); + } + } + + evlist__set_workload_cork_fd(evlist, -1); if (pipe(child_ready_pipe) < 0) { perror("failed to create 'ready' pipe"); @@ -1497,13 +1589,13 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const goto out_close_ready_pipe; } - evlist->workload.pid = fork(); - if (evlist->workload.pid < 0) { + evlist__set_workload_pid(evlist, fork()); + if (evlist__workload_pid(evlist) < 0) { perror("failed to fork"); goto out_close_pipes; } - if (!evlist->workload.pid) { + if (!evlist__workload_pid(evlist)) { int ret; if (pipe_output) @@ -1569,12 +1661,13 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const } if (target__none(target)) { - if (evlist->core.threads == NULL) { + if (evlist__core(evlist)->threads == NULL) { fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", __func__, __LINE__); goto out_close_pipes; } - perf_thread_map__set_pid(evlist->core.threads, 0, evlist->workload.pid); + perf_thread_map__set_pid(evlist__core(evlist)->threads, 0, + evlist__workload_pid(evlist)); } close(child_ready_pipe[1]); @@ -1588,7 +1681,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const } fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); - evlist->workload.cork_fd = go_pipe[1]; + evlist__set_workload_cork_fd(evlist, go_pipe[1]); close(child_ready_pipe[0]); return 0; @@ -1603,18 +1696,18 @@ out_close_ready_pipe: int evlist__start_workload(struct evlist *evlist) { - if (evlist->workload.cork_fd >= 0) { + if (evlist__workload_cork_fd(evlist) >= 0) { char bf = 0; int ret; /* * Remove the cork, let it rip! */ - ret = write(evlist->workload.cork_fd, &bf, 1); + ret = write(evlist__workload_cork_fd(evlist), &bf, 1); if (ret < 0) perror("unable to write to pipe"); - close(evlist->workload.cork_fd); - evlist->workload.cork_fd = -1; + close(evlist__workload_cork_fd(evlist)); + evlist__set_workload_cork_fd(evlist, -1); return ret; } @@ -1625,10 +1718,10 @@ void evlist__cancel_workload(struct evlist *evlist) { int status; - if (evlist->workload.cork_fd >= 0) { - close(evlist->workload.cork_fd); - evlist->workload.cork_fd = -1; - waitpid(evlist->workload.pid, &status, WNOHANG); + if (evlist__workload_cork_fd(evlist) >= 0) { + close(evlist__workload_cork_fd(evlist)); + evlist__set_workload_cork_fd(evlist, -1); + waitpid(evlist__workload_pid(evlist), &status, WNOHANG); } } @@ -1722,7 +1815,8 @@ out_default: int evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) { - int pages_attempted = evlist->core.mmap_len / 1024, pages_max_per_user, printed = 0; + int pages_attempted = evlist__core(evlist)->mmap_len / 1024; + int pages_max_per_user, printed = 0; switch (err) { case EPERM: @@ -1765,7 +1859,7 @@ void evlist__to_front(struct evlist *evlist, struct evsel *move_evsel) list_move_tail(&evsel->core.node, &move); } - list_splice(&move, &evlist->core.entries); + list_splice(&move, &evlist__core(evlist)->entries); } struct evsel *evlist__get_tracking_event(struct evlist *evlist) @@ -1807,7 +1901,7 @@ struct evsel *evlist__findnew_tracking_event(struct evlist *evlist, bool system_ evlist__set_tracking_event(evlist, evsel); } else if (system_wide) { - perf_evlist__go_system_wide(&evlist->core, &evsel->core); + perf_evlist__go_system_wide(evlist__core(evlist), &evsel->core); } return evsel; @@ -1829,14 +1923,14 @@ struct evsel *evlist__find_evsel_by_str(struct evlist *evlist, const char *str) void evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state state) { - enum bkw_mmap_state old_state = evlist->bkw_mmap_state; + enum bkw_mmap_state old_state = evlist__bkw_mmap_state(evlist); enum action { NONE, PAUSE, RESUME, } action = NONE; - if (!evlist->overwrite_mmap) + if (!evlist__overwrite_mmap(evlist)) return; switch (old_state) { @@ -1866,7 +1960,7 @@ void evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state state) WARN_ONCE(1, "Shouldn't get there\n"); } - evlist->bkw_mmap_state = state; + evlist__set_bkw_mmap_state(evlist, state); switch (action) { case PAUSE: @@ -2044,40 +2138,41 @@ int evlist__initialize_ctlfd(struct evlist *evlist, int fd, int ack) return 0; } - evlist->ctl_fd.pos = perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN, - fdarray_flag__nonfilterable | - fdarray_flag__non_perf_event); - if (evlist->ctl_fd.pos < 0) { - evlist->ctl_fd.pos = -1; + evlist__set_ctl_fd_pos(evlist, + perf_evlist__add_pollfd(evlist__core(evlist), fd, NULL, POLLIN, + fdarray_flag__nonfilterable | + fdarray_flag__non_perf_event)); + if (evlist__ctl_fd_pos(evlist) < 0) { + evlist__set_ctl_fd_pos(evlist, -1); pr_err("Failed to add ctl fd entry: %m\n"); return -1; } - evlist->ctl_fd.fd = fd; - evlist->ctl_fd.ack = ack; + evlist__set_ctl_fd_fd(evlist, fd); + evlist__set_ctl_fd_ack(evlist, ack); return 0; } bool evlist__ctlfd_initialized(struct evlist *evlist) { - return evlist->ctl_fd.pos >= 0; + return evlist__ctl_fd_pos(evlist) >= 0; } int evlist__finalize_ctlfd(struct evlist *evlist) { - struct pollfd *entries = evlist->core.pollfd.entries; + struct pollfd *entries = evlist__core(evlist)->pollfd.entries; if (!evlist__ctlfd_initialized(evlist)) return 0; - entries[evlist->ctl_fd.pos].fd = -1; - entries[evlist->ctl_fd.pos].events = 0; - entries[evlist->ctl_fd.pos].revents = 0; + entries[evlist__ctl_fd_pos(evlist)].fd = -1; + entries[evlist__ctl_fd_pos(evlist)].events = 0; + entries[evlist__ctl_fd_pos(evlist)].revents = 0; - evlist->ctl_fd.pos = -1; - evlist->ctl_fd.ack = -1; - evlist->ctl_fd.fd = -1; + evlist__set_ctl_fd_pos(evlist, -1); + evlist__set_ctl_fd_ack(evlist, -1); + evlist__set_ctl_fd_fd(evlist, -1); return 0; } @@ -2094,7 +2189,7 @@ static int evlist__ctlfd_recv(struct evlist *evlist, enum evlist_ctl_cmd *cmd, data_size--; do { - err = read(evlist->ctl_fd.fd, &c, 1); + err = read(evlist__ctl_fd_fd(evlist), &c, 1); if (err > 0) { if (c == '\n' || c == '\0') break; @@ -2108,7 +2203,8 @@ static int evlist__ctlfd_recv(struct evlist *evlist, enum evlist_ctl_cmd *cmd, if (errno == EAGAIN || errno == EWOULDBLOCK) err = 0; else - pr_err("Failed to read from ctlfd %d: %m\n", evlist->ctl_fd.fd); + pr_err("Failed to read from ctlfd %d: %m\n", + evlist__ctl_fd_fd(evlist)); } break; } while (1); @@ -2146,13 +2242,13 @@ int evlist__ctlfd_ack(struct evlist *evlist) { int err; - if (evlist->ctl_fd.ack == -1) + if (evlist__ctl_fd_ack(evlist) == -1) return 0; - err = write(evlist->ctl_fd.ack, EVLIST_CTL_CMD_ACK_TAG, + err = write(evlist__ctl_fd_ack(evlist), EVLIST_CTL_CMD_ACK_TAG, sizeof(EVLIST_CTL_CMD_ACK_TAG)); if (err == -1) - pr_err("failed to write to ctl_ack_fd %d: %m\n", evlist->ctl_fd.ack); + pr_err("failed to write to ctl_ack_fd %d: %m\n", evlist__ctl_fd_ack(evlist)); return err; } @@ -2253,8 +2349,8 @@ int evlist__ctlfd_process(struct evlist *evlist, enum evlist_ctl_cmd *cmd) { int err = 0; char cmd_data[EVLIST_CTL_CMD_MAX_LEN]; - int ctlfd_pos = evlist->ctl_fd.pos; - struct pollfd *entries = evlist->core.pollfd.entries; + int ctlfd_pos = evlist__ctl_fd_pos(evlist); + struct pollfd *entries = evlist__core(evlist)->pollfd.entries; if (!evlist__ctlfd_initialized(evlist) || !entries[ctlfd_pos].revents) return 0; @@ -2425,14 +2521,15 @@ int evlist__parse_event_enable_time(struct evlist *evlist, struct record_opts *o goto free_eet_times; } - eet->pollfd_pos = perf_evlist__add_pollfd(&evlist->core, eet->timerfd, NULL, POLLIN, flags); + eet->pollfd_pos = perf_evlist__add_pollfd(evlist__core(evlist), eet->timerfd, + NULL, POLLIN, flags); if (eet->pollfd_pos < 0) { err = eet->pollfd_pos; goto close_timerfd; } eet->evlist = evlist; - evlist->eet = eet; + RC_CHK_ACCESS(evlist)->eet = eet; opts->target.initial_delay = eet->times[0].start; return 0; @@ -2482,7 +2579,7 @@ int event_enable_timer__process(struct event_enable_timer *eet) if (!eet) return 0; - entries = eet->evlist->core.pollfd.entries; + entries = evlist__core(eet->evlist)->pollfd.entries; revents = entries[eet->pollfd_pos].revents; entries[eet->pollfd_pos].revents = 0; @@ -2518,7 +2615,7 @@ int event_enable_timer__process(struct event_enable_timer *eet) return 0; } -void event_enable_timer__exit(struct event_enable_timer **ep) +static void event_enable_timer__exit(struct event_enable_timer **ep) { if (!ep || !*ep) return; @@ -2622,7 +2719,7 @@ void evlist__warn_user_requested_cpus(struct evlist *evlist, const char *cpu_lis } /* Should uniquify be disabled for the evlist? */ -static bool evlist__disable_uniquify(const struct evlist *evlist) +static bool evlist__disable_uniquify(struct evlist *evlist) { struct evsel *counter; struct perf_pmu *last_pmu = NULL; |
