aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArun Sharma <aruns@google.com>2010-06-04 10:27:10 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-06-05 08:35:53 -0400
commitf60f359383edf2a0ec3aa32cf8be98ad815bdf65 (patch)
treea2e544f8a1c80f2fa34018903bef1e61d71b768a
parent41a37e20178b081193b08b228030d8f562bfee62 (diff)
perf report: Implement --sort cpu
In a shared multi-core environment, users want to analyze why their program was slow. In particular, if the code ran slower only on certain CPUs due to interference from other programs or kernel threads, the user should be able to notice that. Sample usage: perf record -f -a -- sleep 3 perf report --sort cpu,comm Workload: program is running on 16 CPUs Experiencing interference from an antagonist only on 4 CPUs. Samples: 106218177676 cycles Overhead CPU Command ........ ... ............... 6.25% 2 program 6.24% 6 program 6.24% 11 program 6.24% 5 program 6.24% 9 program 6.24% 10 program 6.23% 15 program 6.23% 7 program 6.23% 3 program 6.23% 14 program 6.22% 1 program 6.20% 13 program 3.17% 12 program 3.15% 8 program 3.14% 0 program 3.13% 4 program 3.11% 4 antagonist 3.11% 0 antagonist 3.10% 8 antagonist 3.07% 12 antagonist Cc: David S. Miller <davem@davemloft.net> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <20100505181612.GA5091@sharma-home.net> Signed-off-by: Arun Sharma <aruns@google.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-record.c3
-rw-r--r--tools/perf/util/event.c1
-rw-r--r--tools/perf/util/hist.c1
-rw-r--r--tools/perf/util/sort.c27
-rw-r--r--tools/perf/util/sort.h6
-rw-r--r--tools/perf/util/symbol.h3
6 files changed, 39 insertions, 2 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f28c4bbd801f..5e5c6403a315 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -274,6 +274,9 @@ static void create_counter(int counter, int cpu)
274 if (call_graph) 274 if (call_graph)
275 attr->sample_type |= PERF_SAMPLE_CALLCHAIN; 275 attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
276 276
277 if (system_wide)
278 attr->sample_type |= PERF_SAMPLE_CPU;
279
277 if (raw_samples) { 280 if (raw_samples) {
278 attr->sample_type |= PERF_SAMPLE_TIME; 281 attr->sample_type |= PERF_SAMPLE_TIME;
279 attr->sample_type |= PERF_SAMPLE_RAW; 282 attr->sample_type |= PERF_SAMPLE_RAW;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index ed3e14ff6df0..a7460868124b 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -710,6 +710,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
710 al->map ? al->map->dso->long_name : 710 al->map ? al->map->dso->long_name :
711 al->level == 'H' ? "[hypervisor]" : "<not found>"); 711 al->level == 'H' ? "[hypervisor]" : "<not found>");
712 al->sym = NULL; 712 al->sym = NULL;
713 al->cpu = data->cpu;
713 714
714 if (al->map) { 715 if (al->map) {
715 if (symbol_conf.dso_list && 716 if (symbol_conf.dso_list &&
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 9e6baad92c4a..68d288c975de 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -70,6 +70,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
70 .map = al->map, 70 .map = al->map,
71 .sym = al->sym, 71 .sym = al->sym,
72 }, 72 },
73 .cpu = al->cpu,
73 .ip = al->addr, 74 .ip = al->addr,
74 .level = al->level, 75 .level = al->level,
75 .period = period, 76 .period = period,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 2316cb5a4116..c27b4b03fbc1 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -13,6 +13,7 @@ enum sort_type sort__first_dimension;
13unsigned int dsos__col_width; 13unsigned int dsos__col_width;
14unsigned int comms__col_width; 14unsigned int comms__col_width;
15unsigned int threads__col_width; 15unsigned int threads__col_width;
16unsigned int cpus__col_width;
16static unsigned int parent_symbol__col_width; 17static unsigned int parent_symbol__col_width;
17char * field_sep; 18char * field_sep;
18 19
@@ -28,6 +29,8 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
28 size_t size, unsigned int width); 29 size_t size, unsigned int width);
29static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, 30static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
30 size_t size, unsigned int width); 31 size_t size, unsigned int width);
32static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
33 size_t size, unsigned int width);
31 34
32struct sort_entry sort_thread = { 35struct sort_entry sort_thread = {
33 .se_header = "Command: Pid", 36 .se_header = "Command: Pid",
@@ -63,6 +66,13 @@ struct sort_entry sort_parent = {
63 .se_snprintf = hist_entry__parent_snprintf, 66 .se_snprintf = hist_entry__parent_snprintf,
64 .se_width = &parent_symbol__col_width, 67 .se_width = &parent_symbol__col_width,
65}; 68};
69
70struct sort_entry sort_cpu = {
71 .se_header = "CPU",
72 .se_cmp = sort__cpu_cmp,
73 .se_snprintf = hist_entry__cpu_snprintf,
74 .se_width = &cpus__col_width,
75};
66 76
67struct sort_dimension { 77struct sort_dimension {
68 const char *name; 78 const char *name;
@@ -76,6 +86,7 @@ static struct sort_dimension sort_dimensions[] = {
76 { .name = "dso", .entry = &sort_dso, }, 86 { .name = "dso", .entry = &sort_dso, },
77 { .name = "symbol", .entry = &sort_sym, }, 87 { .name = "symbol", .entry = &sort_sym, },
78 { .name = "parent", .entry = &sort_parent, }, 88 { .name = "parent", .entry = &sort_parent, },
89 { .name = "cpu", .entry = &sort_cpu, },
79}; 90};
80 91
81int64_t cmp_null(void *l, void *r) 92int64_t cmp_null(void *l, void *r)
@@ -242,6 +253,20 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
242 self->parent ? self->parent->name : "[other]"); 253 self->parent ? self->parent->name : "[other]");
243} 254}
244 255
256/* --sort cpu */
257
258int64_t
259sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
260{
261 return right->cpu - left->cpu;
262}
263
264static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
265 size_t size, unsigned int width)
266{
267 return repsep_snprintf(bf, size, "%-*d", width, self->cpu);
268}
269
245int sort_dimension__add(const char *tok) 270int sort_dimension__add(const char *tok)
246{ 271{
247 unsigned int i; 272 unsigned int i;
@@ -281,6 +306,8 @@ int sort_dimension__add(const char *tok)
281 sort__first_dimension = SORT_SYM; 306 sort__first_dimension = SORT_SYM;
282 else if (!strcmp(sd->name, "parent")) 307 else if (!strcmp(sd->name, "parent"))
283 sort__first_dimension = SORT_PARENT; 308 sort__first_dimension = SORT_PARENT;
309 else if (!strcmp(sd->name, "cpu"))
310 sort__first_dimension = SORT_CPU;
284 } 311 }
285 312
286 list_add_tail(&sd->entry->list, &hist_entry__sort_list); 313 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 0d61c4082f43..560c855417e4 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -39,6 +39,7 @@ extern struct sort_entry sort_parent;
39extern unsigned int dsos__col_width; 39extern unsigned int dsos__col_width;
40extern unsigned int comms__col_width; 40extern unsigned int comms__col_width;
41extern unsigned int threads__col_width; 41extern unsigned int threads__col_width;
42extern unsigned int cpus__col_width;
42extern enum sort_type sort__first_dimension; 43extern enum sort_type sort__first_dimension;
43 44
44struct hist_entry { 45struct hist_entry {
@@ -51,6 +52,7 @@ struct hist_entry {
51 struct map_symbol ms; 52 struct map_symbol ms;
52 struct thread *thread; 53 struct thread *thread;
53 u64 ip; 54 u64 ip;
55 s32 cpu;
54 u32 nr_events; 56 u32 nr_events;
55 char level; 57 char level;
56 u8 filtered; 58 u8 filtered;
@@ -68,7 +70,8 @@ enum sort_type {
68 SORT_COMM, 70 SORT_COMM,
69 SORT_DSO, 71 SORT_DSO,
70 SORT_SYM, 72 SORT_SYM,
71 SORT_PARENT 73 SORT_PARENT,
74 SORT_CPU,
72}; 75};
73 76
74/* 77/*
@@ -104,6 +107,7 @@ extern int64_t sort__comm_collapse(struct hist_entry *, struct hist_entry *);
104extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *); 107extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *);
105extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *); 108extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *);
106extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *); 109extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *);
110int64_t sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right);
107extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int); 111extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int);
108extern int sort_dimension__add(const char *); 112extern int sort_dimension__add(const char *);
109void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, 113void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 34760a2fc606..10b7ff859ce0 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -110,7 +110,8 @@ struct addr_location {
110 u64 addr; 110 u64 addr;
111 char level; 111 char level;
112 bool filtered; 112 bool filtered;
113 unsigned int cpumode; 113 u8 cpumode;
114 s32 cpu;
114}; 115};
115 116
116enum dso_kernel_type { 117enum dso_kernel_type {