Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorIngo Molnar <mingo@kernel.org>
Thu, 1 Jan 2015 21:24:36 +0000 (22:24 +0100)
committerIngo Molnar <mingo@kernel.org>
Thu, 1 Jan 2015 21:24:36 +0000 (22:24 +0100)
Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

  User visible fixes:

  - Show progress bar in more places while doing histogram processing
    in the hists browser (Namhyung Kim)

  - Print backtrace symbols when segfault occurs in 'report' (Namhyung Kim)

  Infrastructure fixes:

  - Append callchains only when requested (Namhyung Kim)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
tools/perf/builtin-annotate.c
tools/perf/builtin-diff.c
tools/perf/builtin-report.c
tools/perf/builtin-top.c
tools/perf/tests/hists_cumulate.c
tools/perf/tests/hists_filter.c
tools/perf/tests/hists_output.c
tools/perf/ui/tui/setup.c
tools/perf/util/hist.c
tools/perf/util/hist.h

index e7417fe..747f861 100644 (file)
@@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
                if (nr_samples > 0) {
                        total_nr_samples += nr_samples;
                        hists__collapse_resort(hists, NULL);
-                       hists__output_resort(hists);
+                       hists__output_resort(hists, NULL);
 
                        if (symbol_conf.event_group &&
                            !perf_evsel__is_group_leader(pos))
index 1ce425d..303c1e1 100644 (file)
@@ -605,7 +605,7 @@ static void hists__process(struct hists *hists)
                hists__precompute(hists);
                hists__compute_resort(hists);
        } else {
-               hists__output_resort(hists);
+               hists__output_resort(hists, NULL);
        }
 
        hists__fprintf(hists, true, 0, 0, 0, stdout);
index 3936760..072ae8a 100644 (file)
@@ -457,6 +457,19 @@ static void report__collapse_hists(struct report *rep)
        ui_progress__finish();
 }
 
+static void report__output_resort(struct report *rep)
+{
+       struct ui_progress prog;
+       struct perf_evsel *pos;
+
+       ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
+
+       evlist__for_each(rep->session->evlist, pos)
+               hists__output_resort(evsel__hists(pos), &prog);
+
+       ui_progress__finish();
+}
+
 static int __cmd_report(struct report *rep)
 {
        int ret;
@@ -505,13 +518,20 @@ static int __cmd_report(struct report *rep)
        if (session_done())
                return 0;
 
+       /*
+        * recalculate number of entries after collapsing since it
+        * might be changed during the collapse phase.
+        */
+       rep->nr_entries = 0;
+       evlist__for_each(session->evlist, pos)
+               rep->nr_entries += evsel__hists(pos)->nr_entries;
+
        if (rep->nr_entries == 0) {
                ui__error("The %s file has no samples!\n", file->path);
                return 0;
        }
 
-       evlist__for_each(session->evlist, pos)
-               hists__output_resort(evsel__hists(pos));
+       report__output_resort(rep);
 
        return report__browse_hists(rep);
 }
index 0aa7747..961cea1 100644 (file)
@@ -285,7 +285,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
        }
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        hists__output_recalc_col_len(hists, top->print_entries - printed);
        putchar('\n');
@@ -554,7 +554,7 @@ static void perf_top__sort_new_samples(void *arg)
        }
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 }
 
 static void *display_thread_tui(void *arg)
index 614d5c4..4b8226e 100644 (file)
@@ -187,7 +187,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec
         * function since TEST_ASSERT_VAL() returns in case of failure.
         */
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        if (verbose > 2) {
                pr_info("use callchain: %d, cumulate callchain: %d\n",
index 74f257a..59e53db 100644 (file)
@@ -138,7 +138,7 @@ int test__hists_filter(void)
                struct hists *hists = evsel__hists(evsel);
 
                hists__collapse_resort(hists, NULL);
-               hists__output_resort(hists);
+               hists__output_resort(hists, NULL);
 
                if (verbose > 2) {
                        pr_info("Normal histogram\n");
index a748f2b..f554761 100644 (file)
@@ -152,7 +152,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine)
                goto out;
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        if (verbose > 2) {
                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -252,7 +252,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine)
                goto out;
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        if (verbose > 2) {
                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -306,7 +306,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine)
                goto out;
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        if (verbose > 2) {
                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -384,7 +384,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine)
                goto out;
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        if (verbose > 2) {
                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
@@ -487,7 +487,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine)
                goto out;
 
        hists__collapse_resort(hists, NULL);
-       hists__output_resort(hists);
+       hists__output_resort(hists, NULL);
 
        if (verbose > 2) {
                pr_info("[fields = %s, sort = %s]\n", field_order, sort_order);
index 2f61256..3c38f25 100644 (file)
@@ -1,5 +1,8 @@
 #include <signal.h>
 #include <stdbool.h>
+#ifdef HAVE_BACKTRACE_SUPPORT
+#include <execinfo.h>
+#endif
 
 #include "../../util/cache.h"
 #include "../../util/debug.h"
@@ -88,6 +91,25 @@ int ui__getch(int delay_secs)
        return SLkp_getkey();
 }
 
+#ifdef HAVE_BACKTRACE_SUPPORT
+static void ui__signal_backtrace(int sig)
+{
+       void *stackdump[32];
+       size_t size;
+
+       ui__exit(false);
+       psignal(sig, "perf");
+
+       printf("-------- backtrace --------\n");
+       size = backtrace(stackdump, ARRAY_SIZE(stackdump));
+       backtrace_symbols_fd(stackdump, size, STDOUT_FILENO);
+
+       exit(0);
+}
+#else
+# define ui__signal_backtrace  ui__signal
+#endif
+
 static void ui__signal(int sig)
 {
        ui__exit(false);
@@ -122,8 +144,8 @@ int ui__init(void)
        ui_browser__init();
        tui_progress__init();
 
-       signal(SIGSEGV, ui__signal);
-       signal(SIGFPE, ui__signal);
+       signal(SIGSEGV, ui__signal_backtrace);
+       signal(SIGFPE, ui__signal_backtrace);
        signal(SIGINT, ui__signal);
        signal(SIGQUIT, ui__signal);
        signal(SIGTERM, ui__signal);
index 6e88b9e..0ced178 100644 (file)
@@ -6,6 +6,7 @@
 #include "evlist.h"
 #include "evsel.h"
 #include "annotate.h"
+#include "ui/progress.h"
 #include <math.h>
 
 static bool hists__filter_entry_by_dso(struct hists *hists,
@@ -303,7 +304,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
        size_t callchain_size = 0;
        struct hist_entry *he;
 
-       if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain)
+       if (symbol_conf.use_callchain)
                callchain_size = sizeof(struct callchain_root);
 
        he = zalloc(sizeof(*he) + callchain_size);
@@ -736,7 +737,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
        iter->he = he;
        he_cache[iter->curr++] = he;
 
-       callchain_append(he->callchain, &callchain_cursor, sample->period);
+       hist_entry__append_callchain(he, sample);
 
        /*
         * We need to re-initialize the cursor since callchain_append()
@@ -809,7 +810,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
        iter->he = he;
        he_cache[iter->curr++] = he;
 
-       callchain_append(he->callchain, &cursor, sample->period);
+       if (symbol_conf.use_callchain)
+               callchain_append(he->callchain, &cursor, sample->period);
        return 0;
 }
 
@@ -987,6 +989,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
                else
                        p = &(*p)->rb_right;
        }
+       hists->nr_entries++;
 
        rb_link_node(&he->rb_node_in, parent, p);
        rb_insert_color(&he->rb_node_in, root);
@@ -1024,7 +1027,10 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
        if (!sort__need_collapse)
                return;
 
+       hists->nr_entries = 0;
+
        root = hists__get_rotate_entries_in(hists);
+
        next = rb_first(root);
 
        while (next) {
@@ -1119,7 +1125,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
        rb_insert_color(&he->rb_node, entries);
 }
 
-void hists__output_resort(struct hists *hists)
+void hists__output_resort(struct hists *hists, struct ui_progress *prog)
 {
        struct rb_root *root;
        struct rb_node *next;
@@ -1148,6 +1154,9 @@ void hists__output_resort(struct hists *hists)
 
                if (!n->filtered)
                        hists__calc_col_len(hists, n);
+
+               if (prog)
+                       ui_progress__update(prog, 1);
        }
 }
 
index d0ef9a1..46bd503 100644 (file)
@@ -121,7 +121,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
                              struct hists *hists);
 void hist_entry__free(struct hist_entry *);
 
-void hists__output_resort(struct hists *hists);
+void hists__output_resort(struct hists *hists, struct ui_progress *prog);
 void hists__collapse_resort(struct hists *hists, struct ui_progress *prog);
 
 void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);