These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / tools / perf / builtin-top.c
index 6a4d5d4..7e2e72e 100644 (file)
@@ -40,6 +40,7 @@
 #include "util/xyarray.h"
 #include "util/sort.h"
 #include "util/intlist.h"
+#include "util/parse-branch-options.h"
 #include "arch/common.h"
 
 #include "util/debug.h"
@@ -235,10 +236,13 @@ static void perf_top__show_details(struct perf_top *top)
 
        more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel,
                                       0, top->sym_pcnt_filter, top->print_entries, 4);
-       if (top->zero)
-               symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
-       else
-               symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx);
+
+       if (top->evlist->enabled) {
+               if (top->zero)
+                       symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
+               else
+                       symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx);
+       }
        if (more != 0)
                printf("%d lines not displayed, maybe increase display entries [e]\n", more);
 out_unlock:
@@ -276,11 +280,13 @@ static void perf_top__print_sym_table(struct perf_top *top)
                return;
        }
 
-       if (top->zero) {
-               hists__delete_entries(hists);
-       } else {
-               hists__decay_entries(hists, top->hide_user_symbols,
-                                    top->hide_kernel_symbols);
+       if (top->evlist->enabled) {
+               if (top->zero) {
+                       hists__delete_entries(hists);
+               } else {
+                       hists__decay_entries(hists, top->hide_user_symbols,
+                                            top->hide_kernel_symbols);
+               }
        }
 
        hists__collapse_resort(hists, NULL);
@@ -545,11 +551,13 @@ static void perf_top__sort_new_samples(void *arg)
 
        hists = evsel__hists(t->sym_evsel);
 
-       if (t->zero) {
-               hists__delete_entries(hists);
-       } else {
-               hists__decay_entries(hists, t->hide_user_symbols,
-                                    t->hide_kernel_symbols);
+       if (t->evlist->enabled) {
+               if (t->zero) {
+                       hists__delete_entries(hists);
+               } else {
+                       hists__decay_entries(hists, t->hide_user_symbols,
+                                            t->hide_kernel_symbols);
+               }
        }
 
        hists__collapse_resort(hists, NULL);
@@ -579,7 +587,8 @@ static void *display_thread_tui(void *arg)
                hists->uid_filter_str = top->record_opts.target.uid_str;
        }
 
-       perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
+       perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
+                                     top->min_percent,
                                      &top->session->header.env);
 
        done = 1;
@@ -593,8 +602,8 @@ static void display_sig(int sig __maybe_unused)
 
 static void display_setup_sig(void)
 {
-       signal(SIGSEGV, display_sig);
-       signal(SIGFPE,  display_sig);
+       signal(SIGSEGV, sighandler_dump_stack);
+       signal(SIGFPE, sighandler_dump_stack);
        signal(SIGINT,  display_sig);
        signal(SIGQUIT, display_sig);
        signal(SIGTERM, display_sig);
@@ -646,7 +655,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)
 {
        const char *name = sym->name;
 
-       if (!map->dso->kernel)
+       if (!__map__is_kernel(map))
                return 0;
        /*
         * ppc64 uses function descriptors and appends a '.' to the
@@ -687,6 +696,8 @@ static int hist_iter__top_callback(struct hist_entry_iter *iter,
                perf_top__record_precise_ip(top, he, evsel->idx, ip);
        }
 
+       hist__account_cycles(iter->sample->branch_stack, al, iter->sample,
+                    !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY));
        return 0;
 }
 
@@ -775,7 +786,9 @@ static void perf_event__process_sample(struct perf_tool *tool,
        if (al.sym == NULL || !al.sym->ignore) {
                struct hists *hists = evsel__hists(evsel);
                struct hist_entry_iter iter = {
-                       .add_entry_cb = hist_iter__top_callback,
+                       .evsel          = evsel,
+                       .sample         = sample,
+                       .add_entry_cb   = hist_iter__top_callback,
                };
 
                if (symbol_conf.cumulate_callchain)
@@ -785,15 +798,14 @@ static void perf_event__process_sample(struct perf_tool *tool,
 
                pthread_mutex_lock(&hists->lock);
 
-               err = hist_entry_iter__add(&iter, &al, evsel, sample,
-                                          top->max_stack, top);
+               err = hist_entry_iter__add(&iter, &al, top->max_stack, top);
                if (err < 0)
                        pr_err("Problem incrementing symbol period, skipping event\n");
 
                pthread_mutex_unlock(&hists->lock);
        }
 
-       return;
+       addr_location__put(&al);
 }
 
 static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
@@ -845,9 +857,12 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
                         * TODO: we don't process guest user from host side
                         * except simple counting.
                         */
-                       /* Fall thru */
-               default:
                        goto next_event;
+               default:
+                       if (event->header.type == PERF_RECORD_SAMPLE)
+                               goto next_event;
+                       machine = &session->machines.host;
+                       break;
                }
 
 
@@ -940,7 +955,7 @@ static int __cmd_top(struct perf_top *top)
        machines__set_symbol_filter(&top->session->machines, symbol_filter);
 
        if (!objdump_path) {
-               ret = perf_session_env__lookup_objdump(&top->session->header.env);
+               ret = perf_env__lookup_objdump(&top->session->header.env);
                if (ret)
                        goto out_delete;
        }
@@ -949,8 +964,18 @@ static int __cmd_top(struct perf_top *top)
        if (ret)
                goto out_delete;
 
+       if (perf_session__register_idle_thread(top->session) == NULL)
+               goto out_delete;
+
        machine__synthesize_threads(&top->session->machines.host, &opts->target,
-                                   top->evlist->threads, false);
+                                   top->evlist->threads, false, opts->proc_map_timeout);
+
+       if (sort__has_socket) {
+               ret = perf_env__read_cpu_topology_map(&perf_env);
+               if (ret < 0)
+                       goto out_err_cpu_topo;
+       }
+
        ret = perf_top__start_counters(top);
        if (ret)
                goto out_delete;
@@ -1008,6 +1033,14 @@ out_delete:
        top->session = NULL;
 
        return ret;
+
+out_err_cpu_topo: {
+       char errbuf[BUFSIZ];
+       const char *err = strerror_r(-ret, errbuf, sizeof(errbuf));
+
+       ui__error("Could not read the CPU topology map: %s\n", err);
+       goto out_delete;
+}
 }
 
 static int
@@ -1020,8 +1053,22 @@ callchain_opt(const struct option *opt, const char *arg, int unset)
 static int
 parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 {
-       symbol_conf.use_callchain = true;
-       return record_parse_callchain_opt(opt, arg, unset);
+       struct record_opts *record = (struct record_opts *)opt->value;
+
+       record->callgraph_set = true;
+       callchain_param.enabled = !unset;
+       callchain_param.record_mode = CALLCHAIN_FP;
+
+       /*
+        * --no-call-graph
+        */
+       if (unset) {
+               symbol_conf.use_callchain = false;
+               callchain_param.record_mode = CALLCHAIN_NONE;
+               return 0;
+       }
+
+       return parse_callchain_top_opt(arg);
 }
 
 static int perf_top_config(const char *var, const char *value, void *cb)
@@ -1046,6 +1093,9 @@ parse_percent_limit(const struct option *opt, const char *arg,
        return 0;
 }
 
+const char top_callchain_help[] = CALLCHAIN_RECORD_HELP CALLCHAIN_REPORT_HELP
+       "\n\t\t\t\tDefault: fp,graph,0.5,caller,function";
+
 int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
 {
        char errbuf[BUFSIZ];
@@ -1060,6 +1110,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                        .target         = {
                                .uses_mmap   = true,
                        },
+                       .proc_map_timeout    = 500,
                },
                .max_stack           = PERF_MAX_STACK_DEPTH,
                .sym_pcnt_filter     = 5,
@@ -1120,11 +1171,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
                    "Show a column with the number of samples"),
        OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
-                          NULL, "enables call-graph recording",
+                          NULL, "enables call-graph recording and display",
                           &callchain_opt),
        OPT_CALLBACK(0, "call-graph", &top.record_opts,
-                    "mode[,dump_size]", record_callchain_help,
-                    &parse_callchain_opt),
+                    "record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]",
+                    top_callchain_help, &parse_callchain_opt),
        OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
                    "Accumulate callchains of children and show total overhead as well"),
        OPT_INTEGER(0, "max-stack", &top.max_stack,
@@ -1159,6 +1210,14 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
                   "width[,width...]",
                   "don't try to adjust column width, use these fixed values"),
+       OPT_UINTEGER(0, "proc-map-timeout", &opts->proc_map_timeout,
+                       "per thread proc mmap processing timeout in ms"),
+       OPT_CALLBACK_NOOPT('b', "branch-any", &opts->branch_stack,
+                    "branch any", "sample any taken branches",
+                    parse_branch_stack),
+       OPT_CALLBACK('j', "branch-filter", &opts->branch_stack,
+                    "branch filter mask", "branch stack filter modes",
+                    parse_branch_stack),
        OPT_END()
        };
        const char * const top_usage[] = {
@@ -1246,6 +1305,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                perf_hpp__cancel_cumulate();
        }
 
+       if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
+               callchain_param.order = ORDER_CALLER;
+
        symbol_conf.priv_size = sizeof(struct annotation);
 
        symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);