aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-10-22 17:23:22 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-23 01:55:16 -0400
commitaf0a6fa46388e1e0c2d1a672aad84f8f6ef0b20b (patch)
tree961592b767ecda1e2ac85b997f64bc1665f0b249 /tools/perf
parent4e3b799d7dbb2a12ca8dca8d3594d32095772973 (diff)
perf tools: Fix missing top level callchain
While recursively printing the branches of each callchains, we forget to display the root. It is never printed. Say we have: symbol f1 f2 | -------- f3 | f4 | ---------f5 f6 Actually we never see that, instead it displays: symbol | --------- f3 | f4 | --------- f5 f6 However f1 is always the same than "symbol" and if we are sorting by symbols first then "symbol", f1 and f2 will be well aligned like in the above example, so displaying f1 looks redundant here. But if we are sorting by something else first (dso, comm, etc...), displaying f1 doesn't look redundant but rather necessary because the symbol is not well aligned anymore with its callchain: comm dso symbol f1 f2 | --------- [...] And we want the callchain to be obvious. So we fix the bug by printing the root branch, but we also filter its first entry if we are sorting by symbols first. Reported-by: Anton Blanchard <anton@samba.org> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1256246604-17156-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-report.c40
-rw-r--r--tools/perf/util/sort.c10
-rw-r--r--tools/perf/util/sort.h1
3 files changed, 41 insertions, 10 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index bee207ce589a..3d8c52220f1f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -122,8 +122,8 @@ static void init_rem_hits(void)
122} 122}
123 123
124static size_t 124static size_t
125callchain__fprintf_graph(FILE *fp, struct callchain_node *self, 125__callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
126 u64 total_samples, int depth, int depth_mask) 126 u64 total_samples, int depth, int depth_mask)
127{ 127{
128 struct rb_node *node, *next; 128 struct rb_node *node, *next;
129 struct callchain_node *child; 129 struct callchain_node *child;
@@ -174,9 +174,9 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
174 new_total, 174 new_total,
175 cumul); 175 cumul);
176 } 176 }
177 ret += callchain__fprintf_graph(fp, child, new_total, 177 ret += __callchain__fprintf_graph(fp, child, new_total,
178 depth + 1, 178 depth + 1,
179 new_depth_mask | (1 << depth)); 179 new_depth_mask | (1 << depth));
180 node = next; 180 node = next;
181 } 181 }
182 182
@@ -197,6 +197,33 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
197} 197}
198 198
199static size_t 199static size_t
200callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
201 u64 total_samples)
202{
203 struct callchain_list *chain;
204 int i = 0;
205 int ret = 0;
206
207 list_for_each_entry(chain, &self->val, list) {
208 if (chain->ip >= PERF_CONTEXT_MAX)
209 continue;
210
211 if (!i++ && sort_by_sym_first)
212 continue;
213
214 if (chain->sym)
215 ret += fprintf(fp, " %s\n", chain->sym->name);
216 else
217 ret += fprintf(fp, " %p\n",
218 (void *)(long)chain->ip);
219 }
220
221 ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1);
222
223 return ret;
224}
225
226static size_t
200callchain__fprintf_flat(FILE *fp, struct callchain_node *self, 227callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
201 u64 total_samples) 228 u64 total_samples)
202{ 229{
@@ -244,8 +271,7 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
244 break; 271 break;
245 case CHAIN_GRAPH_ABS: /* Falldown */ 272 case CHAIN_GRAPH_ABS: /* Falldown */
246 case CHAIN_GRAPH_REL: 273 case CHAIN_GRAPH_REL:
247 ret += callchain__fprintf_graph(fp, chain, 274 ret += callchain__fprintf_graph(fp, chain, total_samples);
248 total_samples, 1, 1);
249 case CHAIN_NONE: 275 case CHAIN_NONE:
250 default: 276 default:
251 break; 277 break;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 40c9acd41cad..60ced707bd6b 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -5,8 +5,9 @@ char default_parent_pattern[] = "^sys_|^do_page_fault";
5char *parent_pattern = default_parent_pattern; 5char *parent_pattern = default_parent_pattern;
6char default_sort_order[] = "comm,dso,symbol"; 6char default_sort_order[] = "comm,dso,symbol";
7char *sort_order = default_sort_order; 7char *sort_order = default_sort_order;
8int sort__need_collapse = 0; 8int sort__need_collapse = 0;
9int sort__has_parent = 0; 9int sort__has_parent = 0;
10int sort_by_sym_first;
10 11
11unsigned int dsos__col_width; 12unsigned int dsos__col_width;
12unsigned int comms__col_width; 13unsigned int comms__col_width;
@@ -265,6 +266,10 @@ int sort_dimension__add(const char *tok)
265 sort__has_parent = 1; 266 sort__has_parent = 1;
266 } 267 }
267 268
269 if (list_empty(&hist_entry__sort_list) &&
270 !strcmp(sd->name, "symbol"))
271 sort_by_sym_first = true;
272
268 list_add_tail(&sd->entry->list, &hist_entry__sort_list); 273 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
269 sd->taken = 1; 274 sd->taken = 1;
270 275
@@ -273,4 +278,3 @@ int sort_dimension__add(const char *tok)
273 278
274 return -ESRCH; 279 return -ESRCH;
275} 280}
276
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 13806d782af6..24c2b709f0d3 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 int sort_by_sym_first;
42 43
43struct hist_entry { 44struct hist_entry {
44 struct rb_node rb_node; 45 struct rb_node rb_node;