perf annotate: Fix sizeof_sym_hist overflow issue
[firefly-linux-kernel-4.4.55.git] / tools / perf / builtin-report.c
index 62b285e32aa551093d9869798827a5be2cf3e1e5..b5623639f67dd06f2829e59a56725a7f7be30db2 100644 (file)
@@ -62,6 +62,7 @@ struct report {
        float                   min_percent;
        u64                     nr_entries;
        u64                     queue_size;
+       int                     socket_filter;
        DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 };
 
@@ -162,14 +163,21 @@ static int process_sample_event(struct perf_tool *tool,
        if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
                goto out_put;
 
-       if (sort__mode == SORT_MODE__BRANCH)
+       if (sort__mode == SORT_MODE__BRANCH) {
+               /*
+                * A non-synthesized event might not have a branch stack if
+                * branch stacks have been synthesized (using itrace options).
+                */
+               if (!sample->branch_stack)
+                       goto out_put;
                iter.ops = &hist_iter_branch;
-       else if (rep->mem_mode)
+       } else if (rep->mem_mode) {
                iter.ops = &hist_iter_mem;
-       else if (symbol_conf.cumulate_callchain)
+       } else if (symbol_conf.cumulate_callchain) {
                iter.ops = &hist_iter_cumulative;
-       else
+       } else {
                iter.ops = &hist_iter_normal;
+       }
 
        if (al.map != NULL)
                al.map->dso->hit = 1;
@@ -213,6 +221,15 @@ static int report__setup_sample_type(struct report *rep)
        u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
        bool is_pipe = perf_data_file__is_pipe(session->file);
 
+       if (session->itrace_synth_opts->callchain ||
+           (!is_pipe &&
+            perf_header__has_feat(&session->header, HEADER_AUXTRACE) &&
+            !session->itrace_synth_opts->set))
+               sample_type |= PERF_SAMPLE_CALLCHAIN;
+
+       if (session->itrace_synth_opts->last_branch)
+               sample_type |= PERF_SAMPLE_BRANCH_STACK;
+
        if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
                if (sort__has_parent) {
                        ui__error("Selected --sort parent, but no "
@@ -286,6 +303,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
        struct perf_evsel *evsel = hists_to_evsel(hists);
        char buf[512];
        size_t size = sizeof(buf);
+       int socked_id = hists->socket_filter;
 
        if (symbol_conf.filter_relative) {
                nr_samples = hists->stats.nr_non_filtered_samples;
@@ -326,6 +344,10 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
                ret += fprintf(fp, "\n# Sort order   : %s", sort_order ? : default_mem_sort_order);
        } else
                ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
+
+       if (socked_id > -1)
+               ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
+
        return ret + fprintf(fp, "\n#\n");
 }
 
@@ -365,7 +387,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
 
 static void report__warn_kptr_restrict(const struct report *rep)
 {
-       struct map *kernel_map = rep->session->machines.host.vmlinux_maps[MAP__FUNCTION];
+       struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
        struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
 
        if (kernel_map == NULL ||
@@ -450,6 +472,8 @@ static void report__collapse_hists(struct report *rep)
                if (pos->idx == 0)
                        hists->symbol_filter_str = rep->symbol_filter_str;
 
+               hists->socket_filter = rep->socket_filter;
+
                hists__collapse_resort(hists, &prog);
 
                /* Non-group events are considered as leader */
@@ -635,6 +659,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                },
                .max_stack               = PERF_MAX_STACK_DEPTH,
                .pretty_printing_style   = "normal",
+               .socket_filter           = -1,
        };
        const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
@@ -747,6 +772,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                        "Show full source file name path for source lines"),
        OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
                    "Show callgraph from reference event"),
+       OPT_INTEGER(0, "socket-filter", &report.socket_filter,
+                   "only show processor socket that match with this filter"),
        OPT_END()
        };
        struct perf_data_file file = {
@@ -782,6 +809,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
        if (report.inverted_callchain)
                callchain_param.order = ORDER_CALLER;
 
+       if (itrace_synth_opts.callchain &&
+           (int)itrace_synth_opts.callchain_sz > report.max_stack)
+               report.max_stack = itrace_synth_opts.callchain_sz;
+
        if (!input_name || !strlen(input_name)) {
                if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
                        input_name = "-";
@@ -809,6 +840,9 @@ repeat:
        has_br_stack = perf_header__has_feat(&session->header,
                                             HEADER_BRANCH_STACK);
 
+       if (itrace_synth_opts.last_branch)
+               has_br_stack = true;
+
        /*
         * Branch mode is a tristate:
         * -1 means default, so decide based on the file having branch data.