dm-crypt: use __bio_add_page to add single page to clone bio
[linux-block.git] / tools / perf / builtin-report.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
bf9e1876
IM
2/*
3 * builtin-report.c
4 *
5 * Builtin report command: Analyze the perf.data input file,
6 * look up and read DSOs and symbol information and display
7 * a histogram of results, along various sorting keys.
8 */
16f762a2 9#include "builtin.h"
53cb8bc2 10
41840d21 11#include "util/config.h"
bf9e1876 12
78f7defe 13#include "util/annotate.h"
8fc0321f 14#include "util/color.h"
4a3cec84 15#include "util/dso.h"
5da50258 16#include <linux/list.h>
43cbcd8a 17#include <linux/rbtree.h>
930f8b34 18#include <linux/err.h>
7f7c536f 19#include <linux/zalloc.h>
1101f69a 20#include "util/map.h"
a2928c42 21#include "util/symbol.h"
d3300a3c
ACM
22#include "util/map_symbol.h"
23#include "util/mem-events.h"
24#include "util/branch.h"
f55c5552 25#include "util/callchain.h"
8d513270 26#include "util/values.h"
8fa66bdc 27
53cb8bc2 28#include "perf.h"
8f28827a 29#include "util/debug.h"
e248de33
ACM
30#include "util/evlist.h"
31#include "util/evsel.h"
ef4b1a53 32#include "util/evswitch.h"
7c6a1c65 33#include "util/header.h"
94c744b6 34#include "util/session.h"
97b9d866 35#include "util/srcline.h"
45694aa7 36#include "util/tool.h"
53cb8bc2 37
4b6ab94e 38#include <subcmd/parse-options.h>
34b7b0f9 39#include <subcmd/exec-cmd.h>
53cb8bc2
IM
40#include "util/parse-events.h"
41
6baa0a5a 42#include "util/thread.h"
dd68ada2 43#include "util/sort.h"
3d1d07ec 44#include "util/hist.h"
f5fc1412 45#include "util/data.h"
68e94f4e 46#include "arch/common.h"
46690a80 47#include "util/time-utils.h"
520a2ebc 48#include "util/auxtrace.h"
58db1d6e 49#include "util/units.h"
fb71c86c 50#include "util/util.h" // perf_tip()
8520a98d 51#include "ui/ui.h"
171f7474 52#include "ui/progress.h"
6f7164fa 53#include "util/block-info.h"
520a2ebc 54
fc67297b 55#include <dlfcn.h>
a43783ae 56#include <errno.h>
fd20e811 57#include <inttypes.h>
1eae20c1 58#include <regex.h>
3052ba56 59#include <linux/ctype.h>
9607ad3a 60#include <signal.h>
5d67be97 61#include <linux/bitmap.h>
8520a98d 62#include <linux/string.h>
531d2410 63#include <linux/stringify.h>
2a1292cb 64#include <linux/time64.h>
7a8ef4c4
ACM
65#include <sys/types.h>
66#include <sys/stat.h>
67#include <unistd.h>
6439d7d1 68#include <linux/mman.h>
5d67be97 69
378ef0f5
IR
70#ifdef HAVE_LIBTRACEEVENT
71#include <traceevent/event-parse.h>
72#endif
73
28b21393 74struct report {
45694aa7 75 struct perf_tool tool;
d20deb64 76 struct perf_session *session;
ef4b1a53 77 struct evswitch evswitch;
3402ae0a
IR
78#ifdef HAVE_SLANG_SUPPORT
79 bool use_tui;
80#endif
557cc18e 81#ifdef HAVE_GTK2_SUPPORT
3402ae0a 82 bool use_gtk;
557cc18e 83#endif
3402ae0a 84 bool use_stdio;
fa372aae
ACM
85 bool show_full_info;
86 bool show_threads;
87 bool inverted_callchain;
f4f7e28d 88 bool mem_mode;
a4a4d0a7 89 bool stats_mode;
930f8b34 90 bool tasks_mode;
6439d7d1 91 bool mmaps_mode;
5cfe2c82
JO
92 bool header;
93 bool header_only;
98df858e 94 bool nonany_branch_mode;
57b5de46 95 bool group_set;
b1d1429b 96 bool stitch_lbr;
2e989f82 97 bool disable_order;
2775de0b 98 bool skip_empty;
91e95617 99 int max_stack;
fa372aae 100 struct perf_read_values show_threads_values;
1eddd9e4 101 struct annotation_options annotation_opts;
fa372aae 102 const char *pretty_printing_style;
fa372aae 103 const char *cpu_list;
b14ffaca 104 const char *symbol_filter_str;
46690a80 105 const char *time_str;
0a3cc3ae
JY
106 struct perf_time_interval *ptime_range;
107 int range_size;
5b969bc7 108 int range_num;
064f1981 109 float min_percent;
58c311da 110 u64 nr_entries;
94786b67 111 u64 queue_size;
6f7164fa 112 u64 total_cycles;
21394d94 113 int socket_filter;
fa372aae 114 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
2d78b189 115 struct branch_type_stat brtype_stat;
ec6ae74f 116 bool symbol_ipc;
6f7164fa
JY
117 bool total_cycles_mode;
118 struct block_report *block_reports;
cca0cc76 119 int nr_block_reports;
d20deb64 120};
5d67be97 121
28b21393 122static int report__config(const char *var, const char *value, void *cb)
00c7e1f1 123{
94786b67
JO
124 struct report *rep = cb;
125
00c7e1f1
NK
126 if (!strcmp(var, "report.group")) {
127 symbol_conf.event_group = perf_config_bool(var, value);
128 return 0;
129 }
eec574e6 130 if (!strcmp(var, "report.percent-limit")) {
2665b452
NK
131 double pcnt = strtof(value, NULL);
132
133 rep->min_percent = pcnt;
134 callchain_param.min_percent = pcnt;
eec574e6
NK
135 return 0;
136 }
8d8e645c
NK
137 if (!strcmp(var, "report.children")) {
138 symbol_conf.cumulate_callchain = perf_config_bool(var, value);
139 return 0;
140 }
25ce4bb8
ACM
141 if (!strcmp(var, "report.queue-size"))
142 return perf_config_u64(&rep->queue_size, var, value);
143
fa1f4565
ACM
144 if (!strcmp(var, "report.sort_order")) {
145 default_sort_order = strdup(value);
8f08c363
IR
146 if (!default_sort_order) {
147 pr_err("Not enough memory for report.sort_order\n");
148 return -1;
149 }
fa1f4565
ACM
150 return 0;
151 }
00c7e1f1 152
8f08cf33
NK
153 if (!strcmp(var, "report.skip-empty")) {
154 rep->skip_empty = perf_config_bool(var, value);
155 return 0;
156 }
157
8f08c363 158 pr_debug("%s variable unknown, ignoring...", var);
b8cbb349 159 return 0;
00c7e1f1
NK
160}
161
9d3c02d7
NK
162static int hist_iter__report_callback(struct hist_entry_iter *iter,
163 struct addr_location *al, bool single,
164 void *arg)
165{
166 int err = 0;
167 struct report *rep = arg;
168 struct hist_entry *he = iter->he;
32dcd021 169 struct evsel *evsel = iter->evsel;
bab89f6a 170 struct perf_sample *sample = iter->sample;
9d3c02d7
NK
171 struct mem_info *mi;
172 struct branch_info *bi;
173
ec6ae74f 174 if (!ui__has_annotation() && !rep->symbol_ipc)
9d3c02d7
NK
175 return 0;
176
177 if (sort__mode == SORT_MODE__BRANCH) {
178 bi = he->branch_info;
e345f3bd 179 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
9d3c02d7
NK
180 if (err)
181 goto out;
182
e345f3bd 183 err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
9d3c02d7
NK
184
185 } else if (rep->mem_mode) {
186 mi = he->mem_info;
e345f3bd 187 err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
9d3c02d7
NK
188 if (err)
189 goto out;
190
e345f3bd 191 err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
9d3c02d7
NK
192
193 } else if (symbol_conf.cumulate_callchain) {
194 if (single)
e345f3bd 195 err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
9d3c02d7 196 } else {
e345f3bd 197 err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
9d3c02d7
NK
198 }
199
200out:
201 return err;
f4f7e28d
SE
202}
203
2d78b189
JY
204static int hist_iter__branch_callback(struct hist_entry_iter *iter,
205 struct addr_location *al __maybe_unused,
206 bool single __maybe_unused,
207 void *arg)
208{
209 struct hist_entry *he = iter->he;
210 struct report *rep = arg;
c3b10649 211 struct branch_info *bi = he->branch_info;
40c39e30 212 struct perf_sample *sample = iter->sample;
32dcd021 213 struct evsel *evsel = iter->evsel;
40c39e30
JY
214 int err;
215
c3b10649
JY
216 branch_type_count(&rep->brtype_stat, &bi->flags,
217 bi->from.addr, bi->to.addr);
218
ec6ae74f 219 if (!ui__has_annotation() && !rep->symbol_ipc)
40c39e30
JY
220 return 0;
221
e345f3bd 222 err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
40c39e30
JY
223 if (err)
224 goto out;
225
e345f3bd 226 err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
40c39e30 227
40c39e30
JY
228out:
229 return err;
2d78b189
JY
230}
231
57b5de46 232static void setup_forced_leader(struct report *report,
63503dba 233 struct evlist *evlist)
57b5de46 234{
a26bb0ba 235 if (report->group_set)
64b4778b 236 evlist__force_leader(evlist);
57b5de46
JO
237}
238
89f1688a
JO
239static int process_feature_event(struct perf_session *session,
240 union perf_event *event)
57b5de46 241{
89f1688a 242 struct report *rep = container_of(session->tool, struct report, tool);
57b5de46
JO
243
244 if (event->feat.feat_id < HEADER_LAST_FEATURE)
89f1688a 245 return perf_event__process_feature(session, event);
57b5de46
JO
246
247 if (event->feat.feat_id != HEADER_LAST_FEATURE) {
1b8896fb 248 pr_err("failed: wrong feature ID: %" PRI_lu64 "\n",
57b5de46
JO
249 event->feat.feat_id);
250 return -1;
03de8656
NK
251 } else if (rep->header_only) {
252 session_done = 1;
57b5de46
JO
253 }
254
255 /*
92ead7ee
RB
256 * (feat_id = HEADER_LAST_FEATURE) is the end marker which
257 * means all features are received, now we can force the
57b5de46
JO
258 * group if needed.
259 */
260 setup_forced_leader(rep, session->evlist);
261 return 0;
262}
263
45694aa7 264static int process_sample_event(struct perf_tool *tool,
d20deb64 265 union perf_event *event,
8115d60c 266 struct perf_sample *sample,
32dcd021 267 struct evsel *evsel,
743eb868 268 struct machine *machine)
75051724 269{
28b21393 270 struct report *rep = container_of(tool, struct report, tool);
1ed091c4 271 struct addr_location al;
69bcb019 272 struct hist_entry_iter iter = {
063bd936
NK
273 .evsel = evsel,
274 .sample = sample,
b49a8fe5 275 .hide_unresolved = symbol_conf.hide_unresolved,
063bd936 276 .add_entry_cb = hist_iter__report_callback,
69bcb019 277 };
b91fc39f 278 int ret = 0;
180f95e2 279
5b969bc7
JY
280 if (perf_time__ranges_skip_sample(rep->ptime_range, rep->range_num,
281 sample->time)) {
46690a80 282 return 0;
5b969bc7 283 }
46690a80 284
ef4b1a53
ACM
285 if (evswitch__discard(&rep->evswitch, evsel))
286 return 0;
287
bb3eb566 288 if (machine__resolve(machine, &al, sample) < 0) {
a4210141
NK
289 pr_debug("problem processing %d event, skipping it.\n",
290 event->header.type);
75051724
IM
291 return -1;
292 }
e7fb08b1 293
b1d1429b
KL
294 if (rep->stitch_lbr)
295 al.thread->lbr_stitch_enable = true;
296
b49a8fe5 297 if (symbol_conf.hide_unresolved && al.sym == NULL)
b91fc39f 298 goto out_put;
7bec7a91 299
fa372aae 300 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
b91fc39f 301 goto out_put;
5d67be97 302
f86225db
AH
303 if (sort__mode == SORT_MODE__BRANCH) {
304 /*
305 * A non-synthesized event might not have a branch stack if
306 * branch stacks have been synthesized (using itrace options).
307 */
308 if (!sample->branch_stack)
309 goto out_put;
2d78b189
JY
310
311 iter.add_entry_cb = hist_iter__branch_callback;
69bcb019 312 iter.ops = &hist_iter_branch;
f86225db 313 } else if (rep->mem_mode) {
69bcb019 314 iter.ops = &hist_iter_mem;
f86225db 315 } else if (symbol_conf.cumulate_callchain) {
7a13aa28 316 iter.ops = &hist_iter_cumulative;
f86225db 317 } else {
69bcb019 318 iter.ops = &hist_iter_normal;
f86225db 319 }
69bcb019
NK
320
321 if (al.map != NULL)
63df0e4b 322 map__dso(al.map)->hit = 1;
69bcb019 323
6f7164fa 324 if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) {
bdd1666b 325 hist__account_cycles(sample->branch_stack, &al, sample,
6f7164fa
JY
326 rep->nonany_branch_mode,
327 &rep->total_cycles);
bdd1666b
JY
328 }
329
063bd936 330 ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
69bcb019
NK
331 if (ret < 0)
332 pr_debug("problem adding hist entry, skipping event\n");
b91fc39f
ACM
333out_put:
334 addr_location__put(&al);
27a0dcb7 335 return ret;
75051724 336}
3502973d 337
45694aa7 338static int process_read_event(struct perf_tool *tool,
d20deb64 339 union perf_event *event,
1d037ca1 340 struct perf_sample *sample __maybe_unused,
32dcd021 341 struct evsel *evsel,
1d037ca1 342 struct machine *machine __maybe_unused)
e9ea2fde 343{
28b21393 344 struct report *rep = container_of(tool, struct report, tool);
743eb868 345
fa372aae 346 if (rep->show_threads) {
8ab2e96d 347 const char *name = evsel__name(evsel);
89973506 348 int err = perf_read_values_add_value(&rep->show_threads_values,
8d513270 349 event->read.pid, event->read.tid,
38fe0e01 350 evsel->core.idx,
8d513270
BG
351 name,
352 event->read.value);
89973506
ACM
353
354 if (err)
355 return err;
8d513270
BG
356 }
357
e9ea2fde
PZ
358 return 0;
359}
360
300aa941 361/* For pipe mode, sample_type is not currently set */
28b21393 362static int report__setup_sample_type(struct report *rep)
d80d338d 363{
c824c433 364 struct perf_session *session = rep->session;
b3c2cc2b 365 u64 sample_type = evlist__combined_sample_type(session->evlist);
8ceb41d7 366 bool is_pipe = perf_data__is_pipe(session->data);
ccb17cae 367 struct evsel *evsel;
d20deb64 368
d062ac16 369 if (session->itrace_synth_opts->callchain ||
1c5c25b3 370 session->itrace_synth_opts->add_callchain ||
d062ac16
AH
371 (!is_pipe &&
372 perf_header__has_feat(&session->header, HEADER_AUXTRACE) &&
373 !session->itrace_synth_opts->set))
374 sample_type |= PERF_SAMPLE_CALLCHAIN;
375
ec90e42c
AH
376 if (session->itrace_synth_opts->last_branch ||
377 session->itrace_synth_opts->add_last_branch)
c7eced63
AH
378 sample_type |= PERF_SAMPLE_BRANCH_STACK;
379
cc9784bd 380 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
de7e6a7c 381 if (perf_hpp_list.parent) {
3780f488 382 ui__error("Selected --sort parent, but no "
00894ce9
ACM
383 "callchain data. Did you call "
384 "'perf record' without -g?\n");
d549c769 385 return -EINVAL;
91b4eaea 386 }
b49a821e
JY
387 if (symbol_conf.use_callchain &&
388 !symbol_conf.show_branchflag_count) {
389 ui__error("Selected -g or --branch-history.\n"
390 "But no callchain or branch data.\n"
391 "Did you call 'perf record' without -g or -b?\n");
016e92fb 392 return -1;
91b4eaea 393 }
1cc83815 394 } else if (!callchain_param.enabled &&
fa372aae 395 callchain_param.mode != CHAIN_NONE &&
b9a63b9b 396 !symbol_conf.use_callchain) {
d599db3f 397 symbol_conf.use_callchain = true;
16537f13 398 if (callchain_register_param(&callchain_param) < 0) {
3780f488 399 ui__error("Can't register callchain params.\n");
d549c769 400 return -EINVAL;
b1a88349 401 }
f5970550
PZ
402 }
403
793aaaab
NK
404 if (symbol_conf.cumulate_callchain) {
405 /* Silently ignore if callchain is missing */
406 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
407 symbol_conf.cumulate_callchain = false;
408 perf_hpp__cancel_cumulate();
409 }
410 }
411
55369fc1 412 if (sort__mode == SORT_MODE__BRANCH) {
cc9784bd 413 if (!is_pipe &&
7f3be652 414 !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
3780f488
NK
415 ui__error("Selected -b but no branch data. "
416 "Did you call perf record without -b?\n");
b50311dc
RAV
417 return -1;
418 }
419 }
420
bb30acae 421 if (sort__mode == SORT_MODE__MEMORY) {
ccb17cae
LY
422 /*
423 * FIXUP: prior to kernel 5.18, Arm SPE missed to set
424 * PERF_SAMPLE_DATA_SRC bit in sample type. For backward
425 * compatibility, set the bit if it's an old perf data file.
426 */
427 evlist__for_each_entry(session->evlist, evsel) {
428 if (strstr(evsel->name, "arm_spe") &&
429 !(sample_type & PERF_SAMPLE_DATA_SRC)) {
430 evsel->core.attr.sample_type |= PERF_SAMPLE_DATA_SRC;
431 sample_type |= PERF_SAMPLE_DATA_SRC;
432 }
433 }
434
bb30acae
RB
435 if (!is_pipe && !(sample_type & PERF_SAMPLE_DATA_SRC)) {
436 ui__error("Selected --mem-mode but no mem data. "
437 "Did you call perf record without -d?\n");
438 return -1;
439 }
440 }
441
aa8db3e4 442 callchain_param_setup(sample_type, perf_env__arch(&rep->session->header.env));
98df858e 443
b1d1429b
KL
444 if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
445 ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
446 "Please apply --call-graph lbr when recording.\n");
447 rep->stitch_lbr = false;
448 }
449
98df858e 450 /* ??? handle more cases than just ANY? */
92c7d7cd 451 if (!(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY))
98df858e
AK
452 rep->nonany_branch_mode = true;
453
c3314a74 454#if !defined(HAVE_LIBUNWIND_SUPPORT) && !defined(HAVE_DWARF_SUPPORT)
800d3f56 455 if (dwarf_callchain_users) {
c3314a74
JY
456 ui__warning("Please install libunwind or libdw "
457 "development packages during the perf build.\n");
800d3f56
JY
458 }
459#endif
460
016e92fb
FW
461 return 0;
462}
6142f9ec 463
1d037ca1 464static void sig_handler(int sig __maybe_unused)
46656ac7
TZ
465{
466 session_done = 1;
467}
468
28b21393 469static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
c82ee828
ACM
470 const char *evname, FILE *fp)
471{
472 size_t ret;
473 char unit;
0f0abbac 474 unsigned long nr_samples = hists->stats.nr_samples;
c824c433 475 u64 nr_events = hists->stats.total_period;
32dcd021 476 struct evsel *evsel = hists_to_evsel(hists);
717e263f
NK
477 char buf[512];
478 size_t size = sizeof(buf);
84734b06 479 int socked_id = hists->socket_filter;
717e263f 480
27fafab5
NK
481 if (quiet)
482 return 0;
483
f2148330
NK
484 if (symbol_conf.filter_relative) {
485 nr_samples = hists->stats.nr_non_filtered_samples;
486 nr_events = hists->stats.total_non_filtered_period;
487 }
488
c754c382 489 if (evsel__is_group_event(evsel)) {
32dcd021 490 struct evsel *pos;
717e263f 491
347c751a 492 evsel__group_desc(evsel, buf, size);
717e263f
NK
493 evname = buf;
494
495 for_each_group_member(pos, evsel) {
4ea062ed
ACM
496 const struct hists *pos_hists = evsel__hists(pos);
497
f2148330 498 if (symbol_conf.filter_relative) {
4ea062ed
ACM
499 nr_samples += pos_hists->stats.nr_non_filtered_samples;
500 nr_events += pos_hists->stats.total_non_filtered_period;
f2148330 501 } else {
0f0abbac 502 nr_samples += pos_hists->stats.nr_samples;
4ea062ed 503 nr_events += pos_hists->stats.total_period;
f2148330 504 }
717e263f
NK
505 }
506 }
c82ee828 507
cc686280
AR
508 nr_samples = convert_unit(nr_samples, &unit);
509 ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
8ef278bb
JO
510 if (evname != NULL) {
511 ret += fprintf(fp, " of event%s '%s'",
5643b1a5 512 evsel->core.nr_members > 1 ? "s" : "", evname);
8ef278bb 513 }
cc686280 514
7425664b
JY
515 if (rep->time_str)
516 ret += fprintf(fp, " (time slices: %s)", rep->time_str);
517
11b6e548 518 if (symbol_conf.show_ref_callgraph && evname && strstr(evname, "call-graph=no")) {
9e207ddf
KL
519 ret += fprintf(fp, ", show reference callgraph");
520 }
521
f4f7e28d
SE
522 if (rep->mem_mode) {
523 ret += fprintf(fp, "\n# Total weight : %" PRIu64, nr_events);
228f14f2 524 ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order);
f4f7e28d
SE
525 } else
526 ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
21394d94 527
84734b06
KL
528 if (socked_id > -1)
529 ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
21394d94 530
c82ee828
ACM
531 return ret + fprintf(fp, "\n#\n");
532}
533
f4bd0b4a 534static int evlist__tui_block_hists_browse(struct evlist *evlist, struct report *rep)
7fa46cbf
JY
535{
536 struct evsel *pos;
537 int i = 0, ret;
538
539 evlist__for_each_entry(evlist, pos) {
540 ret = report__browse_block_hists(&rep->block_reports[i++].hist,
848a5e50
JY
541 rep->min_percent, pos,
542 &rep->session->header.env,
543 &rep->annotation_opts);
7fa46cbf
JY
544 if (ret != 0)
545 return ret;
546 }
547
548 return 0;
549}
550
f4bd0b4a 551static int evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, const char *help)
d67f088e 552{
32dcd021 553 struct evsel *pos;
6f7164fa 554 int i = 0;
d67f088e 555
27fafab5
NK
556 if (!quiet) {
557 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
558 evlist->stats.total_lost_samples);
559 }
560
e5cadb93 561 evlist__for_each_entry(evlist, pos) {
4ea062ed 562 struct hists *hists = evsel__hists(pos);
8ab2e96d 563 const char *evname = evsel__name(pos);
d67f088e 564
c754c382 565 if (symbol_conf.event_group && !evsel__is_group_leader(pos))
fc24d7c2
NK
566 continue;
567
2775de0b
NK
568 if (rep->skip_empty && !hists->stats.nr_samples)
569 continue;
570
28b21393 571 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
6f7164fa
JY
572
573 if (rep->total_cycles_mode) {
574 report__browse_block_hists(&rep->block_reports[i++].hist,
848a5e50
JY
575 rep->min_percent, pos,
576 NULL, NULL);
6f7164fa
JY
577 continue;
578 }
579
27fafab5 580 hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
e9de7e2f
ACM
581 !(symbol_conf.use_callchain ||
582 symbol_conf.show_branchflag_count));
d67f088e 583 fprintf(stdout, "\n\n");
d67f088e
ACM
584 }
585
8b53dbef 586 if (!quiet)
d67f088e
ACM
587 fprintf(stdout, "#\n# (%s)\n#\n", help);
588
021162cf
NK
589 if (rep->show_threads) {
590 bool style = !strcmp(rep->pretty_printing_style, "raw");
591 perf_read_values_display(stdout, &rep->show_threads_values,
592 style);
593 perf_read_values_destroy(&rep->show_threads_values);
d67f088e
ACM
594 }
595
2d78b189
JY
596 if (sort__mode == SORT_MODE__BRANCH)
597 branch_type_stat_display(stdout, &rep->brtype_stat);
598
d67f088e
ACM
599 return 0;
600}
601
fad2918e
ACM
602static void report__warn_kptr_restrict(const struct report *rep)
603{
a5e813c6 604 struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
f6fcc143 605 struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
fad2918e 606
78e1bc25 607 if (evlist__exclude_kernel(rep->session->evlist))
9c39ed90
ACM
608 return;
609
fad2918e 610 if (kernel_map == NULL ||
63df0e4b 611 (map__dso(kernel_map)->hit &&
fad2918e
ACM
612 (kernel_kmap->ref_reloc_sym == NULL ||
613 kernel_kmap->ref_reloc_sym->addr == 0))) {
614 const char *desc =
615 "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
616 "can't be resolved.";
617
e94b861a
ACM
618 if (kernel_map && map__has_symbols(kernel_map)) {
619 desc = "If some relocation was applied (e.g. "
620 "kexec) symbols may be misresolved.";
fad2918e
ACM
621 }
622
623 ui__warning(
624"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
625"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
626"Samples in kernel modules can't be resolved as well.\n\n",
627 desc);
628 }
629}
630
8362951b
ACM
631static int report__gtk_browse_hists(struct report *rep, const char *help)
632{
63503dba 633 int (*hist_browser)(struct evlist *evlist, const char *help,
8362951b
ACM
634 struct hist_browser_timer *timer, float min_pcnt);
635
f4bd0b4a 636 hist_browser = dlsym(perf_gtk_handle, "evlist__gtk_browse_hists");
8362951b
ACM
637
638 if (hist_browser == NULL) {
639 ui__error("GTK browser not found!\n");
640 return -1;
641 }
642
643 return hist_browser(rep->session->evlist, help, NULL, rep->min_percent);
644}
645
646static int report__browse_hists(struct report *rep)
647{
648 int ret;
649 struct perf_session *session = rep->session;
63503dba 650 struct evlist *evlist = session->evlist;
d9fc7061 651 char *help = NULL, *path = NULL;
34b7b0f9 652
d9fc7061
IR
653 path = system_path(TIPDIR);
654 if (perf_tip(&help, path) || help == NULL) {
34b7b0f9 655 /* fallback for people who don't install perf ;-) */
d9fc7061
IR
656 free(path);
657 path = system_path(DOCDIR);
658 if (perf_tip(&help, path) || help == NULL)
659 help = strdup("Cannot load tips.txt file, please install perf!");
34b7b0f9 660 }
d9fc7061 661 free(path);
8362951b
ACM
662
663 switch (use_browser) {
664 case 1:
7fa46cbf 665 if (rep->total_cycles_mode) {
f4bd0b4a 666 ret = evlist__tui_block_hists_browse(evlist, rep);
7fa46cbf
JY
667 break;
668 }
669
f4bd0b4a
ACM
670 ret = evlist__tui_browse_hists(evlist, help, NULL, rep->min_percent,
671 &session->header.env, true, &rep->annotation_opts);
8362951b
ACM
672 /*
673 * Usually "ret" is the last pressed key, and we only
674 * care if the key notifies us to switch data file.
675 */
5e3b810a 676 if (ret != K_SWITCH_INPUT_DATA && ret != K_RELOAD)
8362951b
ACM
677 ret = 0;
678 break;
679 case 2:
680 ret = report__gtk_browse_hists(rep, help);
681 break;
682 default:
f4bd0b4a 683 ret = evlist__tty_browse_hists(evlist, rep, help);
8362951b
ACM
684 break;
685 }
d9fc7061 686 free(help);
8362951b
ACM
687 return ret;
688}
689
5b2ea6f2 690static int report__collapse_hists(struct report *rep)
f6d8b057
ACM
691{
692 struct ui_progress prog;
32dcd021 693 struct evsel *pos;
5b2ea6f2 694 int ret = 0;
f6d8b057 695
58c311da 696 ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
f6d8b057 697
e5cadb93 698 evlist__for_each_entry(rep->session->evlist, pos) {
4ea062ed 699 struct hists *hists = evsel__hists(pos);
f6d8b057 700
38fe0e01 701 if (pos->core.idx == 0)
f6d8b057
ACM
702 hists->symbol_filter_str = rep->symbol_filter_str;
703
21394d94
KL
704 hists->socket_filter = rep->socket_filter;
705
5b2ea6f2
NK
706 ret = hists__collapse_resort(hists, &prog);
707 if (ret < 0)
708 break;
f6d8b057
ACM
709
710 /* Non-group events are considered as leader */
c754c382 711 if (symbol_conf.event_group && !evsel__is_group_leader(pos)) {
fba7c866 712 struct hists *leader_hists = evsel__hists(evsel__leader(pos));
f6d8b057
ACM
713
714 hists__match(leader_hists, hists);
715 hists__link(leader_hists, hists);
716 }
717 }
718
719 ui_progress__finish();
5b2ea6f2 720 return ret;
f6d8b057
ACM
721}
722
dbd2a1d5
JO
723static int hists__resort_cb(struct hist_entry *he, void *arg)
724{
725 struct report *rep = arg;
726 struct symbol *sym = he->ms.sym;
727
728 if (rep->symbol_ipc && sym && !sym->annotate2) {
32dcd021 729 struct evsel *evsel = hists_to_evsel(he->hists);
dbd2a1d5 730
217b7d41 731 symbol__annotate2(&he->ms, evsel, &rep->annotation_opts, NULL);
dbd2a1d5
JO
732 }
733
734 return 0;
735}
736
740b97f9
NK
737static void report__output_resort(struct report *rep)
738{
739 struct ui_progress prog;
32dcd021 740 struct evsel *pos;
740b97f9
NK
741
742 ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
743
dbd2a1d5 744 evlist__for_each_entry(rep->session->evlist, pos) {
10c513f7 745 evsel__output_resort_cb(pos, &prog, hists__resort_cb, rep);
dbd2a1d5 746 }
740b97f9
NK
747
748 ui_progress__finish();
749}
750
55f75444
NK
751static int count_sample_event(struct perf_tool *tool __maybe_unused,
752 union perf_event *event __maybe_unused,
753 struct perf_sample *sample __maybe_unused,
754 struct evsel *evsel,
755 struct machine *machine __maybe_unused)
756{
757 struct hists *hists = evsel__hists(evsel);
758
759 hists__inc_nr_events(hists);
760 return 0;
761}
762
d7ba22d4
NK
763static int count_lost_samples_event(struct perf_tool *tool,
764 union perf_event *event,
765 struct perf_sample *sample,
766 struct machine *machine __maybe_unused)
767{
768 struct report *rep = container_of(tool, struct report, tool);
769 struct evsel *evsel;
770
771 evsel = evlist__id2evsel(rep->session->evlist, sample->id);
772 if (evsel) {
773 hists__inc_nr_lost_samples(evsel__hists(evsel),
774 event->lost_samples.lost);
775 }
776 return 0;
777}
778
892ba7f1
NK
779static int process_attr(struct perf_tool *tool __maybe_unused,
780 union perf_event *event,
781 struct evlist **pevlist);
782
a4a4d0a7
JO
783static void stats_setup(struct report *rep)
784{
785 memset(&rep->tool, 0, sizeof(rep->tool));
892ba7f1 786 rep->tool.attr = process_attr;
55f75444 787 rep->tool.sample = count_sample_event;
d7ba22d4 788 rep->tool.lost_samples = count_lost_samples_event;
a4a4d0a7
JO
789 rep->tool.no_warn = true;
790}
791
792static int stats_print(struct report *rep)
793{
794 struct perf_session *session = rep->session;
795
2775de0b
NK
796 perf_session__fprintf_nr_events(session, stdout, rep->skip_empty);
797 evlist__fprintf_nr_events(session->evlist, stdout, rep->skip_empty);
a4a4d0a7
JO
798 return 0;
799}
800
930f8b34
JO
801static void tasks_setup(struct report *rep)
802{
803 memset(&rep->tool, 0, sizeof(rep->tool));
8614ada0 804 rep->tool.ordered_events = true;
6439d7d1
ACM
805 if (rep->mmaps_mode) {
806 rep->tool.mmap = perf_event__process_mmap;
807 rep->tool.mmap2 = perf_event__process_mmap2;
808 }
892ba7f1 809 rep->tool.attr = process_attr;
930f8b34
JO
810 rep->tool.comm = perf_event__process_comm;
811 rep->tool.exit = perf_event__process_exit;
812 rep->tool.fork = perf_event__process_fork;
813 rep->tool.no_warn = true;
814}
815
816struct task {
817 struct thread *thread;
818 struct list_head list;
819 struct list_head children;
820};
821
822static struct task *tasks_list(struct task *task, struct machine *machine)
823{
824 struct thread *parent_thread, *thread = task->thread;
825 struct task *parent_task;
826
827 /* Already listed. */
828 if (!list_empty(&task->list))
829 return NULL;
830
831 /* Last one in the chain. */
832 if (thread->ppid == -1)
833 return task;
834
835 parent_thread = machine__find_thread(machine, -1, thread->ppid);
836 if (!parent_thread)
837 return ERR_PTR(-ENOENT);
838
839 parent_task = thread__priv(parent_thread);
840 list_add_tail(&task->list, &parent_task->children);
841 return tasks_list(parent_task, machine);
842}
843
6439d7d1
ACM
844static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
845{
846 size_t printed = 0;
ff583dc4
IR
847 struct map_rb_node *rb_node;
848
849 maps__for_each_entry(maps, rb_node) {
850 struct map *map = rb_node->map;
63df0e4b 851 const struct dso *dso = map__dso(map);
ddee3f2b 852 u32 prot = map__prot(map);
6439d7d1
ACM
853
854 printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
e5116f46 855 indent, "", map__start(map), map__end(map),
ddee3f2b
IR
856 prot & PROT_READ ? 'r' : '-',
857 prot & PROT_WRITE ? 'w' : '-',
858 prot & PROT_EXEC ? 'x' : '-',
859 map__flags(map) ? 's' : 'p',
2a6e5e8a 860 map__pgoff(map),
63df0e4b 861 dso->id.ino, dso->name);
6439d7d1
ACM
862 }
863
864 return printed;
865}
866
930f8b34
JO
867static void task__print_level(struct task *task, FILE *fp, int level)
868{
869 struct thread *thread = task->thread;
870 struct task *child;
6439d7d1
ACM
871 int comm_indent = fprintf(fp, " %8d %8d %8d |%*s",
872 thread->pid_, thread->tid, thread->ppid,
873 level, "");
874
875 fprintf(fp, "%s\n", thread__comm_str(thread));
930f8b34 876
fe87797d 877 maps__fprintf_task(thread->maps, comm_indent, fp);
930f8b34
JO
878
879 if (!list_empty(&task->children)) {
880 list_for_each_entry(child, &task->children, list)
881 task__print_level(child, fp, level + 1);
882 }
883}
884
885static int tasks_print(struct report *rep, FILE *fp)
886{
887 struct perf_session *session = rep->session;
888 struct machine *machine = &session->machines.host;
889 struct task *tasks, *task;
890 unsigned int nr = 0, itask = 0, i;
891 struct rb_node *nd;
892 LIST_HEAD(list);
893
894 /*
895 * No locking needed while accessing machine->threads,
896 * because --tasks is single threaded command.
897 */
898
899 /* Count all the threads. */
900 for (i = 0; i < THREADS__TABLE_SIZE; i++)
901 nr += machine->threads[i].nr;
902
903 tasks = malloc(sizeof(*tasks) * nr);
904 if (!tasks)
905 return -ENOMEM;
906
907 for (i = 0; i < THREADS__TABLE_SIZE; i++) {
908 struct threads *threads = &machine->threads[i];
909
f3acb3a8
DB
910 for (nd = rb_first_cached(&threads->entries); nd;
911 nd = rb_next(nd)) {
930f8b34
JO
912 task = tasks + itask++;
913
914 task->thread = rb_entry(nd, struct thread, rb_node);
915 INIT_LIST_HEAD(&task->children);
916 INIT_LIST_HEAD(&task->list);
917 thread__set_priv(task->thread, task);
918 }
919 }
920
921 /*
922 * Iterate every task down to the unprocessed parent
923 * and link all in task children list. Task with no
924 * parent is added into 'list'.
925 */
926 for (itask = 0; itask < nr; itask++) {
927 task = tasks + itask;
928
929 if (!list_empty(&task->list))
930 continue;
931
932 task = tasks_list(task, machine);
933 if (IS_ERR(task)) {
934 pr_err("Error: failed to process tasks\n");
935 free(tasks);
936 return PTR_ERR(task);
937 }
938
939 if (task)
940 list_add_tail(&task->list, &list);
941 }
942
943 fprintf(fp, "# %8s %8s %8s %s\n", "pid", "tid", "ppid", "comm");
944
945 list_for_each_entry(task, &list, list)
946 task__print_level(task, fp, 0);
947
948 free(tasks);
949 return 0;
950}
951
28b21393 952static int __cmd_report(struct report *rep)
016e92fb 953{
f6d8b057 954 int ret;
993ac88d 955 struct perf_session *session = rep->session;
32dcd021 956 struct evsel *pos;
8ceb41d7 957 struct perf_data *data = session->data;
8fa66bdc 958
46656ac7
TZ
959 signal(SIGINT, sig_handler);
960
fa372aae
ACM
961 if (rep->cpu_list) {
962 ret = perf_session__cpu_bitmap(session, rep->cpu_list,
963 rep->cpu_bitmap);
25b1606b
NK
964 if (ret) {
965 ui__error("failed to set cpu bitmap\n");
d4ae0a6f 966 return ret;
25b1606b 967 }
644e0840 968 session->itrace_synth_opts->cpu_bitmap = rep->cpu_bitmap;
5d67be97
AB
969 }
970
89973506
ACM
971 if (rep->show_threads) {
972 ret = perf_read_values_init(&rep->show_threads_values);
973 if (ret)
974 return ret;
975 }
f5970550 976
28b21393 977 ret = report__setup_sample_type(rep);
25b1606b
NK
978 if (ret) {
979 /* report__setup_sample_type() already showed error message */
d4ae0a6f 980 return ret;
25b1606b 981 }
d549c769 982
a4a4d0a7
JO
983 if (rep->stats_mode)
984 stats_setup(rep);
985
930f8b34
JO
986 if (rep->tasks_mode)
987 tasks_setup(rep);
988
b7b61cbe 989 ret = perf_session__process_events(session);
25b1606b
NK
990 if (ret) {
991 ui__error("failed to process sample\n");
d4ae0a6f 992 return ret;
25b1606b 993 }
97b07b69 994
d5a8bd0f
JY
995 evlist__check_mem_load_aux(session->evlist);
996
a4a4d0a7
JO
997 if (rep->stats_mode)
998 return stats_print(rep);
999
930f8b34
JO
1000 if (rep->tasks_mode)
1001 return tasks_print(rep, stdout);
1002
fad2918e 1003 report__warn_kptr_restrict(rep);
ec80fde7 1004
e5cadb93 1005 evlist__for_each_entry(session->evlist, pos)
590cd344
NK
1006 rep->nr_entries += evsel__hists(pos)->nr_entries;
1007
150e465a
NK
1008 if (use_browser == 0) {
1009 if (verbose > 3)
1010 perf_session__fprintf(session, stdout);
9ac99545 1011
150e465a
NK
1012 if (verbose > 2)
1013 perf_session__fprintf_dsos(session, stdout);
16f762a2 1014
150e465a 1015 if (dump_trace) {
2775de0b
NK
1016 perf_session__fprintf_nr_events(session, stdout,
1017 rep->skip_empty);
1018 evlist__fprintf_nr_events(session->evlist, stdout,
1019 rep->skip_empty);
150e465a
NK
1020 return 0;
1021 }
71ad0f5e
JO
1022 }
1023
5b2ea6f2
NK
1024 ret = report__collapse_hists(rep);
1025 if (ret) {
1026 ui__error("failed to process hist entry\n");
1027 return ret;
1028 }
e248de33 1029
33e940a2
ACM
1030 if (session_done())
1031 return 0;
1032
740b97f9
NK
1033 /*
1034 * recalculate number of entries after collapsing since it
1035 * might be changed during the collapse phase.
1036 */
1037 rep->nr_entries = 0;
e5cadb93 1038 evlist__for_each_entry(session->evlist, pos)
740b97f9
NK
1039 rep->nr_entries += evsel__hists(pos)->nr_entries;
1040
58c311da 1041 if (rep->nr_entries == 0) {
2d4f2799 1042 ui__error("The %s data has no samples!\n", data->path);
d4ae0a6f 1043 return 0;
cbbc79a5
EM
1044 }
1045
740b97f9 1046 report__output_resort(rep);
6e1f601a 1047
6f7164fa 1048 if (rep->total_cycles_mode) {
cca0cc76
JY
1049 int block_hpps[6] = {
1050 PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT,
1051 PERF_HPP_REPORT__BLOCK_LBR_CYCLES,
1052 PERF_HPP_REPORT__BLOCK_CYCLES_PCT,
1053 PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
1054 PERF_HPP_REPORT__BLOCK_RANGE,
1055 PERF_HPP_REPORT__BLOCK_DSO,
1056 };
1057
6f7164fa 1058 rep->block_reports = block_info__create_report(session->evlist,
cca0cc76
JY
1059 rep->total_cycles,
1060 block_hpps, 6,
1061 &rep->nr_block_reports);
6f7164fa
JY
1062 if (!rep->block_reports)
1063 return -1;
1064 }
1065
8362951b 1066 return report__browse_hists(rep);
8fa66bdc
ACM
1067}
1068
4eb3e478 1069static int
cff6bb46 1070report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
4eb3e478 1071{
1cc83815 1072 struct callchain_param *callchain = opt->value;
c20ab37e 1073
1cc83815 1074 callchain->enabled = !unset;
b9a63b9b
ACM
1075 /*
1076 * --no-call-graph
1077 */
1078 if (unset) {
1cc83815
ACM
1079 symbol_conf.use_callchain = false;
1080 callchain->mode = CHAIN_NONE;
b9a63b9b
ACM
1081 return 0;
1082 }
1083
cff6bb46 1084 return parse_callchain_report_opt(arg);
4eb3e478
FW
1085}
1086
2a1292cb
AK
1087static int
1088parse_time_quantum(const struct option *opt, const char *arg,
1089 int unset __maybe_unused)
1090{
1091 unsigned long *time_q = opt->value;
1092 char *end;
1093
1094 *time_q = strtoul(arg, &end, 0);
1095 if (end == arg)
1096 goto parse_err;
1097 if (*time_q == 0) {
1098 pr_err("time quantum cannot be 0");
1099 return -1;
1100 }
526bbbdd 1101 end = skip_spaces(end);
2a1292cb
AK
1102 if (*end == 0)
1103 return 0;
1104 if (!strcmp(end, "s")) {
1105 *time_q *= NSEC_PER_SEC;
1106 return 0;
1107 }
1108 if (!strcmp(end, "ms")) {
1109 *time_q *= NSEC_PER_MSEC;
1110 return 0;
1111 }
1112 if (!strcmp(end, "us")) {
1113 *time_q *= NSEC_PER_USEC;
1114 return 0;
1115 }
1116 if (!strcmp(end, "ns"))
1117 return 0;
1118parse_err:
1119 pr_err("Cannot parse time quantum `%s'\n", arg);
1120 return -1;
1121}
1122
b21484f1
GP
1123int
1124report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
1125 const char *arg, int unset __maybe_unused)
1126{
1127 if (arg) {
1128 int err = regcomp(&ignore_callees_regex, arg, REG_EXTENDED);
1129 if (err) {
1130 char buf[BUFSIZ];
1131 regerror(err, &ignore_callees_regex, buf, sizeof(buf));
1132 pr_err("Invalid --ignore-callees regex: %s\n%s", arg, buf);
1133 return -1;
1134 }
1135 have_ignore_callees = 1;
1136 }
1137
1138 return 0;
1139}
1140
993ac88d 1141static int
7e6a7998 1142parse_branch_mode(const struct option *opt,
1d037ca1 1143 const char *str __maybe_unused, int unset)
993ac88d 1144{
55369fc1
NK
1145 int *branch_mode = opt->value;
1146
1147 *branch_mode = !unset;
993ac88d
SE
1148 return 0;
1149}
1150
064f1981
NK
1151static int
1152parse_percent_limit(const struct option *opt, const char *str,
1153 int unset __maybe_unused)
1154{
28b21393 1155 struct report *rep = opt->value;
2665b452 1156 double pcnt = strtof(str, NULL);
064f1981 1157
2665b452
NK
1158 rep->min_percent = pcnt;
1159 callchain_param.min_percent = pcnt;
064f1981
NK
1160 return 0;
1161}
1162
0d71a2b2
JO
1163static int process_attr(struct perf_tool *tool __maybe_unused,
1164 union perf_event *event,
1165 struct evlist **pevlist)
1166{
1167 u64 sample_type;
1168 int err;
1169
1170 err = perf_event__process_attr(tool, event, pevlist);
1171 if (err)
1172 return err;
1173
1174 /*
1175 * Check if we need to enable callchains based
1176 * on events sample_type.
1177 */
b3c2cc2b 1178 sample_type = evlist__combined_sample_type(*pevlist);
aa8db3e4 1179 callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env));
0d71a2b2
JO
1180 return 0;
1181}
1182
b0ad8ea6 1183int cmd_report(int argc, const char **argv)
d20deb64 1184{
993ac88d 1185 struct perf_session *session;
520a2ebc 1186 struct itrace_synth_opts itrace_synth_opts = { .set = 0, };
efad1415 1187 struct stat st;
993ac88d 1188 bool has_br_stack = false;
55369fc1 1189 int branch_mode = -1;
0feba17b 1190 int last_key = 0;
fa94c36c 1191 bool branch_call_mode = false;
9d0199cd 1192#define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function,percent"
49b8e2be
RV
1193 static const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
1194 CALLCHAIN_REPORT_HELP
1195 "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
76a26549 1196 char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
d20deb64 1197 const char * const report_usage[] = {
fb2baceb 1198 "perf report [<options>]",
d20deb64
ACM
1199 NULL
1200 };
28b21393 1201 struct report report = {
45694aa7 1202 .tool = {
d20deb64
ACM
1203 .sample = process_sample_event,
1204 .mmap = perf_event__process_mmap,
5c5e854b 1205 .mmap2 = perf_event__process_mmap2,
d20deb64 1206 .comm = perf_event__process_comm,
f3b3614a 1207 .namespaces = perf_event__process_namespaces,
ba78c1c5 1208 .cgroup = perf_event__process_cgroup,
f62d3f0f
ACM
1209 .exit = perf_event__process_exit,
1210 .fork = perf_event__process_fork,
d20deb64
ACM
1211 .lost = perf_event__process_lost,
1212 .read = process_read_event,
0d71a2b2 1213 .attr = process_attr,
378ef0f5 1214#ifdef HAVE_LIBTRACEEVENT
d20deb64 1215 .tracing_data = perf_event__process_tracing_data,
378ef0f5 1216#endif
d20deb64 1217 .build_id = perf_event__process_build_id,
520a2ebc
AH
1218 .id_index = perf_event__process_id_index,
1219 .auxtrace_info = perf_event__process_auxtrace_info,
1220 .auxtrace = perf_event__process_auxtrace,
4ab8455f 1221 .event_update = perf_event__process_event_update,
57b5de46 1222 .feature = process_feature_event,
0a8cb85c 1223 .ordered_events = true,
d20deb64
ACM
1224 .ordering_requires_timestamps = true,
1225 },
fe176085 1226 .max_stack = PERF_MAX_STACK_DEPTH,
d20deb64 1227 .pretty_printing_style = "normal",
21394d94 1228 .socket_filter = -1,
8f08cf33 1229 .skip_empty = true,
d20deb64 1230 };
a37338aa
RM
1231 char *sort_order_help = sort_help("sort by key(s):");
1232 char *field_order_help = sort_help("output field(s): overhead period sample ");
57594454 1233 const char *disassembler_style = NULL, *objdump_path = NULL, *addr2line_path = NULL;
d20deb64 1234 const struct option options[] = {
70cb4e96 1235 OPT_STRING('i', "input", &input_name, "file",
53cb8bc2 1236 "input file name"),
c0555642 1237 OPT_INCR('v', "verbose", &verbose,
815e777f 1238 "be more verbose (show symbol address, etc)"),
a527c2c1 1239 OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"),
97b07b69
IM
1240 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1241 "dump raw trace in ASCII"),
a4a4d0a7 1242 OPT_BOOLEAN(0, "stats", &report.stats_mode, "Display event stats"),
930f8b34 1243 OPT_BOOLEAN(0, "tasks", &report.tasks_mode, "Display recorded tasks"),
6439d7d1 1244 OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"),
b32d133a
ACM
1245 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1246 "file", "vmlinux pathname"),
91340c51
ACM
1247 OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
1248 "don't load vmlinux even if found"),
b226a5a7
DA
1249 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1250 "file", "kallsyms pathname"),
2059fc7a 1251 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
b32d133a 1252 OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
42976487 1253 "load module symbols - WARNING: use only with -k and LIVE kernel"),
d599db3f 1254 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
e3d7e183 1255 "Show a column with the number of samples"),
fa372aae 1256 OPT_BOOLEAN('T', "threads", &report.show_threads,
8d513270 1257 "Show per-thread event counters"),
fa372aae 1258 OPT_STRING(0, "pretty", &report.pretty_printing_style, "key",
9f866697 1259 "pretty printing style key: normal raw"),
3402ae0a 1260#ifdef HAVE_SLANG_SUPPORT
fa372aae 1261 OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"),
3402ae0a 1262#endif
557cc18e 1263#ifdef HAVE_GTK2_SUPPORT
c31a9457 1264 OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
557cc18e 1265#endif
fa372aae
ACM
1266 OPT_BOOLEAN(0, "stdio", &report.use_stdio,
1267 "Use the stdio interface"),
5cfe2c82
JO
1268 OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
1269 OPT_BOOLEAN(0, "header-only", &report.header_only,
1270 "Show only data header."),
63299f05 1271 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
a37338aa 1272 sort_order_help),
a7d945bc 1273 OPT_STRING('F', "fields", &field_order, "key[,keys...]",
a37338aa 1274 field_order_help),
b272a59d 1275 OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
a1645ce1 1276 "Show sample percentage for different cpu modes"),
b272a59d
NK
1277 OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
1278 "Show sample percentage for different cpu modes", PARSE_OPT_HIDDEN),
b25bcf2f
IM
1279 OPT_STRING('p', "parent", &parent_pattern, "regex",
1280 "regex filter to identify parent, see: '--sort parent'"),
d599db3f 1281 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
b8e6d829 1282 "Only display entries with parent-match"),
1cc83815 1283 OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
f2af0086 1284 "print_type,threshold[,print_limit],order,sort_key[,branch],value",
21cf6284
NK
1285 report_callchain_help, &report_parse_callchain_opt,
1286 callchain_default_opt),
793aaaab 1287 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
aa9d1f83
AK
1288 "Accumulate callchains of children and show total overhead as well. "
1289 "Enabled by default, use --no-children to disable."),
91e95617
WL
1290 OPT_INTEGER(0, "max-stack", &report.max_stack,
1291 "Set the maximum stack depth when parsing the callchain, "
1292 "anything beyond the specified depth will be ignored. "
4cb93446 1293 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
fa372aae
ACM
1294 OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
1295 "alias for inverted call graph"),
b21484f1
GP
1296 OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
1297 "ignore callees of these functions in call graphs",
1298 report_parse_ignore_callees_opt),
655000e7 1299 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
25903407 1300 "only consider symbols in these dsos"),
c8e66720 1301 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
cc8b88b1 1302 "only consider symbols in these comms"),
e03eaa40
DA
1303 OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
1304 "only consider symbols in these pids"),
1305 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
1306 "only consider symbols in these tids"),
655000e7 1307 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
7bec7a91 1308 "only consider these symbols"),
b14ffaca
NK
1309 OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
1310 "only show symbols that (partially) match with this filter"),
655000e7 1311 OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
52d422de
ACM
1312 "width[,width...]",
1313 "don't try to adjust column width, use these fixed values"),
0c8c2077 1314 OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
52d422de
ACM
1315 "separator for columns, no spaces will be added between "
1316 "columns '.' is reserved."),
b49a8fe5 1317 OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
71289be7 1318 "Only display entries resolved to a symbol"),
a7066709
HK
1319 OPT_CALLBACK(0, "symfs", NULL, "directory",
1320 "Look for files with symbols relative to this directory",
1321 symbol__config_symfs),
c8e66720 1322 OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
fa372aae
ACM
1323 "list of cpus to profile"),
1324 OPT_BOOLEAN('I', "show-info", &report.show_full_info,
fbe96f29 1325 "Display extended information about perf.data file"),
1eddd9e4 1326 OPT_BOOLEAN(0, "source", &report.annotation_opts.annotate_src,
64c6f0c7 1327 "Interleave source code with assembly code (default)"),
1eddd9e4 1328 OPT_BOOLEAN(0, "asm-raw", &report.annotation_opts.show_asm_raw,
64c6f0c7 1329 "Display raw encoding of assembly instructions (default)"),
56d9117c 1330 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
f69b64f7 1331 "Specify disassembler style (e.g. -M intel for intel syntax)"),
3b0b16bf
AK
1332 OPT_STRING(0, "prefix", &report.annotation_opts.prefix, "prefix",
1333 "Add prefix to source file path names in programs (with --prefix-strip)"),
1334 OPT_STRING(0, "prefix-strip", &report.annotation_opts.prefix_strip, "N",
1335 "Strip first N entries of source file path name in programs (with --prefix)"),
3f2728bd
ACM
1336 OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
1337 "Show a column with the sum of periods"),
57b5de46 1338 OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set,
01d14f16 1339 "Show event group information together"),
429a5f9d
JY
1340 OPT_INTEGER(0, "group-sort-idx", &symbol_conf.group_sort_idx,
1341 "Sort the output by the event at the index n in group. "
1342 "If n is invalid, sort by the first event. "
1343 "WARNING: should be used on grouped events."),
55369fc1 1344 OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
fa94c36c
AK
1345 "use branch records for per branch histogram filling",
1346 parse_branch_mode),
1347 OPT_BOOLEAN(0, "branch-history", &branch_call_mode,
1348 "add last branch records to call history"),
56d9117c 1349 OPT_STRING(0, "objdump", &objdump_path, "path",
7a4ec938 1350 "objdump binary to use for disassembly and annotations"),
57594454
IR
1351 OPT_STRING(0, "addr2line", &addr2line_path, "path",
1352 "addr2line binary to use for line numbers"),
328ccdac
NK
1353 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
1354 "Disable symbol demangling"),
763122ad
AK
1355 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1356 "Enable kernel symbol demangling"),
f4f7e28d 1357 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
4968ac8f
AK
1358 OPT_INTEGER(0, "samples", &symbol_conf.res_sample,
1359 "Number of samples to save per histogram entry for individual browsing"),
064f1981
NK
1360 OPT_CALLBACK(0, "percent-limit", &report, "percent",
1361 "Don't show entries under that percent", parse_percent_limit),
f2148330 1362 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
33db4568 1363 "how to display percentage of filtered entries", parse_filter_percentage),
520a2ebc 1364 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
c12e039d 1365 "Instruction Tracing options\n" ITRACE_HELP,
520a2ebc 1366 itrace_parse_synth_opts),
a9710ba0
AK
1367 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
1368 "Show full source file name path for source lines"),
9e207ddf
KL
1369 OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
1370 "Show callgraph from reference event"),
b1d1429b
KL
1371 OPT_BOOLEAN(0, "stitch-lbr", &report.stitch_lbr,
1372 "Enable LBR callgraph stitching approach"),
21394d94
KL
1373 OPT_INTEGER(0, "socket-filter", &report.socket_filter,
1374 "only show processor socket that match with this filter"),
053a3989
NK
1375 OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace,
1376 "Show raw trace event output (do not use print fmt or plugins)"),
4251446d
NK
1377 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
1378 "Show entries in a hierarchy"),
175b968b
ACM
1379 OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
1380 "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
1381 stdio__config_color, "always"),
46690a80
DA
1382 OPT_STRING(0, "time", &report.time_str, "str",
1383 "Time span of interest (start,stop)"),
f3a60646
JY
1384 OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
1385 "Show inline function"),
e6902d1b
JO
1386 OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
1387 "Set percent type local/global-period/hits",
1388 annotate_parse_percent_type),
52bab886 1389 OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, "Show times in nanosecs"),
2a1292cb
AK
1390 OPT_CALLBACK(0, "time-quantum", &symbol_conf.time_quantum, "time (ms|us|ns|s)",
1391 "Set time quantum for time sort key (default 100ms)",
1392 parse_time_quantum),
ef4b1a53 1393 OPTS_EVSWITCH(&report.evswitch),
6f7164fa
JY
1394 OPT_BOOLEAN(0, "total-cycles", &report.total_cycles_mode,
1395 "Sort all blocks by 'Sampled Cycles%'"),
2e989f82
JY
1396 OPT_BOOLEAN(0, "disable-order", &report.disable_order,
1397 "Disable raw trace ordering"),
2775de0b
NK
1398 OPT_BOOLEAN(0, "skip-empty", &report.skip_empty,
1399 "Do not display empty (or dummy) events in the output"),
53cb8bc2 1400 OPT_END()
d20deb64 1401 };
8ceb41d7 1402 struct perf_data data = {
f5fc1412
JO
1403 .mode = PERF_DATA_MODE_READ,
1404 };
a635fc51 1405 int ret = hists__init();
ec6ae74f 1406 char sort_tmp[128];
a635fc51
ACM
1407
1408 if (ret < 0)
a37338aa 1409 goto exit;
53cb8bc2 1410
217b7d41
IR
1411 annotation_options__init(&report.annotation_opts);
1412
ecc4c561
ACM
1413 ret = perf_config(report__config, &report);
1414 if (ret)
a37338aa 1415 goto exit;
00c7e1f1 1416
655000e7 1417 argc = parse_options(argc, argv, options, report_usage, 0);
b3f38fc2
NK
1418 if (argc) {
1419 /*
1420 * Special case: if there's an argument left then assume that
1421 * it's a symbol filter:
1422 */
1423 if (argc > 1)
1424 usage_with_options(report_usage, options);
1425
1426 report.symbol_filter_str = argv[0];
1427 }
655000e7 1428
56d9117c
IR
1429 if (disassembler_style) {
1430 report.annotation_opts.disassembler_style = strdup(disassembler_style);
1431 if (!report.annotation_opts.disassembler_style)
1432 return -ENOMEM;
1433 }
1434 if (objdump_path) {
1435 report.annotation_opts.objdump_path = strdup(objdump_path);
1436 if (!report.annotation_opts.objdump_path)
1437 return -ENOMEM;
1438 }
57594454
IR
1439 if (addr2line_path) {
1440 symbol_conf.addr2line_path = strdup(addr2line_path);
1441 if (!symbol_conf.addr2line_path)
1442 return -ENOMEM;
1443 }
56d9117c 1444
a37338aa
RM
1445 if (annotate_check_args(&report.annotation_opts) < 0) {
1446 ret = -EINVAL;
1447 goto exit;
1448 }
3b0b16bf 1449
6439d7d1
ACM
1450 if (report.mmaps_mode)
1451 report.tasks_mode = true;
1452
2e989f82 1453 if (dump_trace && report.disable_order)
977f739b
JO
1454 report.tool.ordered_events = false;
1455
27fafab5
NK
1456 if (quiet)
1457 perf_quiet_option();
1458
a3df50ab
JC
1459 ret = symbol__validate_sym_arguments();
1460 if (ret)
a37338aa 1461 goto exit;
36c8bb56 1462
fa372aae 1463 if (report.inverted_callchain)
d797fdc5 1464 callchain_param.order = ORDER_CALLER;
792aeafa
NK
1465 if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
1466 callchain_param.order = ORDER_CALLER;
d797fdc5 1467
1c5c25b3 1468 if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
188bb5e2
AH
1469 (int)itrace_synth_opts.callchain_sz > report.max_stack)
1470 report.max_stack = itrace_synth_opts.callchain_sz;
1471
70cb4e96 1472 if (!input_name || !strlen(input_name)) {
efad1415 1473 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
70cb4e96 1474 input_name = "-";
efad1415 1475 else
70cb4e96 1476 input_name = "perf.data";
efad1415 1477 }
ad0de097 1478
2d4f2799
JO
1479 data.path = input_name;
1480 data.force = symbol_conf.force;
f5fc1412 1481
ad0de097 1482repeat:
2681bd85 1483 session = perf_session__new(&data, &report.tool);
a37338aa
RM
1484 if (IS_ERR(session)) {
1485 ret = PTR_ERR(session);
1486 goto exit;
1487 }
993ac88d 1488
ef4b1a53
ACM
1489 ret = evswitch__init(&report.evswitch, session->evlist, stderr);
1490 if (ret)
a37338aa 1491 goto exit;
ef4b1a53 1492
cb62c6f1
AB
1493 if (zstd_init(&(session->zstd_data), 0) < 0)
1494 pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
1495
94786b67
JO
1496 if (report.queue_size) {
1497 ordered_events__set_alloc_size(&session->ordered_events,
1498 report.queue_size);
1499 }
1500
520a2ebc
AH
1501 session->itrace_synth_opts = &itrace_synth_opts;
1502
993ac88d
SE
1503 report.session = session;
1504
1505 has_br_stack = perf_header__has_feat(&session->header,
1506 HEADER_BRANCH_STACK);
b3c2cc2b 1507 if (evlist__combined_sample_type(session->evlist) & PERF_SAMPLE_STACK_USER)
10ccbc1c 1508 has_br_stack = false;
efad1415 1509
57b5de46 1510 setup_forced_leader(&report, session->evlist);
ad52b8cb 1511
9d2dc632 1512 if (symbol_conf.group_sort_idx && evlist__nr_groups(session->evlist) == 0) {
429a5f9d
JY
1513 parse_options_usage(NULL, options, "group-sort-idx", 0);
1514 ret = -EINVAL;
1515 goto error;
1516 }
1517
ec90e42c 1518 if (itrace_synth_opts.last_branch || itrace_synth_opts.add_last_branch)
fb9fab66
AH
1519 has_br_stack = true;
1520
f9a7be7c
JY
1521 if (has_br_stack && branch_call_mode)
1522 symbol_conf.show_branchflag_count = true;
1523
2d78b189
JY
1524 memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat));
1525
fa94c36c
AK
1526 /*
1527 * Branch mode is a tristate:
1528 * -1 means default, so decide based on the file having branch data.
1529 * 0/1 means the user chose a mode.
1530 */
1531 if (((branch_mode == -1 && has_br_stack) || branch_mode == 1) &&
fefd2d96 1532 !branch_call_mode) {
55369fc1 1533 sort__mode = SORT_MODE__BRANCH;
793aaaab
NK
1534 symbol_conf.cumulate_callchain = false;
1535 }
fa94c36c 1536 if (branch_call_mode) {
09a6a1b0 1537 callchain_param.key = CCKEY_ADDRESS;
6fa9c3e7 1538 callchain_param.branch_callstack = true;
fa94c36c
AK
1539 symbol_conf.use_callchain = true;
1540 callchain_register_param(&callchain_param);
1541 if (sort_order == NULL)
1542 sort_order = "srcline,symbol,dso";
1543 }
993ac88d 1544
f4f7e28d 1545 if (report.mem_mode) {
55369fc1 1546 if (sort__mode == SORT_MODE__BRANCH) {
a4210141 1547 pr_err("branch and mem mode incompatible\n");
f4f7e28d
SE
1548 goto error;
1549 }
afab87b9 1550 sort__mode = SORT_MODE__MEMORY;
793aaaab 1551 symbol_conf.cumulate_callchain = false;
f4f7e28d 1552 }
a68c2c58 1553
4251446d
NK
1554 if (symbol_conf.report_hierarchy) {
1555 /* disable incompatible options */
4251446d
NK
1556 symbol_conf.cumulate_callchain = false;
1557
1558 if (field_order) {
1559 pr_err("Error: --hierarchy and --fields options cannot be used together\n");
1560 parse_options_usage(report_usage, options, "F", 1);
1561 parse_options_usage(NULL, options, "hierarchy", 0);
1562 goto error;
1563 }
1564
52225036 1565 perf_hpp_list.need_collapse = true;
4251446d
NK
1566 }
1567
712d36db
SS
1568 if (report.use_stdio)
1569 use_browser = 0;
3402ae0a 1570#ifdef HAVE_SLANG_SUPPORT
712d36db
SS
1571 else if (report.use_tui)
1572 use_browser = 1;
3402ae0a 1573#endif
557cc18e 1574#ifdef HAVE_GTK2_SUPPORT
712d36db
SS
1575 else if (report.use_gtk)
1576 use_browser = 2;
557cc18e 1577#endif
712d36db 1578
b138f42e
NK
1579 /* Force tty output for header output and per-thread stat. */
1580 if (report.header || report.header_only || report.show_threads)
5cfe2c82 1581 use_browser = 0;
114f709e
DCC
1582 if (report.header || report.header_only)
1583 report.tool.show_feat_hdr = SHOW_FEAT_HEADER;
1584 if (report.show_full_info)
1585 report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
930f8b34 1586 if (report.stats_mode || report.tasks_mode)
a4a4d0a7 1587 use_browser = 0;
930f8b34 1588 if (report.stats_mode && report.tasks_mode) {
6439d7d1 1589 pr_err("Error: --tasks and --mmaps can't be used together with --stats\n");
930f8b34
JO
1590 goto error;
1591 }
5cfe2c82 1592
6f7164fa
JY
1593 if (report.total_cycles_mode) {
1594 if (sort__mode != SORT_MODE__BRANCH)
1595 report.total_cycles_mode = false;
7fa46cbf 1596 else
848a5e50 1597 sort_order = NULL;
6f7164fa
JY
1598 }
1599
4bceffbc
NK
1600 if (strcmp(input_name, "-") != 0)
1601 setup_browser(true);
22af969e 1602 else
4bceffbc 1603 use_browser = 0;
4bceffbc 1604
ec6ae74f
JY
1605 if (sort_order && strstr(sort_order, "ipc")) {
1606 parse_options_usage(report_usage, options, "s", 1);
1607 goto error;
1608 }
1609
1610 if (sort_order && strstr(sort_order, "symbol")) {
1611 if (sort__mode == SORT_MODE__BRANCH) {
1612 snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
1613 sort_order, "ipc_lbr");
1614 report.symbol_ipc = true;
1615 } else {
1616 snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
1617 sort_order, "ipc_null");
1618 }
1619
1620 sort_order = sort_tmp;
1621 }
1622
5e3b810a 1623 if ((last_key != K_SWITCH_INPUT_DATA && last_key != K_RELOAD) &&
0feba17b 1624 (setup_sorting(session->evlist) < 0)) {
9887804d
JO
1625 if (sort_order)
1626 parse_options_usage(report_usage, options, "s", 1);
1627 if (field_order)
1628 parse_options_usage(sort_order ? NULL : report_usage,
1629 options, "F", 1);
1630 goto error;
1631 }
1632
27fafab5 1633 if ((report.header || report.header_only) && !quiet) {
5cfe2c82
JO
1634 perf_session__fprintf_info(session, stdout,
1635 report.show_full_info);
07a716ff 1636 if (report.header_only) {
03de8656
NK
1637 if (data.is_pipe) {
1638 /*
1639 * we need to process first few records
1640 * which contains PERF_RECORD_HEADER_FEATURE.
1641 */
1642 perf_session__process_events(session);
1643 }
07a716ff
TS
1644 ret = 0;
1645 goto error;
1646 }
930f8b34
JO
1647 } else if (use_browser == 0 && !quiet &&
1648 !report.stats_mode && !report.tasks_mode) {
5cfe2c82
JO
1649 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
1650 stdout);
1651 }
1652
ef7b93a1 1653 /*
6692c262 1654 * Only in the TUI browser we are doing integrated annotation,
ef7b93a1
ACM
1655 * so don't allocate extra space that won't be used in the stdio
1656 * implementation.
1657 */
6f7164fa
JY
1658 if (ui__has_annotation() || report.symbol_ipc ||
1659 report.total_cycles_mode) {
b01141f4
ACM
1660 ret = symbol__annotation_init();
1661 if (ret < 0)
1662 goto error;
80d50cae
ACM
1663 /*
1664 * For searching by name on the "Browse map details".
1665 * providing it only in verbose mode not to bloat too
1666 * much struct symbol.
1667 */
bb963e16 1668 if (verbose > 0) {
80d50cae
ACM
1669 /*
1670 * XXX: Need to provide a less kludgy way to ask for
1671 * more space per symbol, the u32 is for the index on
1672 * the ui browser.
1673 * See symbol__browser_index.
1674 */
1675 symbol_conf.priv_size += sizeof(u32);
1676 symbol_conf.sort_by_name = true;
1677 }
7384083b 1678 annotation_config__init(&report.annotation_opts);
80d50cae 1679 }
655000e7 1680
0a7e6d1b 1681 if (symbol__init(&session->header.env) < 0)
993ac88d 1682 goto error;
53cb8bc2 1683
284c4e18
JY
1684 if (report.time_str) {
1685 ret = perf_time__parse_for_ranges(report.time_str, session,
1686 &report.ptime_range,
1687 &report.range_size,
1688 &report.range_num);
1689 if (ret < 0)
0a3cc3ae 1690 goto error;
4885c90c
AH
1691
1692 itrace_synth_opts__set_time_range(&itrace_synth_opts,
1693 report.ptime_range,
1694 report.range_num);
46690a80
DA
1695 }
1696
378ef0f5 1697#ifdef HAVE_LIBTRACEEVENT
ea85ab24 1698 if (session->tevent.pevent &&
ece2a4f4
TSV
1699 tep_set_function_resolver(session->tevent.pevent,
1700 machine__resolve_kernel_addr,
1701 &session->machines.host) < 0) {
ea85ab24
WY
1702 pr_err("%s: failed to set libtraceevent function resolver\n",
1703 __func__);
1704 return -1;
1705 }
378ef0f5 1706#endif
08e71542 1707 sort__setup_elide(stdout);
25903407 1708
993ac88d 1709 ret = __cmd_report(&report);
5e3b810a 1710 if (ret == K_SWITCH_INPUT_DATA || ret == K_RELOAD) {
ad0de097 1711 perf_session__delete(session);
0feba17b 1712 last_key = K_SWITCH_INPUT_DATA;
ad0de097
FT
1713 goto repeat;
1714 } else
1715 ret = 0;
1716
993ac88d 1717error:
4885c90c
AH
1718 if (report.ptime_range) {
1719 itrace_synth_opts__clear_time_range(&itrace_synth_opts);
284c4e18 1720 zfree(&report.ptime_range);
4885c90c 1721 }
6f7164fa 1722
cca0cc76
JY
1723 if (report.block_reports) {
1724 block_info__free_report(report.block_reports,
1725 report.nr_block_reports);
1726 report.block_reports = NULL;
1727 }
6f7164fa 1728
cb62c6f1 1729 zstd_fini(&(session->zstd_data));
993ac88d 1730 perf_session__delete(session);
a37338aa 1731exit:
217b7d41 1732 annotation_options__exit(&report.annotation_opts);
a37338aa
RM
1733 free(sort_order_help);
1734 free(field_order_help);
993ac88d 1735 return ret;
53cb8bc2 1736}