perf tools: Allow sorting by symbol size
authorCharles Baylis <charles.baylis@linaro.org>
Fri, 24 Feb 2017 13:32:56 +0000 (13:32 +0000)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 3 Mar 2017 22:07:16 +0000 (19:07 -0300)
Add new sort key 'symbol_size' to allow user to sort by symbol size, or
(more usefully) display the symbol size using --fields=...,symbol_size.

Committer note:

Testing it together with the recently added -q, to remove the headers,
and using the '+' sign with -s, to add the symbol_size sort order to
the default, which is '-s/--sort comm,dso,symbol':

  # perf report -q -s +symbol_size | head -10
  10.39%  swapper       [kernel.vmlinux] [k] intel_idle               270
   3.45%  swapper       [kernel.vmlinux] [k] update_blocked_averages 1546
   2.61%  swapper       [kernel.vmlinux] [k] update_load_avg         1292
   2.36%  swapper       [kernel.vmlinux] [k] update_cfs_shares        240
   1.83%  swapper       [kernel.vmlinux] [k] __hrtimer_run_queues     606
   1.74%  swapper       [kernel.vmlinux] [k] update_cfs_rq_load_avg. 1187
   1.66%  swapper       [kernel.vmlinux] [k] apic_timer_interrupt     152
   1.60%  CPU 0/KVM     [kvm]            [k] kvm_set_msr_common      3046
   1.60%  gnome-shell   libglib-2.0.so.0 [.] g_slist_find              37
   1.46%  gnome-termina libglib-2.0.so.0 [.] g_hash_table_lookup      370
  #

Signed-off-by: Charles Baylis <charles.baylis@linaro.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1487943176-13840-1-git-send-email-charles.baylis@linaro.org
[ Use symbol__size(), remove needless %lld + (long long) casting ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-report.txt
tools/perf/util/hist.h
tools/perf/util/sort.c
tools/perf/util/sort.h

index c04cc0647c16e6d8bbb458d655ab8ddbec3262c9..33f91906f5dc0ec783f934b71affbfea99049129 100644 (file)
@@ -80,6 +80,7 @@ OPTIONS
        - pid: command and tid of the task
        - dso: name of library or module executed at the time of sample
        - symbol: name of function executed at the time of sample
+       - symbol_size: size of function executed at the time of sample
        - parent: name of function matched to the parent regex filter. Unmatched
        entries are displayed as "[other]".
        - cpu: cpu number the task ran at the time of sample
index 28c216e3d5b72557825a8918ab2aa6d6369c40f8..2e839bf40bdd1b2c091556d018ad602219443407 100644 (file)
@@ -57,6 +57,7 @@ enum hist_column {
        HISTC_SRCLINE_FROM,
        HISTC_SRCLINE_TO,
        HISTC_TRACE,
+       HISTC_SYM_SIZE,
        HISTC_NR_COLS, /* Last entry */
 };
 
index 0ff622288d243c4edad03a904b6da3a52cf4da50..f8f16c0e20b68a9724ccb31b02d02a4cb9bd2e0e 100644 (file)
@@ -1396,6 +1396,46 @@ struct sort_entry sort_transaction = {
        .se_width_idx   = HISTC_TRANSACTION,
 };
 
+/* --sort symbol_size */
+
+static int64_t _sort__sym_size_cmp(struct symbol *sym_l, struct symbol *sym_r)
+{
+       int64_t size_l = sym_l != NULL ? symbol__size(sym_l) : 0;
+       int64_t size_r = sym_r != NULL ? symbol__size(sym_r) : 0;
+
+       return size_l < size_r ? -1 :
+               size_l == size_r ? 0 : 1;
+}
+
+static int64_t
+sort__sym_size_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       return _sort__sym_size_cmp(right->ms.sym, left->ms.sym);
+}
+
+static int _hist_entry__sym_size_snprintf(struct symbol *sym, char *bf,
+                                         size_t bf_size, unsigned int width)
+{
+       if (sym)
+               return repsep_snprintf(bf, bf_size, "%*d", width, symbol__size(sym));
+
+       return repsep_snprintf(bf, bf_size, "%*s", width, "unknown");
+}
+
+static int hist_entry__sym_size_snprintf(struct hist_entry *he, char *bf,
+                                        size_t size, unsigned int width)
+{
+       return _hist_entry__sym_size_snprintf(he->ms.sym, bf, size, width);
+}
+
+struct sort_entry sort_sym_size = {
+       .se_header      = "Symbol size",
+       .se_cmp         = sort__sym_size_cmp,
+       .se_snprintf    = hist_entry__sym_size_snprintf,
+       .se_width_idx   = HISTC_SYM_SIZE,
+};
+
+
 struct sort_dimension {
        const char              *name;
        struct sort_entry       *entry;
@@ -1418,6 +1458,7 @@ static struct sort_dimension common_sort_dimensions[] = {
        DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
        DIM(SORT_TRANSACTION, "transaction", sort_transaction),
        DIM(SORT_TRACE, "trace", sort_trace),
+       DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size),
 };
 
 #undef DIM
index 796c847e2f000d6722ed2cb35321e7f3b8b0489e..f583325a374363b92a26edb5e988817955a35e65 100644 (file)
@@ -211,6 +211,7 @@ enum sort_type {
        SORT_GLOBAL_WEIGHT,
        SORT_TRANSACTION,
        SORT_TRACE,
+       SORT_SYM_SIZE,
 
        /* branch stack specific sort keys */
        __SORT_BRANCH_STACK,