aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2013-12-18 16:16:18 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-12-19 09:34:37 -0500
commit6dbc8ca97b7737fa9254083df29d06c556b0653c (patch)
tree78322c4bf93c50847921e9dd29fc27e96b56c3f4
parent44e8303944cd45788abd48f14d4c683331ed6cf7 (diff)
perf report: Introduce helpers for processing callchains
Continuing to try to remove the code duplication introduced with mem and branch hist entry code, this time providing prologue and epilogues to deal with callchains when processing samples. Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-js3pour59yk2aibqzb1tpumh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-report.c72
1 files changed, 32 insertions, 40 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 9a20c9efb84b..8424053b399a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -75,6 +75,24 @@ static int perf_report_config(const char *var, const char *value, void *cb)
75 return perf_default_config(var, value, cb); 75 return perf_default_config(var, value, cb);
76} 76}
77 77
78static int report__resolve_callchain(struct perf_report *rep, struct symbol **parent,
79 struct perf_evsel *evsel, struct addr_location *al,
80 struct perf_sample *sample, struct machine *machine)
81{
82 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
83 return machine__resolve_callchain(machine, evsel, al->thread, sample,
84 parent, al, rep->max_stack);
85 }
86 return 0;
87}
88
89static int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
90{
91 if (!symbol_conf.use_callchain)
92 return 0;
93 return callchain_append(he->callchain, &callchain_cursor, sample->period);
94}
95
78static int perf_report__add_mem_hist_entry(struct perf_tool *tool, 96static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
79 struct addr_location *al, 97 struct addr_location *al,
80 struct perf_sample *sample, 98 struct perf_sample *sample,
@@ -85,19 +103,13 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
85 struct perf_report *rep = container_of(tool, struct perf_report, tool); 103 struct perf_report *rep = container_of(tool, struct perf_report, tool);
86 struct symbol *parent = NULL; 104 struct symbol *parent = NULL;
87 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 105 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
88 int err = 0;
89 struct hist_entry *he; 106 struct hist_entry *he;
90 struct mem_info *mi, *mx; 107 struct mem_info *mi, *mx;
91 uint64_t cost; 108 uint64_t cost;
109 int err = report__resolve_callchain(rep, &parent, evsel, al, sample, machine);
92 110
93 if ((sort__has_parent || symbol_conf.use_callchain) && 111 if (err)
94 sample->callchain) { 112 return err;
95 err = machine__resolve_callchain(machine, evsel, al->thread,
96 sample, &parent, al,
97 rep->max_stack);
98 if (err)
99 return err;
100 }
101 113
102 mi = machine__resolve_mem(machine, al->thread, sample, cpumode); 114 mi = machine__resolve_mem(machine, al->thread, sample, cpumode);
103 if (!mi) 115 if (!mi)
@@ -133,13 +145,7 @@ static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
133 145
134 evsel->hists.stats.total_period += cost; 146 evsel->hists.stats.total_period += cost;
135 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 147 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
136 err = 0; 148 err = hist_entry__append_callchain(he, sample);
137
138 if (symbol_conf.use_callchain) {
139 err = callchain_append(he->callchain,
140 &callchain_cursor,
141 sample->period);
142 }
143out: 149out:
144 return err; 150 return err;
145} 151}
@@ -152,19 +158,13 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
152{ 158{
153 struct perf_report *rep = container_of(tool, struct perf_report, tool); 159 struct perf_report *rep = container_of(tool, struct perf_report, tool);
154 struct symbol *parent = NULL; 160 struct symbol *parent = NULL;
155 int err = 0;
156 unsigned i; 161 unsigned i;
157 struct hist_entry *he; 162 struct hist_entry *he;
158 struct branch_info *bi, *bx; 163 struct branch_info *bi, *bx;
164 int err = report__resolve_callchain(rep, &parent, evsel, al, sample, machine);
159 165
160 if ((sort__has_parent || symbol_conf.use_callchain) 166 if (err)
161 && sample->callchain) { 167 return err;
162 err = machine__resolve_callchain(machine, evsel, al->thread,
163 sample, &parent, al,
164 rep->max_stack);
165 if (err)
166 return err;
167 }
168 168
169 bi = machine__resolve_bstack(machine, al->thread, 169 bi = machine__resolve_bstack(machine, al->thread,
170 sample->branch_stack); 170 sample->branch_stack);
@@ -216,16 +216,11 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool,
216{ 216{
217 struct perf_report *rep = container_of(tool, struct perf_report, tool); 217 struct perf_report *rep = container_of(tool, struct perf_report, tool);
218 struct symbol *parent = NULL; 218 struct symbol *parent = NULL;
219 int err = 0;
220 struct hist_entry *he; 219 struct hist_entry *he;
220 int err = report__resolve_callchain(rep, &parent, evsel, al, sample, machine);
221 221
222 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { 222 if (err)
223 err = machine__resolve_callchain(machine, evsel, al->thread, 223 return err;
224 sample, &parent, al,
225 rep->max_stack);
226 if (err)
227 return err;
228 }
229 224
230 he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL, 225 he = __hists__add_entry(&evsel->hists, al, parent, NULL, NULL,
231 sample->period, sample->weight, 226 sample->period, sample->weight,
@@ -233,17 +228,14 @@ static int perf_evsel__add_hist_entry(struct perf_tool *tool,
233 if (he == NULL) 228 if (he == NULL)
234 return -ENOMEM; 229 return -ENOMEM;
235 230
236 if (symbol_conf.use_callchain) { 231 err = hist_entry__append_callchain(he, sample);
237 err = callchain_append(he->callchain, 232 if (err)
238 &callchain_cursor, 233 goto out;
239 sample->period);
240 if (err)
241 return err;
242 }
243 234
244 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); 235 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
245 evsel->hists.stats.total_period += sample->period; 236 evsel->hists.stats.total_period += sample->period;
246 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 237 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
238out:
247 return err; 239 return err;
248} 240}
249 241