diff options
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 109 |
1 files changed, 65 insertions, 44 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 50d2fb222d48..9c27bb30b708 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -7,6 +7,7 @@ * a histogram of results, along various sorting keys. */ #include "builtin.h" +#include "perf.h" #include "util/color.h" #include <linux/list.h> @@ -221,7 +222,8 @@ static int process_branch_callback(struct evsel *evsel, if (a.map != NULL) dso__set_hit(map__dso(a.map)); - hist__account_cycles(sample->branch_stack, al, sample, false, NULL); + hist__account_cycles(sample->branch_stack, al, sample, false, + NULL, evsel); ret = hist_entry_iter__add(&iter, &a, PERF_MAX_STACK_DEPTH, ann); out: @@ -279,7 +281,7 @@ static int evsel__add_sample(struct evsel *evsel, struct perf_sample *sample, return ret; } -static int process_sample_event(struct perf_tool *tool, +static int process_sample_event(const struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct evsel *evsel, @@ -311,7 +313,8 @@ out_put: return ret; } -static int process_feature_event(struct perf_session *session, +static int process_feature_event(const struct perf_tool *tool __maybe_unused, + struct perf_session *session, union perf_event *event) { if (event->feat.feat_id < HEADER_LAST_FEATURE) @@ -319,14 +322,14 @@ static int process_feature_event(struct perf_session *session, return 0; } -static int hist_entry__tty_annotate(struct hist_entry *he, +static int hist_entry__stdio_annotate(struct hist_entry *he, struct evsel *evsel, struct perf_annotate *ann) { - if (!ann->use_stdio2) - return symbol__tty_annotate(&he->ms, evsel); + if (ann->use_stdio2) + return hist_entry__tty_annotate2(he, evsel); - return symbol__tty_annotate2(&he->ms, evsel); + return hist_entry__tty_annotate(he, evsel); } static void print_annotate_data_stat(struct annotated_data_stat *s) @@ -396,10 +399,10 @@ static void print_annotate_item_stat(struct list_head *head, const char *title) printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n\n", total, total_good, 100.0 * total_good / (total ?: 1), total_bad, 100.0 * total_bad / (total ?: 1)); - printf(" %-10s: %5s %5s\n", "Name", "Good", "Bad"); + printf(" %-20s: %5s %5s\n", "Name/opcode", "Good", "Bad"); printf("-----------------------------------------------------------\n"); list_for_each_entry(istat, head, list) - printf(" %-10s: %5d %5d\n", istat->name, istat->good, istat->bad); + printf(" %-20s: %5d %5d\n", istat->name, istat->good, istat->bad); printf("\n"); } @@ -517,7 +520,7 @@ find_next: /* skip missing symbols */ nd = rb_next(nd); } else if (use_browser == 1) { - key = hist_entry__tui_annotate(he, evsel, NULL); + key = hist_entry__tui_annotate(he, evsel, NULL, NO_ADDR); switch (key) { case -1: @@ -539,7 +542,7 @@ find_next: if (next != NULL) nd = next; } else { - hist_entry__tty_annotate(he, evsel, ann); + hist_entry__stdio_annotate(he, evsel, ann); nd = rb_next(nd); } } @@ -560,7 +563,7 @@ static int __cmd_annotate(struct perf_annotate *ann) } if (!annotate_opts.objdump_path) { - ret = perf_env__lookup_objdump(&session->header.env, + ret = perf_env__lookup_objdump(perf_session__env(session), &annotate_opts.objdump_path); if (ret) goto out; @@ -571,8 +574,8 @@ static int __cmd_annotate(struct perf_annotate *ann) goto out; if (dump_trace) { - perf_session__fprintf_nr_events(session, stdout, false); - evlist__fprintf_nr_events(session->evlist, stdout, false); + perf_session__fprintf_nr_events(session, stdout); + evlist__fprintf_nr_events(session->evlist, stdout); goto out; } @@ -632,13 +635,23 @@ static int __cmd_annotate(struct perf_annotate *ann) evlist__for_each_entry(session->evlist, pos) { struct hists *hists = evsel__hists(pos); u32 nr_samples = hists->stats.nr_samples; + struct ui_progress prog; + struct evsel *evsel; - if (nr_samples == 0) + if (!symbol_conf.event_group || !evsel__is_group_leader(pos)) continue; - if (!symbol_conf.event_group || !evsel__is_group_leader(pos)) + for_each_group_member(evsel, pos) + nr_samples += evsel__hists(evsel)->stats.nr_samples; + + if (nr_samples == 0) continue; + ui_progress__init(&prog, nr_samples, + "Sorting group events for output..."); + evsel__output_resort(pos, &prog); + ui_progress__finish(); + hists__find_annotations(hists, pos, ann); } @@ -686,28 +699,7 @@ static const char * const annotate_usage[] = { int cmd_annotate(int argc, const char **argv) { - struct perf_annotate annotate = { - .tool = { - .sample = process_sample_event, - .mmap = perf_event__process_mmap, - .mmap2 = perf_event__process_mmap2, - .comm = perf_event__process_comm, - .exit = perf_event__process_exit, - .fork = perf_event__process_fork, - .namespaces = perf_event__process_namespaces, - .attr = perf_event__process_attr, - .build_id = perf_event__process_build_id, -#ifdef HAVE_LIBTRACEEVENT - .tracing_data = perf_event__process_tracing_data, -#endif - .id_index = perf_event__process_id_index, - .auxtrace_info = perf_event__process_auxtrace_info, - .auxtrace = perf_event__process_auxtrace, - .feature = process_feature_event, - .ordered_events = true, - .ordering_requires_timestamps = true, - }, - }; + struct perf_annotate annotate = {}; struct perf_data data = { .mode = PERF_DATA_MODE_READ, }; @@ -795,6 +787,10 @@ int cmd_annotate(int argc, const char **argv) "Show stats for the data type annotation"), OPT_BOOLEAN(0, "insn-stat", &annotate.insn_stat, "Show instruction stats for the data type annotation"), + OPT_BOOLEAN(0, "skip-empty", &symbol_conf.skip_empty, + "Do not display empty (or dummy) events in the output"), + OPT_BOOLEAN(0, "code-with-type", &annotate_opts.code_with_type, + "Show data type info in code annotation (memory instructions only)"), OPT_END() }; int ret; @@ -848,7 +844,7 @@ int cmd_annotate(int argc, const char **argv) } #endif -#ifndef HAVE_DWARF_GETLOCATIONS_SUPPORT +#ifndef HAVE_LIBDW_SUPPORT if (annotate.data_type) { pr_err("Error: Data type profiling is disabled due to missing DWARF support\n"); return -ENOTSUP; @@ -864,6 +860,25 @@ int cmd_annotate(int argc, const char **argv) data.path = input_name; + perf_tool__init(&annotate.tool, /*ordered_events=*/true); + annotate.tool.sample = process_sample_event; + annotate.tool.mmap = perf_event__process_mmap; + annotate.tool.mmap2 = perf_event__process_mmap2; + annotate.tool.comm = perf_event__process_comm; + annotate.tool.exit = perf_event__process_exit; + annotate.tool.fork = perf_event__process_fork; + annotate.tool.namespaces = perf_event__process_namespaces; + annotate.tool.attr = perf_event__process_attr; + annotate.tool.build_id = perf_event__process_build_id; +#ifdef HAVE_LIBTRACEEVENT + annotate.tool.tracing_data = perf_event__process_tracing_data; +#endif + annotate.tool.id_index = perf_event__process_id_index; + annotate.tool.auxtrace_info = perf_event__process_auxtrace_info; + annotate.tool.auxtrace = perf_event__process_auxtrace; + annotate.tool.feature = process_feature_event; + annotate.tool.ordering_requires_timestamps = true; + annotate.session = perf_session__new(&data, &annotate.tool); if (IS_ERR(annotate.session)) return PTR_ERR(annotate.session); @@ -882,7 +897,7 @@ int cmd_annotate(int argc, const char **argv) symbol_conf.try_vmlinux_path = true; - ret = symbol__init(&annotate.session->header.env); + ret = symbol__init(perf_session__env(annotate.session)); if (ret < 0) goto out_delete; @@ -901,6 +916,8 @@ int cmd_annotate(int argc, const char **argv) annotate_opts.annotate_src = false; symbol_conf.annotate_data_member = true; symbol_conf.annotate_data_sample = true; + } else if (annotate_opts.code_with_type) { + symbol_conf.annotate_data_member = true; } setup_browser(true); @@ -916,13 +933,17 @@ int cmd_annotate(int argc, const char **argv) sort_order = "dso,symbol"; /* - * Set SORT_MODE__BRANCH so that annotate display IPC/Cycle - * if branch info is in perf data in TUI mode. + * Set SORT_MODE__BRANCH so that annotate displays IPC/Cycle and + * branch counters, if the corresponding branch info is available + * in the perf data in the TUI mode. */ - if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack) + if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack) { sort__mode = SORT_MODE__BRANCH; + if (annotate.session->evlist->nr_br_cntr > 0) + annotate_opts.show_br_cntr = true; + } - if (setup_sorting(NULL) < 0) + if (setup_sorting(/*evlist=*/NULL, perf_session__env(annotate.session)) < 0) usage_with_options(annotate_usage, options); ret = __cmd_annotate(&annotate); |
