aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2019-03-11 10:44:54 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-03-11 15:32:31 -0400
commit3723908d05834c76fd5cc9ecd17b0851342e1df4 (patch)
treee84112f997919f484e30b8c28ae6af0987a01f54
parente87e548126cdc66fd4f194b38b59f351b6e5d3e8 (diff)
perf report: Support time sort key
Add a time sort key to perf report to display samples for different time quantums separately. This allows easier analysis of workloads that change over time, and also will allow looking at the context of samples. % perf record ... % perf report --sort time,overhead,symbol --time-quantum 1ms --stdio ... 0.67% 277061.87300 [.] _dl_start 0.50% 277061.87300 [.] f1 0.50% 277061.87300 [.] f2 0.33% 277061.87300 [.] main 0.29% 277061.87300 [.] _dl_lookup_symbol_x 0.29% 277061.87300 [.] dl_main 0.29% 277061.87300 [.] do_lookup_x 0.17% 277061.87300 [.] _dl_debug_initialize 0.17% 277061.87300 [.] _dl_init_paths 0.08% 277061.87300 [.] check_match 0.04% 277061.87300 [.] _dl_count_modids 1.33% 277061.87400 [.] f1 1.33% 277061.87400 [.] f2 1.33% 277061.87400 [.] main 1.17% 277061.87500 [.] main 1.08% 277061.87500 [.] f1 1.08% 277061.87500 [.] f2 1.00% 277061.87600 [.] main 0.83% 277061.87600 [.] f1 0.83% 277061.87600 [.] f2 1.00% 277061.87700 [.] main Committer notes: Rename 'time' argument to hist_time() to htime to overcome this in older distros: cc1: warnings being treated as errors util/hist.c: In function 'hist_time': util/hist.c:251: error: declaration of 'time' shadows a global declaration /usr/include/time.h:186: error: shadowed declaration is here Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20190311144502.15423-4-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/Documentation/perf-report.txt2
-rw-r--r--tools/perf/util/hist.c11
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/sort.c39
-rw-r--r--tools/perf/util/sort.h2
5 files changed, 55 insertions, 0 deletions
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 9ec1702bccdd..546d87221ad8 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -105,6 +105,8 @@ OPTIONS
105 guest machine 105 guest machine
106 - sample: Number of sample 106 - sample: Number of sample
107 - period: Raw number of event count of sample 107 - period: Raw number of event count of sample
108 - time: Separate the samples by time stamp with the resolution specified by
109 --time-quantum (default 100ms). Specify with overhead and before it.
108 110
109 By default, comm, dso and symbol keys are used. 111 By default, comm, dso and symbol keys are used.
110 (i.e. --sort comm,dso,symbol) 112 (i.e. --sort comm,dso,symbol)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f9eb95bf3938..34c0f00c68d1 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -19,6 +19,7 @@
19#include <math.h> 19#include <math.h>
20#include <inttypes.h> 20#include <inttypes.h>
21#include <sys/param.h> 21#include <sys/param.h>
22#include <linux/time64.h>
22 23
23static bool hists__filter_entry_by_dso(struct hists *hists, 24static bool hists__filter_entry_by_dso(struct hists *hists,
24 struct hist_entry *he); 25 struct hist_entry *he);
@@ -192,6 +193,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
192 hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3); 193 hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
193 hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12); 194 hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
194 hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12); 195 hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
196 hists__new_col_len(hists, HISTC_TIME, 12);
195 197
196 if (h->srcline) { 198 if (h->srcline) {
197 len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header)); 199 len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header));
@@ -246,6 +248,14 @@ static void he_stat__add_cpumode_period(struct he_stat *he_stat,
246 } 248 }
247} 249}
248 250
251static long hist_time(unsigned long htime)
252{
253 unsigned long time_quantum = symbol_conf.time_quantum;
254 if (time_quantum)
255 return (htime / time_quantum) * time_quantum;
256 return htime;
257}
258
249static void he_stat__add_period(struct he_stat *he_stat, u64 period, 259static void he_stat__add_period(struct he_stat *he_stat, u64 period,
250 u64 weight) 260 u64 weight)
251{ 261{
@@ -635,6 +645,7 @@ __hists__add_entry(struct hists *hists,
635 .raw_data = sample->raw_data, 645 .raw_data = sample->raw_data,
636 .raw_size = sample->raw_size, 646 .raw_size = sample->raw_size,
637 .ops = ops, 647 .ops = ops,
648 .time = hist_time(sample->time),
638 }, *he = hists__findnew_entry(hists, &entry, al, sample_self); 649 }, *he = hists__findnew_entry(hists, &entry, al, sample_self);
639 650
640 if (!hists->has_callchains && he && he->callchain_size != 0) 651 if (!hists->has_callchains && he && he->callchain_size != 0)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 4af27fbab24f..6279eca56409 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -31,6 +31,7 @@ enum hist_filter {
31 31
32enum hist_column { 32enum hist_column {
33 HISTC_SYMBOL, 33 HISTC_SYMBOL,
34 HISTC_TIME,
34 HISTC_DSO, 35 HISTC_DSO,
35 HISTC_THREAD, 36 HISTC_THREAD,
36 HISTC_COMM, 37 HISTC_COMM,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index d2299e912e59..bdd30cab51cb 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -3,6 +3,7 @@
3#include <inttypes.h> 3#include <inttypes.h>
4#include <regex.h> 4#include <regex.h>
5#include <linux/mman.h> 5#include <linux/mman.h>
6#include <linux/time64.h>
6#include "sort.h" 7#include "sort.h"
7#include "hist.h" 8#include "hist.h"
8#include "comm.h" 9#include "comm.h"
@@ -15,6 +16,7 @@
15#include <traceevent/event-parse.h> 16#include <traceevent/event-parse.h>
16#include "mem-events.h" 17#include "mem-events.h"
17#include "annotate.h" 18#include "annotate.h"
19#include "time-utils.h"
18#include <linux/kernel.h> 20#include <linux/kernel.h>
19 21
20regex_t parent_regex; 22regex_t parent_regex;
@@ -654,6 +656,42 @@ struct sort_entry sort_socket = {
654 .se_width_idx = HISTC_SOCKET, 656 .se_width_idx = HISTC_SOCKET,
655}; 657};
656 658
659/* --sort time */
660
661static int64_t
662sort__time_cmp(struct hist_entry *left, struct hist_entry *right)
663{
664 return right->time - left->time;
665}
666
667static int hist_entry__time_snprintf(struct hist_entry *he, char *bf,
668 size_t size, unsigned int width)
669{
670 unsigned long secs;
671 unsigned long long nsecs;
672 char he_time[32];
673
674 nsecs = he->time;
675 secs = nsecs / NSEC_PER_SEC;
676 nsecs -= secs * NSEC_PER_SEC;
677
678 if (symbol_conf.nanosecs)
679 snprintf(he_time, sizeof he_time, "%5lu.%09llu: ",
680 secs, nsecs);
681 else
682 timestamp__scnprintf_usec(he->time, he_time,
683 sizeof(he_time));
684
685 return repsep_snprintf(bf, size, "%-.*s", width, he_time);
686}
687
688struct sort_entry sort_time = {
689 .se_header = "Time",
690 .se_cmp = sort__time_cmp,
691 .se_snprintf = hist_entry__time_snprintf,
692 .se_width_idx = HISTC_TIME,
693};
694
657/* --sort trace */ 695/* --sort trace */
658 696
659static char *get_trace_output(struct hist_entry *he) 697static char *get_trace_output(struct hist_entry *he)
@@ -1634,6 +1672,7 @@ static struct sort_dimension common_sort_dimensions[] = {
1634 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size), 1672 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size),
1635 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id), 1673 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
1636 DIM(SORT_SYM_IPC_NULL, "ipc_null", sort_sym_ipc_null), 1674 DIM(SORT_SYM_IPC_NULL, "ipc_null", sort_sym_ipc_null),
1675 DIM(SORT_TIME, "time", sort_time),
1637}; 1676};
1638 1677
1639#undef DIM 1678#undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 2fbee0b1011c..19dceb7f6145 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -135,6 +135,7 @@ struct hist_entry {
135 char *srcfile; 135 char *srcfile;
136 struct symbol *parent; 136 struct symbol *parent;
137 struct branch_info *branch_info; 137 struct branch_info *branch_info;
138 long time;
138 struct hists *hists; 139 struct hists *hists;
139 struct mem_info *mem_info; 140 struct mem_info *mem_info;
140 void *raw_data; 141 void *raw_data;
@@ -231,6 +232,7 @@ enum sort_type {
231 SORT_DSO_SIZE, 232 SORT_DSO_SIZE,
232 SORT_CGROUP_ID, 233 SORT_CGROUP_ID,
233 SORT_SYM_IPC_NULL, 234 SORT_SYM_IPC_NULL,
235 SORT_TIME,
234 236
235 /* branch stack specific sort keys */ 237 /* branch stack specific sort keys */
236 __SORT_BRANCH_STACK, 238 __SORT_BRANCH_STACK,