]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - tools/perf/builtin-report.c
perf report: Sort by sampled cycles percent per block for tui
[linux.git] / tools / perf / builtin-report.c
index aae0e57c60fbb582b7c48c71bc6c939d798de2f7..1e81985b7d569182796f0377315b9f19c1f6f9fe 100644 (file)
@@ -51,6 +51,7 @@
 #include "util/util.h" // perf_tip()
 #include "ui/ui.h"
 #include "ui/progress.h"
+#include "util/block-info.h"
 
 #include <dlfcn.h>
 #include <errno.h>
@@ -96,10 +97,13 @@ struct report {
        float                   min_percent;
        u64                     nr_entries;
        u64                     queue_size;
+       u64                     total_cycles;
        int                     socket_filter;
        DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
        struct branch_type_stat brtype_stat;
        bool                    symbol_ipc;
+       bool                    total_cycles_mode;
+       struct block_report     *block_reports;
 };
 
 static int report__config(const char *var, const char *value, void *cb)
@@ -290,9 +294,10 @@ static int process_sample_event(struct perf_tool *tool,
        if (al.map != NULL)
                al.map->dso->hit = 1;
 
-       if (ui__has_annotation() || rep->symbol_ipc) {
+       if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) {
                hist__account_cycles(sample->branch_stack, &al, sample,
-                                    rep->nonany_branch_mode);
+                                    rep->nonany_branch_mode,
+                                    &rep->total_cycles);
        }
 
        ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
@@ -399,6 +404,13 @@ static int report__setup_sample_type(struct report *rep)
                                PERF_SAMPLE_BRANCH_ANY))
                rep->nonany_branch_mode = true;
 
+#ifndef HAVE_LIBUNWIND_SUPPORT
+       if (dwarf_callchain_users) {
+               ui__warning("Please install libunwind development packages "
+                           "during the perf build.\n");
+       }
+#endif
+
        return 0;
 }
 
@@ -473,11 +485,28 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
        return ret + fprintf(fp, "\n#\n");
 }
 
+static int perf_evlist__tui_block_hists_browse(struct evlist *evlist,
+                                              struct report *rep)
+{
+       struct evsel *pos;
+       int i = 0, ret;
+
+       evlist__for_each_entry(evlist, pos) {
+               ret = report__browse_block_hists(&rep->block_reports[i++].hist,
+                                                rep->min_percent, pos);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static int perf_evlist__tty_browse_hists(struct evlist *evlist,
                                         struct report *rep,
                                         const char *help)
 {
        struct evsel *pos;
+       int i = 0;
 
        if (!quiet) {
                fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
@@ -493,6 +522,13 @@ static int perf_evlist__tty_browse_hists(struct evlist *evlist,
                        continue;
 
                hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
+
+               if (rep->total_cycles_mode) {
+                       report__browse_block_hists(&rep->block_reports[i++].hist,
+                                                  rep->min_percent, pos);
+                       continue;
+               }
+
                hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
                               !(symbol_conf.use_callchain ||
                                 symbol_conf.show_branchflag_count));
@@ -575,6 +611,11 @@ static int report__browse_hists(struct report *rep)
 
        switch (use_browser) {
        case 1:
+               if (rep->total_cycles_mode) {
+                       ret = perf_evlist__tui_block_hists_browse(evlist, rep);
+                       break;
+               }
+
                ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
                                                    rep->min_percent,
                                                    &session->header.env,
@@ -720,11 +761,9 @@ static struct task *tasks_list(struct task *task, struct machine *machine)
 static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
 {
        size_t printed = 0;
-       struct rb_node *nd;
-
-       for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
-               struct map *map = rb_entry(nd, struct map, rb_node);
+       struct map *map;
 
+       maps__for_each_entry(maps, map) {
                printed += fprintf(fp, "%*s  %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
                                   indent, "", map->start, map->end,
                                   map->prot & PROT_READ ? 'r' : '-',
@@ -920,6 +959,13 @@ static int __cmd_report(struct report *rep)
 
        report__output_resort(rep);
 
+       if (rep->total_cycles_mode) {
+               rep->block_reports = block_info__create_report(session->evlist,
+                                                              rep->total_cycles);
+               if (!rep->block_reports)
+                       return -1;
+       }
+
        return report__browse_hists(rep);
 }
 
@@ -1204,6 +1250,8 @@ int cmd_report(int argc, const char **argv)
                     "Set time quantum for time sort key (default 100ms)",
                     parse_time_quantum),
        OPTS_EVSWITCH(&report.evswitch),
+       OPT_BOOLEAN(0, "total-cycles", &report.total_cycles_mode,
+                   "Sort all blocks by 'Sampled Cycles%'"),
        OPT_END()
        };
        struct perf_data data = {
@@ -1366,6 +1414,13 @@ int cmd_report(int argc, const char **argv)
                goto error;
        }
 
+       if (report.total_cycles_mode) {
+               if (sort__mode != SORT_MODE__BRANCH)
+                       report.total_cycles_mode = false;
+               else
+                       sort_order = "sym";
+       }
+
        if (strcmp(input_name, "-") != 0)
                setup_browser(true);
        else
@@ -1416,7 +1471,8 @@ int cmd_report(int argc, const char **argv)
         * so don't allocate extra space that won't be used in the stdio
         * implementation.
         */
-       if (ui__has_annotation() || report.symbol_ipc) {
+       if (ui__has_annotation() || report.symbol_ipc ||
+           report.total_cycles_mode) {
                ret = symbol__annotation_init();
                if (ret < 0)
                        goto error;
@@ -1477,6 +1533,10 @@ int cmd_report(int argc, const char **argv)
                itrace_synth_opts__clear_time_range(&itrace_synth_opts);
                zfree(&report.ptime_range);
        }
+
+       if (report.block_reports)
+               zfree(&report.block_reports);
+
        zstd_fini(&(session->zstd_data));
        perf_session__delete(session);
        return ret;