diff options
Diffstat (limited to 'tools/perf/util')
27 files changed, 183 insertions, 84 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c8b01176c9e1..09762985c713 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1714,8 +1714,8 @@ static int symbol__disassemble_bpf(struct symbol *sym, if (dso->binary_type != DSO_BINARY_TYPE__BPF_PROG_INFO) return -1; - pr_debug("%s: handling sym %s addr %lx len %lx\n", __func__, - sym->name, sym->start, sym->end - sym->start); + pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__, + sym->name, sym->start, sym->end - sym->start); memset(tpath, 0, sizeof(tpath)); perf_exe(tpath, sizeof(tpath)); @@ -1740,7 +1740,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, info_linear = info_node->info_linear; sub_id = dso->bpf_prog.sub_id; - info.buffer = (void *)(info_linear->info.jited_prog_insns); + info.buffer = (void *)(uintptr_t)(info_linear->info.jited_prog_insns); info.buffer_length = info_linear->info.jited_prog_len; if (info_linear->info.nr_line_info) @@ -1776,7 +1776,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, const char *srcline; u64 addr; - addr = pc + ((u64 *)(info_linear->info.jited_ksyms))[sub_id]; + addr = pc + ((u64 *)(uintptr_t)(info_linear->info.jited_ksyms))[sub_id]; count = disassemble(pc, &info); if (prog_linfo) diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index ca0fff6272be..06f48312c5ed 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -7,7 +7,6 @@ #include "asm/bug.h" #include "debug.h" #include <unistd.h> -#include <asm/unistd.h> #include <sys/syscall.h> static unsigned long flag = PERF_FLAG_FD_CLOEXEC; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 110804936fc3..de488b43f440 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -422,11 +422,9 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm) if (!etmq->packet) goto out_free; - if (etm->synth_opts.last_branch || etm->sample_branches) { - etmq->prev_packet = zalloc(szp); - if (!etmq->prev_packet) - goto out_free; - } + etmq->prev_packet = zalloc(szp); + if (!etmq->prev_packet) + goto out_free; if (etm->synth_opts.last_branch) { size_t sz = sizeof(struct branch_stack); @@ -981,7 +979,6 @@ static int cs_etm__sample(struct cs_etm_queue *etmq) * PREV_PACKET is a branch. */ if (etm->synth_opts.last_branch && - etmq->prev_packet && etmq->prev_packet->sample_type == CS_ETM_RANGE && etmq->prev_packet->last_instr_taken_branch) cs_etm__update_last_branch_rb(etmq); @@ -1014,7 +1011,7 @@ static int cs_etm__sample(struct cs_etm_queue *etmq) etmq->period_instructions = instrs_over; } - if (etm->sample_branches && etmq->prev_packet) { + if (etm->sample_branches) { bool generate_sample = false; /* Generate sample for tracing on packet */ @@ -1071,9 +1068,6 @@ static int cs_etm__flush(struct cs_etm_queue *etmq) struct cs_etm_auxtrace *etm = etmq->etm; struct cs_etm_packet *tmp; - if (!etmq->prev_packet) - return 0; - /* Handle start tracing packet */ if (etmq->prev_packet->sample_type == CS_ETM_EMPTY) goto swap_packet; diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 26af43ad9ddd..e0311c9750ad 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -310,7 +310,7 @@ static int add_tracepoint_field_value(struct ctf_writer *cw, if (flags & TEP_FIELD_IS_DYNAMIC) { unsigned long long tmp_val; - tmp_val = tep_read_number(fmtf->event->pevent, + tmp_val = tep_read_number(fmtf->event->tep, data + offset, len); offset = tmp_val; len = offset >> 16; @@ -354,7 +354,7 @@ static int add_tracepoint_field_value(struct ctf_writer *cw, unsigned long long value_int; value_int = tep_read_number( - fmtf->event->pevent, + fmtf->event->tep, data + offset + i * len, len); if (!(flags & TEP_FIELD_IS_SIGNED)) diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index c6351b557bb0..6a3eaf7d9353 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -57,9 +57,11 @@ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, else if (prog_id > node->info_linear->info.id) n = n->rb_right; else - break; + goto out; } + node = NULL; +out: up_read(&env->bpf_progs.lock); return node; } @@ -109,9 +111,11 @@ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id) else if (btf_id > node->id) n = n->rb_right; else - break; + goto out; } + node = NULL; +out: up_read(&env->bpf_progs.lock); return node; } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 36ae7e92dab1..4e908ec1ef64 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -6,6 +6,7 @@ #include <stdio.h> #include <linux/kernel.h> #include <linux/bpf.h> +#include <linux/perf_event.h> #include "../perf.h" #include "build-id.h" diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6689378ee577..4b6783ff5813 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1009,7 +1009,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, */ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, unsigned int auxtrace_pages, - bool auxtrace_overwrite, int nr_cblocks, int affinity) + bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush) { struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; @@ -1019,7 +1019,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, * Its value is decided by evsel's write_backward. * So &mp should not be passed through const pointer. */ - struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity }; + struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity, .flush = flush }; if (!evlist->mmap) evlist->mmap = perf_evlist__alloc_mmap(evlist, false); @@ -1051,7 +1051,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) { - return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS); + return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1); } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) @@ -1868,12 +1868,12 @@ static void *perf_evlist__poll_thread(void *arg) { struct perf_evlist *evlist = arg; bool draining = false; - int i; + int i, done = 0; + + while (!done) { + bool got_data = false; - while (draining || !(evlist->thread.done)) { - if (draining) - draining = false; - else if (evlist->thread.done) + if (evlist->thread.done) draining = true; if (!draining) @@ -1894,9 +1894,13 @@ static void *perf_evlist__poll_thread(void *arg) pr_warning("cannot locate proper evsel for the side band event\n"); perf_mmap__consume(map); + got_data = true; } perf_mmap__read_done(map); } + + if (draining && !got_data) + break; } return NULL; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 6a94785b9100..c9a0f72677fd 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -177,7 +177,8 @@ unsigned long perf_event_mlock_kb_in_pages(void); int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, unsigned int auxtrace_pages, - bool auxtrace_overwrite, int nr_cblocks, int affinity); + bool auxtrace_overwrite, int nr_cblocks, + int affinity, int flush); int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); void perf_evlist__munmap(struct perf_evlist *evlist); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 66d066f18b5b..a10cf4cde920 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -580,6 +580,12 @@ static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size) return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } +static int perf_evsel__tool_name(char *bf, size_t size) +{ + int ret = scnprintf(bf, size, "duration_time"); + return ret; +} + const char *perf_evsel__name(struct perf_evsel *evsel) { char bf[128]; @@ -601,7 +607,10 @@ const char *perf_evsel__name(struct perf_evsel *evsel) break; case PERF_TYPE_SOFTWARE: - perf_evsel__sw_name(evsel, bf, sizeof(bf)); + if (evsel->tool_event) + perf_evsel__tool_name(bf, sizeof(bf)); + else + perf_evsel__sw_name(evsel, bf, sizeof(bf)); break; case PERF_TYPE_TRACEPOINT: @@ -2368,7 +2377,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, if (data->user_regs.abi) { u64 mask = evsel->attr.sample_regs_user; - sz = hweight_long(mask) * sizeof(u64); + sz = hweight64(mask) * sizeof(u64); OVERFLOW_CHECK(array, sz, max_size); data->user_regs.mask = mask; data->user_regs.regs = (u64 *)array; @@ -2424,7 +2433,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, if (data->intr_regs.abi != PERF_SAMPLE_REGS_ABI_NONE) { u64 mask = evsel->attr.sample_regs_intr; - sz = hweight_long(mask) * sizeof(u64); + sz = hweight64(mask) * sizeof(u64); OVERFLOW_CHECK(array, sz, max_size); data->intr_regs.mask = mask; data->intr_regs.regs = (u64 *)array; @@ -2552,7 +2561,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, if (type & PERF_SAMPLE_REGS_USER) { if (sample->user_regs.abi) { result += sizeof(u64); - sz = hweight_long(sample->user_regs.mask) * sizeof(u64); + sz = hweight64(sample->user_regs.mask) * sizeof(u64); result += sz; } else { result += sizeof(u64); @@ -2580,7 +2589,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, if (type & PERF_SAMPLE_REGS_INTR) { if (sample->intr_regs.abi) { result += sizeof(u64); - sz = hweight_long(sample->intr_regs.mask) * sizeof(u64); + sz = hweight64(sample->intr_regs.mask) * sizeof(u64); result += sz; } else { result += sizeof(u64); @@ -2710,7 +2719,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, if (type & PERF_SAMPLE_REGS_USER) { if (sample->user_regs.abi) { *array++ = sample->user_regs.abi; - sz = hweight_long(sample->user_regs.mask) * sizeof(u64); + sz = hweight64(sample->user_regs.mask) * sizeof(u64); memcpy(array, sample->user_regs.regs, sz); array = (void *)array + sz; } else { @@ -2746,7 +2755,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, if (type & PERF_SAMPLE_REGS_INTR) { if (sample->intr_regs.abi) { *array++ = sample->intr_regs.abi; - sz = hweight_long(sample->intr_regs.mask) * sizeof(u64); + sz = hweight64(sample->intr_regs.mask) * sizeof(u64); memcpy(array, sample->intr_regs.regs, sz); array = (void *)array + sz; } else { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 0f2c6c93d721..6d190cbf1070 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -75,6 +75,11 @@ struct perf_stat_evsel; typedef int (perf_evsel__sb_cb_t)(union perf_event *event, void *data); +enum perf_tool_event { + PERF_TOOL_NONE = 0, + PERF_TOOL_DURATION_TIME = 1, +}; + /** struct perf_evsel - event selector * * @evlist - evlist this evsel is in, if it is in one. @@ -121,6 +126,7 @@ struct perf_evsel { unsigned int sample_size; int id_pos; int is_pos; + enum perf_tool_event tool_event; bool uniquified_name; bool snapshot; bool supported; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index b9e693825873..2d2af2ac2b1e 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2606,6 +2606,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) perf_env__insert_bpf_prog_info(env, info_node); } + up_write(&env->bpf_progs.lock); return 0; out: free(info_linear); @@ -2623,7 +2624,9 @@ static int process_bpf_prog_info(struct feat_fd *ff __maybe_unused, void *data _ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused) { struct perf_env *env = &ff->ph->env; + struct btf_node *node = NULL; u32 count, i; + int err = -1; if (ff->ph->needs_swap) { pr_warning("interpreting btf from systems with endianity is not yet supported\n"); @@ -2636,31 +2639,32 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused) down_write(&env->bpf_progs.lock); for (i = 0; i < count; ++i) { - struct btf_node *node; u32 id, data_size; if (do_read_u32(ff, &id)) - return -1; + goto out; if (do_read_u32(ff, &data_size)) - return -1; + goto out; node = malloc(sizeof(struct btf_node) + data_size); if (!node) - return -1; + goto out; node->id = id; node->data_size = data_size; - if (__do_read(ff, node->data, data_size)) { - free(node); - return -1; - } + if (__do_read(ff, node->data, data_size)) + goto out; perf_env__insert_btf(env, node); + node = NULL; } + err = 0; +out: up_write(&env->bpf_progs.lock); - return 0; + free(node); + return err; } struct feature_ops { diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index e32628cd20a7..ee71efb9db62 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -261,6 +261,22 @@ bool __map__is_extra_kernel_map(const struct map *map) return kmap && kmap->name[0]; } +bool __map__is_bpf_prog(const struct map *map) +{ + const char *name; + + if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) + return true; + + /* + * If PERF_RECORD_BPF_EVENT is not included, the dso will not have + * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can + * guess the type based on name. + */ + name = map->dso->short_name; + return name && (strstr(name, "bpf_prog_") == name); +} + bool map__has_symbols(const struct map *map) { return dso__has_symbols(map->dso); @@ -910,10 +926,8 @@ static void __maps__insert_name(struct maps *maps, struct map *map) rc = strcmp(m->dso->short_name, map->dso->short_name); if (rc < 0) p = &(*p)->rb_left; - else if (rc > 0) - p = &(*p)->rb_right; else - return; + p = &(*p)->rb_right; } rb_link_node(&map->rb_node_name, parent, p); rb_insert_color(&map->rb_node_name, &maps->names); diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 0e20749f2c55..dc93787c74f0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -159,10 +159,12 @@ int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, bool __map__is_kernel(const struct map *map); bool __map__is_extra_kernel_map(const struct map *map); +bool __map__is_bpf_prog(const struct map *map); static inline bool __map__is_kmodule(const struct map *map) { - return !__map__is_kernel(map) && !__map__is_extra_kernel_map(map); + return !__map__is_kernel(map) && !__map__is_extra_kernel_map(map) && + !__map__is_bpf_prog(map); } bool map__has_symbols(const struct map *map); diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index cdc7740fc181..ef3d79b2c90b 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -440,6 +440,8 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int c perf_mmap__setup_affinity_mask(map, mp); + map->flush = mp->flush; + if (auxtrace_mmap__mmap(&map->auxtrace_mmap, &mp->auxtrace_mp, map->base, fd)) return -1; @@ -492,7 +494,7 @@ static int __perf_mmap__read_init(struct perf_mmap *md) md->start = md->overwrite ? head : old; md->end = md->overwrite ? old : head; - if (md->start == md->end) + if ((md->end - md->start) < md->flush) return -EAGAIN; size = md->end - md->start; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index e566c19b242b..b82f8c2d55c4 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -39,6 +39,7 @@ struct perf_mmap { } aio; #endif cpu_set_t affinity_mask; + u64 flush; }; /* @@ -70,7 +71,7 @@ enum bkw_mmap_state { }; struct mmap_params { - int prot, mask, nr_cblocks, affinity; + int prot, mask, nr_cblocks, affinity, flush; struct auxtrace_mmap_params auxtrace_mp; }; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 5ef4939408f2..4432bfe039fd 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -317,10 +317,12 @@ static struct perf_evsel * __add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct perf_pmu *pmu, - struct list_head *config_terms, bool auto_merge_stats) + struct list_head *config_terms, bool auto_merge_stats, + const char *cpu_list) { struct perf_evsel *evsel; - struct cpu_map *cpus = pmu ? pmu->cpus : NULL; + struct cpu_map *cpus = pmu ? pmu->cpus : + cpu_list ? cpu_map__new(cpu_list) : NULL; event_attr_init(attr); @@ -348,7 +350,25 @@ static int add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct list_head *config_terms) { - return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM; + return __add_event(list, idx, attr, name, NULL, config_terms, false, NULL) ? 0 : -ENOMEM; +} + +static int add_event_tool(struct list_head *list, int *idx, + enum perf_tool_event tool_event) +{ + struct perf_evsel *evsel; + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_DUMMY, + }; + + evsel = __add_event(list, idx, &attr, NULL, NULL, NULL, false, "0"); + if (!evsel) + return -ENOMEM; + evsel->tool_event = tool_event; + if (tool_event == PERF_TOOL_DURATION_TIME) + evsel->unit = strdup("ns"); + return 0; } static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) @@ -1233,6 +1253,13 @@ int parse_events_add_numeric(struct parse_events_state *parse_state, get_config_name(head_config), &config_terms); } +int parse_events_add_tool(struct parse_events_state *parse_state, + struct list_head *list, + enum perf_tool_event tool_event) +{ + return add_event_tool(list, &parse_state->idx, tool_event); +} + int parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, char *name, struct list_head *head_config, @@ -1267,7 +1294,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, if (!head_config) { attr.type = pmu->type; - evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats); + evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, + auto_merge_stats, NULL); if (evsel) { evsel->pmu_name = name; evsel->use_uncore_alias = use_uncore_alias; @@ -1295,7 +1323,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, evsel = __add_event(list, &parse_state->idx, &attr, get_config_name(head_config), pmu, - &config_terms, auto_merge_stats); + &config_terms, auto_merge_stats, NULL); if (evsel) { evsel->unit = info.unit; evsel->scale = info.scale; @@ -2429,6 +2457,25 @@ out_enomem: return evt_num; } +static void print_tool_event(const char *name, const char *event_glob, + bool name_only) +{ + if (event_glob && !strglobmatch(name, event_glob)) + return; + if (name_only) + printf("%s ", name); + else + printf(" %-50s [%s]\n", name, "Tool event"); + +} + +void print_tool_events(const char *event_glob, bool name_only) +{ + print_tool_event("duration_time", event_glob, name_only); + if (pager_in_use()) + printf("\n"); +} + void print_symbol_events(const char *event_glob, unsigned type, struct event_symbol *syms, unsigned max, bool name_only) @@ -2512,6 +2559,7 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag, print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, event_symbols_sw, PERF_COUNT_SW_MAX, name_only); + print_tool_events(event_glob, name_only); print_hwcache_events(event_glob, name_only); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 5ed035cbcbb7..a052cd6ac63e 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -160,6 +160,10 @@ int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct list_head *head_config); +enum perf_tool_event; +int parse_events_add_tool(struct parse_events_state *parse_state, + struct list_head *list, + enum perf_tool_event tool_event); int parse_events_add_cache(struct list_head *list, int *idx, char *type, char *op_result1, char *op_result2, struct parse_events_error *error, @@ -200,6 +204,7 @@ extern struct event_symbol event_symbols_sw[]; void print_symbol_events(const char *event_glob, unsigned type, struct event_symbol *syms, unsigned max, bool name_only); +void print_tool_events(const char *event_glob, bool name_only); void print_tracepoint_events(const char *subsys_glob, const char *event_glob, bool name_only); int print_hwcache_events(const char *event_glob, bool name_only); diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 7805c71aaae2..c54bfe88626c 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -15,6 +15,7 @@ #include "../perf.h" #include "parse-events.h" #include "parse-events-bison.h" +#include "evsel.h" char *parse_events_get_text(yyscan_t yyscanner); YYSTYPE *parse_events_get_lval(yyscan_t yyscanner); @@ -154,6 +155,14 @@ static int sym(yyscan_t scanner, int type, int config) return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW; } +static int tool(yyscan_t scanner, enum perf_tool_event event) +{ + YYSTYPE *yylval = parse_events_get_lval(scanner); + + yylval->num = event; + return PE_VALUE_SYM_TOOL; +} + static int term(yyscan_t scanner, int type) { YYSTYPE *yylval = parse_events_get_lval(scanner); @@ -322,7 +331,7 @@ cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COU alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } -duration_time { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } +duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); } bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); } /* diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 44819bdb037d..6ad8d4914969 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -14,6 +14,7 @@ #include <linux/types.h> #include "util.h" #include "pmu.h" +#include "evsel.h" #include "debug.h" #include "parse-events.h" #include "parse-events-bison.h" @@ -45,6 +46,7 @@ static void inc_group_count(struct list_head *list, %token PE_START_EVENTS PE_START_TERMS %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM +%token PE_VALUE_SYM_TOOL %token PE_EVENT_NAME %token PE_NAME %token PE_BPF_OBJECT PE_BPF_SOURCE @@ -58,6 +60,7 @@ static void inc_group_count(struct list_head *list, %type <num> PE_VALUE %type <num> PE_VALUE_SYM_HW %type <num> PE_VALUE_SYM_SW +%type <num> PE_VALUE_SYM_TOOL %type <num> PE_RAW %type <num> PE_TERM %type <str> PE_NAME @@ -321,6 +324,15 @@ value_sym sep_slash_slash_dc ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); $$ = list; } +| +PE_VALUE_SYM_TOOL sep_slash_slash_dc +{ + struct list_head *list; + + ALLOC_LIST(list); + ABORT_ON(parse_events_add_tool(_parse_state, list, $1)); + $$ = list; +} event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index dda0ac978b1e..6aa7e2352e16 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -342,7 +342,7 @@ static bool is_tracepoint(struct pyrf_event *pevent) static PyObject* tracepoint_field(struct pyrf_event *pe, struct tep_format_field *field) { - struct tep_handle *pevent = field->event->pevent; + struct tep_handle *pevent = field->event->tep; void *data = pe->sample.raw_data; PyObject *ret = NULL; unsigned long long val; diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 5f06378a482b..61aa7f3df915 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -372,7 +372,7 @@ static void perl_process_tracepoint(struct perf_sample *sample, ns = nsecs - s * NSEC_PER_SEC; scripting_context->event_data = data; - scripting_context->pevent = evsel->tp_format->pevent; + scripting_context->pevent = evsel->tp_format->tep; ENTER; SAVETMPS; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 09604c6508f0..22f52b669871 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -837,7 +837,7 @@ static void python_process_tracepoint(struct perf_sample *sample, ns = nsecs - s * NSEC_PER_SEC; scripting_context->event_data = data; - scripting_context->pevent = evsel->tp_format->pevent; + scripting_context->pevent = evsel->tp_format->tep; context = _PyCapsule_New(scripting_context, NULL, NULL); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b17f1c9bc965..bad5f87ae001 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1928,12 +1928,14 @@ more: size = event->header.size; + skip = -EINVAL; + if (size < sizeof(struct perf_event_header) || (skip = rd->process(session, event, file_pos)) < 0) { - pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", + pr_err("%#" PRIx64 " [%#x]: failed to process type: %d [%s]\n", file_offset + head, event->header.size, - event->header.type); - err = -EINVAL; + event->header.type, strerror(-skip)); + err = skip; goto out; } diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 6d043c78f3c2..3324f23c7efc 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -18,11 +18,6 @@ #define CNTR_NOT_SUPPORTED "<not supported>" #define CNTR_NOT_COUNTED "<not counted>" -static bool is_duration_time(struct perf_evsel *evsel) -{ - return !strcmp(evsel->name, "duration_time"); -} - static void print_running(struct perf_stat_config *config, u64 run, u64 ena) { @@ -628,9 +623,6 @@ static void print_aggr(struct perf_stat_config *config, ad.id = id = config->aggr_map->map[s]; first = true; evlist__for_each_entry(evlist, counter) { - if (is_duration_time(counter)) - continue; - ad.val = ad.ena = ad.run = 0; ad.nr = 0; if (!collect_data(config, counter, aggr_cb, &ad)) @@ -848,8 +840,6 @@ static void print_no_aggr_metric(struct perf_stat_config *config, if (prefix) fputs(prefix, config->output); evlist__for_each_entry(evlist, counter) { - if (is_duration_time(counter)) - continue; if (first) { aggr_printout(config, counter, cpu, 0); first = false; @@ -906,8 +896,6 @@ static void print_metric_headers(struct perf_stat_config *config, /* Print metrics headers only */ evlist__for_each_entry(evlist, counter) { - if (is_duration_time(counter)) - continue; os.evsel = counter; out.ctx = &os; out.print_metric = print_metric_header; @@ -1136,15 +1124,11 @@ perf_evlist__print_counters(struct perf_evlist *evlist, break; case AGGR_THREAD: evlist__for_each_entry(evlist, counter) { - if (is_duration_time(counter)) - continue; print_aggr_thread(config, _target, counter, prefix); } break; case AGGR_GLOBAL: evlist__for_each_entry(evlist, counter) { - if (is_duration_time(counter)) - continue; print_counter_aggr(config, counter, prefix); } if (metric_only) @@ -1155,8 +1139,6 @@ perf_evlist__print_counters(struct perf_evlist *evlist, print_no_aggr_metric(config, evlist, prefix); else { evlist__for_each_entry(evlist, counter) { - if (is_duration_time(counter)) - continue; print_counter(config, counter, prefix); } } diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index ad74be1f0e42..863955e4094e 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -111,7 +111,7 @@ raw_field_value(struct tep_event *event, const char *name, void *data) unsigned long long read_size(struct tep_event *event, void *ptr, int size) { - return tep_read_number(event->pevent, ptr, size); + return tep_read_number(event->tep, ptr, size); } void event_format__fprintf(struct tep_event *event, diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index efe2f58cff4e..48d53d8e3e16 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -442,7 +442,7 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe) tep_set_flag(pevent, TEP_NSEC_OUTPUT); tep_set_file_bigendian(pevent, file_bigendian); - tep_set_host_bigendian(pevent, host_bigendian); + tep_set_local_bigendian(pevent, host_bigendian); if (do_read(buf, 1) < 0) goto out; diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index cbe0dd758e3a..01b9d89bf5bf 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c @@ -40,7 +40,7 @@ int trace_event__init(struct trace_event *t) static int trace_event__init2(void) { - int be = tep_host_bigendian(); + int be = tep_is_bigendian(); struct tep_handle *pevent; if (trace_event__init(&tevent)) @@ -49,7 +49,7 @@ static int trace_event__init2(void) pevent = tevent.pevent; tep_set_flag(pevent, TEP_NSEC_OUTPUT); tep_set_file_bigendian(pevent, be); - tep_set_host_bigendian(pevent, be); + tep_set_local_bigendian(pevent, be); tevent_initialized = true; return 0; } |