builtin-report.c 41.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4 5 6 7 8
/*
 * builtin-report.c
 *
 * Builtin report command: Analyze the perf.data input file,
 * look up and read DSOs and symbol information and display
 * a histogram of results, along various sorting keys.
 */
9
#include "builtin.h"
10

11
#include "util/config.h"
12

13
#include "util/annotate.h"
14
#include "util/color.h"
15
#include "util/dso.h"
16
#include <linux/list.h>
17
#include <linux/rbtree.h>
18
#include <linux/err.h>
19
#include <linux/zalloc.h>
20
#include "util/map.h"
21
#include "util/symbol.h"
22 23 24
#include "util/map_symbol.h"
#include "util/mem-events.h"
#include "util/branch.h"
25
#include "util/callchain.h"
26
#include "util/values.h"
27

28
#include "perf.h"
29
#include "util/debug.h"
30 31
#include "util/evlist.h"
#include "util/evsel.h"
32
#include "util/evswitch.h"
33
#include "util/header.h"
34
#include "util/session.h"
35
#include "util/srcline.h"
36
#include "util/tool.h"
37

38
#include <subcmd/parse-options.h>
39
#include <subcmd/exec-cmd.h>
40 41
#include "util/parse-events.h"

42
#include "util/thread.h"
43
#include "util/sort.h"
44
#include "util/hist.h"
45
#include "util/data.h"
46
#include "arch/common.h"
47
#include "util/time-utils.h"
48
#include "util/auxtrace.h"
49
#include "util/units.h"
50
#include "util/branch.h"
51
#include "util/util.h" // perf_tip()
52
#include "ui/ui.h"
53
#include "ui/progress.h"
54

55
#include <dlfcn.h>
56
#include <errno.h>
57
#include <inttypes.h>
58
#include <regex.h>
59
#include <linux/ctype.h>
60
#include <signal.h>
61
#include <linux/bitmap.h>
62
#include <linux/string.h>
63
#include <linux/stringify.h>
A
Andi Kleen 已提交
64
#include <linux/time64.h>
65 66 67
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
68
#include <linux/mman.h>
69

70
struct report {
71
	struct perf_tool	tool;
72
	struct perf_session	*session;
73
	struct evswitch		evswitch;
74
	bool			use_tui, use_gtk, use_stdio;
75 76 77
	bool			show_full_info;
	bool			show_threads;
	bool			inverted_callchain;
78
	bool			mem_mode;
79
	bool			stats_mode;
80
	bool			tasks_mode;
81
	bool			mmaps_mode;
82 83
	bool			header;
	bool			header_only;
84
	bool			nonany_branch_mode;
85
	bool			group_set;
86
	int			max_stack;
87
	struct perf_read_values	show_threads_values;
88
	struct annotation_options annotation_opts;
89 90
	const char		*pretty_printing_style;
	const char		*cpu_list;
91
	const char		*symbol_filter_str;
92
	const char		*time_str;
93 94
	struct perf_time_interval *ptime_range;
	int			range_size;
95
	int			range_num;
96
	float			min_percent;
97
	u64			nr_entries;
98
	u64			queue_size;
99
	int			socket_filter;
100
	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
101
	struct branch_type_stat	brtype_stat;
102
	bool			symbol_ipc;
103
};
104

105
static int report__config(const char *var, const char *value, void *cb)
106
{
107 108
	struct report *rep = cb;

109 110 111 112
	if (!strcmp(var, "report.group")) {
		symbol_conf.event_group = perf_config_bool(var, value);
		return 0;
	}
113
	if (!strcmp(var, "report.percent-limit")) {
114 115 116 117
		double pcnt = strtof(value, NULL);

		rep->min_percent = pcnt;
		callchain_param.min_percent = pcnt;
118 119
		return 0;
	}
120 121 122 123
	if (!strcmp(var, "report.children")) {
		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
		return 0;
	}
124 125 126
	if (!strcmp(var, "report.queue-size"))
		return perf_config_u64(&rep->queue_size, var, value);

127 128 129 130
	if (!strcmp(var, "report.sort_order")) {
		default_sort_order = strdup(value);
		return 0;
	}
131

132
	return 0;
133 134
}

135 136 137 138 139 140 141
static int hist_iter__report_callback(struct hist_entry_iter *iter,
				      struct addr_location *al, bool single,
				      void *arg)
{
	int err = 0;
	struct report *rep = arg;
	struct hist_entry *he = iter->he;
142
	struct evsel *evsel = iter->evsel;
143
	struct perf_sample *sample = iter->sample;
144 145 146
	struct mem_info *mi;
	struct branch_info *bi;

147
	if (!ui__has_annotation() && !rep->symbol_ipc)
148 149 150 151
		return 0;

	if (sort__mode == SORT_MODE__BRANCH) {
		bi = he->branch_info;
152
		err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
153 154 155
		if (err)
			goto out;

156
		err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
157 158 159

	} else if (rep->mem_mode) {
		mi = he->mem_info;
160
		err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
161 162 163
		if (err)
			goto out;

164
		err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
165 166 167

	} else if (symbol_conf.cumulate_callchain) {
		if (single)
168
			err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
169
	} else {
170
		err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
171 172 173 174
	}

out:
	return err;
175 176
}

177 178 179 180 181 182 183 184
static int hist_iter__branch_callback(struct hist_entry_iter *iter,
				      struct addr_location *al __maybe_unused,
				      bool single __maybe_unused,
				      void *arg)
{
	struct hist_entry *he = iter->he;
	struct report *rep = arg;
	struct branch_info *bi;
185
	struct perf_sample *sample = iter->sample;
186
	struct evsel *evsel = iter->evsel;
187 188
	int err;

189
	if (!ui__has_annotation() && !rep->symbol_ipc)
190 191
		return 0;

192
	bi = he->branch_info;
193
	err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
194 195 196
	if (err)
		goto out;

197
	err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
198

199 200 201
	branch_type_count(&rep->brtype_stat, &bi->flags,
			  bi->from.addr, bi->to.addr);

202 203
out:
	return err;
204 205
}

206
static void setup_forced_leader(struct report *report,
207
				struct evlist *evlist)
208
{
209 210
	if (report->group_set)
		perf_evlist__force_leader(evlist);
211 212
}

213 214
static int process_feature_event(struct perf_session *session,
				 union perf_event *event)
215
{
216
	struct report *rep = container_of(session->tool, struct report, tool);
217 218

	if (event->feat.feat_id < HEADER_LAST_FEATURE)
219
		return perf_event__process_feature(session, event);
220 221

	if (event->feat.feat_id != HEADER_LAST_FEATURE) {
222
		pr_err("failed: wrong feature ID: %" PRI_lu64 "\n",
223 224 225 226 227
		       event->feat.feat_id);
		return -1;
	}

	/*
228 229
	 * (feat_id = HEADER_LAST_FEATURE) is the end marker which
	 * means all features are received, now we can force the
230 231 232 233 234 235
	 * group if needed.
	 */
	setup_forced_leader(rep, session->evlist);
	return 0;
}

236
static int process_sample_event(struct perf_tool *tool,
237
				union perf_event *event,
238
				struct perf_sample *sample,
239
				struct evsel *evsel,
240
				struct machine *machine)
241
{
242
	struct report *rep = container_of(tool, struct report, tool);
243
	struct addr_location al;
244
	struct hist_entry_iter iter = {
245 246
		.evsel 			= evsel,
		.sample 		= sample,
247
		.hide_unresolved 	= symbol_conf.hide_unresolved,
248
		.add_entry_cb 		= hist_iter__report_callback,
249
	};
250
	int ret = 0;
251

252 253
	if (perf_time__ranges_skip_sample(rep->ptime_range, rep->range_num,
					  sample->time)) {
254
		return 0;
255
	}
256

257 258 259
	if (evswitch__discard(&rep->evswitch, evsel))
		return 0;

260
	if (machine__resolve(machine, &al, sample) < 0) {
261 262
		pr_debug("problem processing %d event, skipping it.\n",
			 event->header.type);
263 264
		return -1;
	}
265

266
	if (symbol_conf.hide_unresolved && al.sym == NULL)
267
		goto out_put;
268

269
	if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
270
		goto out_put;
271

272 273 274 275 276 277 278
	if (sort__mode == SORT_MODE__BRANCH) {
		/*
		 * A non-synthesized event might not have a branch stack if
		 * branch stacks have been synthesized (using itrace options).
		 */
		if (!sample->branch_stack)
			goto out_put;
279 280

		iter.add_entry_cb = hist_iter__branch_callback;
281
		iter.ops = &hist_iter_branch;
282
	} else if (rep->mem_mode) {
283
		iter.ops = &hist_iter_mem;
284
	} else if (symbol_conf.cumulate_callchain) {
285
		iter.ops = &hist_iter_cumulative;
286
	} else {
287
		iter.ops = &hist_iter_normal;
288
	}
289 290 291 292

	if (al.map != NULL)
		al.map->dso->hit = 1;

293 294 295 296 297
	if (ui__has_annotation() || rep->symbol_ipc) {
		hist__account_cycles(sample->branch_stack, &al, sample,
				     rep->nonany_branch_mode);
	}

298
	ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
299 300
	if (ret < 0)
		pr_debug("problem adding hist entry, skipping event\n");
301 302
out_put:
	addr_location__put(&al);
303
	return ret;
304
}
I
Ingo Molnar 已提交
305

306
static int process_read_event(struct perf_tool *tool,
307
			      union perf_event *event,
308
			      struct perf_sample *sample __maybe_unused,
309
			      struct evsel *evsel,
310
			      struct machine *machine __maybe_unused)
311
{
312
	struct report *rep = container_of(tool, struct report, tool);
313

314
	if (rep->show_threads) {
315
		const char *name = perf_evsel__name(evsel);
316
		int err = perf_read_values_add_value(&rep->show_threads_values,
317
					   event->read.pid, event->read.tid,
318
					   evsel->idx,
319 320
					   name,
					   event->read.value);
321 322 323

		if (err)
			return err;
324 325
	}

326 327 328
	return 0;
}

329
/* For pipe mode, sample_type is not currently set */
330
static int report__setup_sample_type(struct report *rep)
331
{
332 333
	struct perf_session *session = rep->session;
	u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
334
	bool is_pipe = perf_data__is_pipe(session->data);
335

336 337 338 339 340 341
	if (session->itrace_synth_opts->callchain ||
	    (!is_pipe &&
	     perf_header__has_feat(&session->header, HEADER_AUXTRACE) &&
	     !session->itrace_synth_opts->set))
		sample_type |= PERF_SAMPLE_CALLCHAIN;

342 343 344
	if (session->itrace_synth_opts->last_branch)
		sample_type |= PERF_SAMPLE_BRANCH_STACK;

345
	if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
346
		if (perf_hpp_list.parent) {
347
			ui__error("Selected --sort parent, but no "
348 349
				    "callchain data. Did you call "
				    "'perf record' without -g?\n");
350
			return -EINVAL;
351
		}
352 353 354 355 356
		if (symbol_conf.use_callchain &&
			!symbol_conf.show_branchflag_count) {
			ui__error("Selected -g or --branch-history.\n"
				  "But no callchain or branch data.\n"
				  "Did you call 'perf record' without -g or -b?\n");
357
			return -1;
358
		}
359
	} else if (!callchain_param.enabled &&
360
		   callchain_param.mode != CHAIN_NONE &&
361
		   !symbol_conf.use_callchain) {
362
			symbol_conf.use_callchain = true;
363
			if (callchain_register_param(&callchain_param) < 0) {
364
				ui__error("Can't register callchain params.\n");
365
				return -EINVAL;
366
			}
367 368
	}

369 370 371 372 373 374 375 376
	if (symbol_conf.cumulate_callchain) {
		/* Silently ignore if callchain is missing */
		if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
			symbol_conf.cumulate_callchain = false;
			perf_hpp__cancel_cumulate();
		}
	}

377
	if (sort__mode == SORT_MODE__BRANCH) {
378
		if (!is_pipe &&
379
		    !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
380 381
			ui__error("Selected -b but no branch data. "
				  "Did you call perf record without -b?\n");
382 383 384 385
			return -1;
		}
	}

386 387
	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
		if ((sample_type & PERF_SAMPLE_REGS_USER) &&
388
		    (sample_type & PERF_SAMPLE_STACK_USER)) {
389
			callchain_param.record_mode = CALLCHAIN_DWARF;
390 391
			dwarf_callchain_users = true;
		} else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
392
			callchain_param.record_mode = CALLCHAIN_LBR;
393 394 395
		else
			callchain_param.record_mode = CALLCHAIN_FP;
	}
396 397 398 399 400 401

	/* ??? handle more cases than just ANY? */
	if (!(perf_evlist__combined_branch_type(session->evlist) &
				PERF_SAMPLE_BRANCH_ANY))
		rep->nonany_branch_mode = true;

402 403
	return 0;
}
404

405
static void sig_handler(int sig __maybe_unused)
406 407 408 409
{
	session_done = 1;
}

410
static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
411 412 413 414
					      const char *evname, FILE *fp)
{
	size_t ret;
	char unit;
415 416
	unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
	u64 nr_events = hists->stats.total_period;
417
	struct evsel *evsel = hists_to_evsel(hists);
418 419
	char buf[512];
	size_t size = sizeof(buf);
420
	int socked_id = hists->socket_filter;
421

422 423 424
	if (quiet)
		return 0;

425 426 427 428 429
	if (symbol_conf.filter_relative) {
		nr_samples = hists->stats.nr_non_filtered_samples;
		nr_events = hists->stats.total_non_filtered_period;
	}

430
	if (perf_evsel__is_group_event(evsel)) {
431
		struct evsel *pos;
432 433 434 435 436

		perf_evsel__group_desc(evsel, buf, size);
		evname = buf;

		for_each_group_member(pos, evsel) {
437 438
			const struct hists *pos_hists = evsel__hists(pos);

439
			if (symbol_conf.filter_relative) {
440 441
				nr_samples += pos_hists->stats.nr_non_filtered_samples;
				nr_events += pos_hists->stats.total_non_filtered_period;
442
			} else {
443 444
				nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
				nr_events += pos_hists->stats.total_period;
445
			}
446 447
		}
	}
448

449 450
	nr_samples = convert_unit(nr_samples, &unit);
	ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
451 452
	if (evname != NULL) {
		ret += fprintf(fp, " of event%s '%s'",
453
			       evsel->core.nr_members > 1 ? "s" : "", evname);
454
	}
455

456 457 458
	if (rep->time_str)
		ret += fprintf(fp, " (time slices: %s)", rep->time_str);

459 460 461 462 463
	if (symbol_conf.show_ref_callgraph &&
	    strstr(evname, "call-graph=no")) {
		ret += fprintf(fp, ", show reference callgraph");
	}

464 465
	if (rep->mem_mode) {
		ret += fprintf(fp, "\n# Total weight : %" PRIu64, nr_events);
466
		ret += fprintf(fp, "\n# Sort order   : %s", sort_order ? : default_mem_sort_order);
467 468
	} else
		ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
469

470 471
	if (socked_id > -1)
		ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
472

473 474 475
	return ret + fprintf(fp, "\n#\n");
}

476
static int perf_evlist__tty_browse_hists(struct evlist *evlist,
477
					 struct report *rep,
478
					 const char *help)
479
{
480
	struct evsel *pos;
481

482 483 484 485 486
	if (!quiet) {
		fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
			evlist->stats.total_lost_samples);
	}

487
	evlist__for_each_entry(evlist, pos) {
488
		struct hists *hists = evsel__hists(pos);
489
		const char *evname = perf_evsel__name(pos);
490

491 492 493 494
		if (symbol_conf.event_group &&
		    !perf_evsel__is_group_leader(pos))
			continue;

495
		hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
496
		hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
497 498
			       !(symbol_conf.use_callchain ||
			         symbol_conf.show_branchflag_count));
499 500 501
		fprintf(stdout, "\n\n");
	}

502
	if (!quiet)
503 504
		fprintf(stdout, "#\n# (%s)\n#\n", help);

505 506 507 508 509
	if (rep->show_threads) {
		bool style = !strcmp(rep->pretty_printing_style, "raw");
		perf_read_values_display(stdout, &rep->show_threads_values,
					 style);
		perf_read_values_destroy(&rep->show_threads_values);
510 511
	}

512 513 514
	if (sort__mode == SORT_MODE__BRANCH)
		branch_type_stat_display(stdout, &rep->brtype_stat);

515 516 517
	return 0;
}

518 519
static void report__warn_kptr_restrict(const struct report *rep)
{
520
	struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
521
	struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
522

523 524 525
	if (perf_evlist__exclude_kernel(rep->session->evlist))
		return;

526 527 528 529 530 531 532 533
	if (kernel_map == NULL ||
	    (kernel_map->dso->hit &&
	     (kernel_kmap->ref_reloc_sym == NULL ||
	      kernel_kmap->ref_reloc_sym->addr == 0))) {
		const char *desc =
		    "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
		    "can't be resolved.";

534 535 536
		if (kernel_map && map__has_symbols(kernel_map)) {
			desc = "If some relocation was applied (e.g. "
			       "kexec) symbols may be misresolved.";
537 538 539 540 541 542 543 544 545 546
		}

		ui__warning(
"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
"Samples in kernel modules can't be resolved as well.\n\n",
		desc);
	}
}

547 548
static int report__gtk_browse_hists(struct report *rep, const char *help)
{
549
	int (*hist_browser)(struct evlist *evlist, const char *help,
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
			    struct hist_browser_timer *timer, float min_pcnt);

	hist_browser = dlsym(perf_gtk_handle, "perf_evlist__gtk_browse_hists");

	if (hist_browser == NULL) {
		ui__error("GTK browser not found!\n");
		return -1;
	}

	return hist_browser(rep->session->evlist, help, NULL, rep->min_percent);
}

static int report__browse_hists(struct report *rep)
{
	int ret;
	struct perf_session *session = rep->session;
566
	struct evlist *evlist = session->evlist;
567 568 569 570 571 572 573 574
	const char *help = perf_tip(system_path(TIPDIR));

	if (help == NULL) {
		/* fallback for people who don't install perf ;-) */
		help = perf_tip(DOCDIR);
		if (help == NULL)
			help = "Cannot load tips.txt file, please install perf!";
	}
575 576 577 578 579

	switch (use_browser) {
	case 1:
		ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
						    rep->min_percent,
580
						    &session->header.env,
581
						    true, &rep->annotation_opts);
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
		/*
		 * Usually "ret" is the last pressed key, and we only
		 * care if the key notifies us to switch data file.
		 */
		if (ret != K_SWITCH_INPUT_DATA)
			ret = 0;
		break;
	case 2:
		ret = report__gtk_browse_hists(rep, help);
		break;
	default:
		ret = perf_evlist__tty_browse_hists(evlist, rep, help);
		break;
	}

	return ret;
}

600
static int report__collapse_hists(struct report *rep)
601 602
{
	struct ui_progress prog;
603
	struct evsel *pos;
604
	int ret = 0;
605

606
	ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
607

608
	evlist__for_each_entry(rep->session->evlist, pos) {
609
		struct hists *hists = evsel__hists(pos);
610 611 612 613

		if (pos->idx == 0)
			hists->symbol_filter_str = rep->symbol_filter_str;

614 615
		hists->socket_filter = rep->socket_filter;

616 617 618
		ret = hists__collapse_resort(hists, &prog);
		if (ret < 0)
			break;
619 620 621 622

		/* Non-group events are considered as leader */
		if (symbol_conf.event_group &&
		    !perf_evsel__is_group_leader(pos)) {
623
			struct hists *leader_hists = evsel__hists(pos->leader);
624 625 626 627 628 629 630

			hists__match(leader_hists, hists);
			hists__link(leader_hists, hists);
		}
	}

	ui_progress__finish();
631
	return ret;
632 633
}

634 635 636 637 638 639
static int hists__resort_cb(struct hist_entry *he, void *arg)
{
	struct report *rep = arg;
	struct symbol *sym = he->ms.sym;

	if (rep->symbol_ipc && sym && !sym->annotate2) {
640
		struct evsel *evsel = hists_to_evsel(he->hists);
641 642 643 644 645 646 647 648

		symbol__annotate2(sym, he->ms.map, evsel,
				  &annotation__default_options, NULL);
	}

	return 0;
}

649 650 651
static void report__output_resort(struct report *rep)
{
	struct ui_progress prog;
652
	struct evsel *pos;
653 654 655

	ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");

656 657 658 659
	evlist__for_each_entry(rep->session->evlist, pos) {
		perf_evsel__output_resort_cb(pos, &prog,
					     hists__resort_cb, rep);
	}
660 661 662 663

	ui_progress__finish();
}

664 665 666 667 668 669 670 671 672 673 674 675 676 677
static void stats_setup(struct report *rep)
{
	memset(&rep->tool, 0, sizeof(rep->tool));
	rep->tool.no_warn = true;
}

static int stats_print(struct report *rep)
{
	struct perf_session *session = rep->session;

	perf_session__fprintf_nr_events(session, stdout);
	return 0;
}

678 679 680
static void tasks_setup(struct report *rep)
{
	memset(&rep->tool, 0, sizeof(rep->tool));
681
	rep->tool.ordered_events = true;
682 683 684 685
	if (rep->mmaps_mode) {
		rep->tool.mmap = perf_event__process_mmap;
		rep->tool.mmap2 = perf_event__process_mmap2;
	}
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
	rep->tool.comm = perf_event__process_comm;
	rep->tool.exit = perf_event__process_exit;
	rep->tool.fork = perf_event__process_fork;
	rep->tool.no_warn = true;
}

struct task {
	struct thread		*thread;
	struct list_head	 list;
	struct list_head	 children;
};

static struct task *tasks_list(struct task *task, struct machine *machine)
{
	struct thread *parent_thread, *thread = task->thread;
	struct task   *parent_task;

	/* Already listed. */
	if (!list_empty(&task->list))
		return NULL;

	/* Last one in the chain. */
	if (thread->ppid == -1)
		return task;

	parent_thread = machine__find_thread(machine, -1, thread->ppid);
	if (!parent_thread)
		return ERR_PTR(-ENOENT);

	parent_task = thread__priv(parent_thread);
	list_add_tail(&task->list, &parent_task->children);
	return tasks_list(parent_task, machine);
}

720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
{
	size_t printed = 0;
	struct rb_node *nd;

	for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
		struct map *map = rb_entry(nd, struct map, rb_node);

		printed += fprintf(fp, "%*s  %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
				   indent, "", map->start, map->end,
				   map->prot & PROT_READ ? 'r' : '-',
				   map->prot & PROT_WRITE ? 'w' : '-',
				   map->prot & PROT_EXEC ? 'x' : '-',
				   map->flags & MAP_SHARED ? 's' : 'p',
				   map->pgoff,
				   map->ino, map->dso->name);
	}

	return printed;
}

static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp)
{
743
	return maps__fprintf_task(&mg->maps, indent, fp);
744 745
}

746 747 748 749
static void task__print_level(struct task *task, FILE *fp, int level)
{
	struct thread *thread = task->thread;
	struct task *child;
750 751 752 753 754
	int comm_indent = fprintf(fp, "  %8d %8d %8d |%*s",
				  thread->pid_, thread->tid, thread->ppid,
				  level, "");

	fprintf(fp, "%s\n", thread__comm_str(thread));
755

756
	map_groups__fprintf_task(thread->mg, comm_indent, fp);
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788

	if (!list_empty(&task->children)) {
		list_for_each_entry(child, &task->children, list)
			task__print_level(child, fp, level + 1);
	}
}

static int tasks_print(struct report *rep, FILE *fp)
{
	struct perf_session *session = rep->session;
	struct machine      *machine = &session->machines.host;
	struct task *tasks, *task;
	unsigned int nr = 0, itask = 0, i;
	struct rb_node *nd;
	LIST_HEAD(list);

	/*
	 * No locking needed while accessing machine->threads,
	 * because --tasks is single threaded command.
	 */

	/* Count all the threads. */
	for (i = 0; i < THREADS__TABLE_SIZE; i++)
		nr += machine->threads[i].nr;

	tasks = malloc(sizeof(*tasks) * nr);
	if (!tasks)
		return -ENOMEM;

	for (i = 0; i < THREADS__TABLE_SIZE; i++) {
		struct threads *threads = &machine->threads[i];

789 790
		for (nd = rb_first_cached(&threads->entries); nd;
		     nd = rb_next(nd)) {
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
			task = tasks + itask++;

			task->thread = rb_entry(nd, struct thread, rb_node);
			INIT_LIST_HEAD(&task->children);
			INIT_LIST_HEAD(&task->list);
			thread__set_priv(task->thread, task);
		}
	}

	/*
	 * Iterate every task down to the unprocessed parent
	 * and link all in task children list. Task with no
	 * parent is added into 'list'.
	 */
	for (itask = 0; itask < nr; itask++) {
		task = tasks + itask;

		if (!list_empty(&task->list))
			continue;

		task = tasks_list(task, machine);
		if (IS_ERR(task)) {
			pr_err("Error: failed to process tasks\n");
			free(tasks);
			return PTR_ERR(task);
		}

		if (task)
			list_add_tail(&task->list, &list);
	}

	fprintf(fp, "# %8s %8s %8s  %s\n", "pid", "tid", "ppid", "comm");

	list_for_each_entry(task, &list, list)
		task__print_level(task, fp, 0);

	free(tasks);
	return 0;
}

831
static int __cmd_report(struct report *rep)
832
{
833
	int ret;
834
	struct perf_session *session = rep->session;
835
	struct evsel *pos;
836
	struct perf_data *data = session->data;
837

838 839
	signal(SIGINT, sig_handler);

840 841 842
	if (rep->cpu_list) {
		ret = perf_session__cpu_bitmap(session, rep->cpu_list,
					       rep->cpu_bitmap);
843 844
		if (ret) {
			ui__error("failed to set cpu bitmap\n");
845
			return ret;
846
		}
847
		session->itrace_synth_opts->cpu_bitmap = rep->cpu_bitmap;
848 849
	}

850 851 852 853 854
	if (rep->show_threads) {
		ret = perf_read_values_init(&rep->show_threads_values);
		if (ret)
			return ret;
	}
855

856
	ret = report__setup_sample_type(rep);
857 858
	if (ret) {
		/* report__setup_sample_type() already showed error message */
859
		return ret;
860
	}
861

862 863 864
	if (rep->stats_mode)
		stats_setup(rep);

865 866 867
	if (rep->tasks_mode)
		tasks_setup(rep);

868
	ret = perf_session__process_events(session);
869 870
	if (ret) {
		ui__error("failed to process sample\n");
871
		return ret;
872
	}
873

874 875 876
	if (rep->stats_mode)
		return stats_print(rep);

877 878 879
	if (rep->tasks_mode)
		return tasks_print(rep, stdout);

880
	report__warn_kptr_restrict(rep);
881

882
	evlist__for_each_entry(session->evlist, pos)
883 884
		rep->nr_entries += evsel__hists(pos)->nr_entries;

885 886 887
	if (use_browser == 0) {
		if (verbose > 3)
			perf_session__fprintf(session, stdout);
888

889 890
		if (verbose > 2)
			perf_session__fprintf_dsos(session, stdout);
891

892 893
		if (dump_trace) {
			perf_session__fprintf_nr_events(session, stdout);
894
			perf_evlist__fprintf_nr_events(session->evlist, stdout);
895 896
			return 0;
		}
897 898
	}

899 900 901 902 903
	ret = report__collapse_hists(rep);
	if (ret) {
		ui__error("failed to process hist entry\n");
		return ret;
	}
904

905 906 907
	if (session_done())
		return 0;

908 909 910 911 912
	/*
	 * recalculate number of entries after collapsing since it
	 * might be changed during the collapse phase.
	 */
	rep->nr_entries = 0;
913
	evlist__for_each_entry(session->evlist, pos)
914 915
		rep->nr_entries += evsel__hists(pos)->nr_entries;

916
	if (rep->nr_entries == 0) {
J
Jiri Olsa 已提交
917
		ui__error("The %s data has no samples!\n", data->path);
918
		return 0;
919 920
	}

921
	report__output_resort(rep);
922

923
	return report__browse_hists(rep);
924 925
}

926
static int
927
report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
928
{
929
	struct callchain_param *callchain = opt->value;
930

931
	callchain->enabled = !unset;
932 933 934 935
	/*
	 * --no-call-graph
	 */
	if (unset) {
936 937
		symbol_conf.use_callchain = false;
		callchain->mode = CHAIN_NONE;
938 939 940
		return 0;
	}

941
	return parse_callchain_report_opt(arg);
942 943
}

A
Andi Kleen 已提交
944 945 946 947 948 949 950 951 952 953 954 955 956 957
static int
parse_time_quantum(const struct option *opt, const char *arg,
		   int unset __maybe_unused)
{
	unsigned long *time_q = opt->value;
	char *end;

	*time_q = strtoul(arg, &end, 0);
	if (end == arg)
		goto parse_err;
	if (*time_q == 0) {
		pr_err("time quantum cannot be 0");
		return -1;
	}
958
	end = skip_spaces(end);
A
Andi Kleen 已提交
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
	if (*end == 0)
		return 0;
	if (!strcmp(end, "s")) {
		*time_q *= NSEC_PER_SEC;
		return 0;
	}
	if (!strcmp(end, "ms")) {
		*time_q *= NSEC_PER_MSEC;
		return 0;
	}
	if (!strcmp(end, "us")) {
		*time_q *= NSEC_PER_USEC;
		return 0;
	}
	if (!strcmp(end, "ns"))
		return 0;
parse_err:
	pr_err("Cannot parse time quantum `%s'\n", arg);
	return -1;
}

980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
int
report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
				const char *arg, int unset __maybe_unused)
{
	if (arg) {
		int err = regcomp(&ignore_callees_regex, arg, REG_EXTENDED);
		if (err) {
			char buf[BUFSIZ];
			regerror(err, &ignore_callees_regex, buf, sizeof(buf));
			pr_err("Invalid --ignore-callees regex: %s\n%s", arg, buf);
			return -1;
		}
		have_ignore_callees = 1;
	}

	return 0;
}

998
static int
999
parse_branch_mode(const struct option *opt,
1000
		  const char *str __maybe_unused, int unset)
1001
{
1002 1003 1004
	int *branch_mode = opt->value;

	*branch_mode = !unset;
1005 1006 1007
	return 0;
}

1008 1009 1010 1011
static int
parse_percent_limit(const struct option *opt, const char *str,
		    int unset __maybe_unused)
{
1012
	struct report *rep = opt->value;
1013
	double pcnt = strtof(str, NULL);
1014

1015 1016
	rep->min_percent = pcnt;
	callchain_param.min_percent = pcnt;
1017 1018 1019
	return 0;
}

1020
int cmd_report(int argc, const char **argv)
1021
{
1022
	struct perf_session *session;
1023
	struct itrace_synth_opts itrace_synth_opts = { .set = 0, };
1024
	struct stat st;
1025
	bool has_br_stack = false;
1026
	int branch_mode = -1;
1027
	bool branch_call_mode = false;
1028
#define CALLCHAIN_DEFAULT_OPT  "graph,0.5,caller,function,percent"
1029 1030 1031
	static const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
						    CALLCHAIN_REPORT_HELP
						    "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
1032
	char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
1033
	const char * const report_usage[] = {
N
Namhyung Kim 已提交
1034
		"perf report [<options>]",
1035 1036
		NULL
	};
1037
	struct report report = {
1038
		.tool = {
1039 1040
			.sample		 = process_sample_event,
			.mmap		 = perf_event__process_mmap,
1041
			.mmap2		 = perf_event__process_mmap2,
1042
			.comm		 = perf_event__process_comm,
1043
			.namespaces	 = perf_event__process_namespaces,
1044 1045
			.exit		 = perf_event__process_exit,
			.fork		 = perf_event__process_fork,
1046 1047 1048 1049 1050
			.lost		 = perf_event__process_lost,
			.read		 = process_read_event,
			.attr		 = perf_event__process_attr,
			.tracing_data	 = perf_event__process_tracing_data,
			.build_id	 = perf_event__process_build_id,
1051 1052 1053
			.id_index	 = perf_event__process_id_index,
			.auxtrace_info	 = perf_event__process_auxtrace_info,
			.auxtrace	 = perf_event__process_auxtrace,
1054
			.event_update	 = perf_event__process_event_update,
1055
			.feature	 = process_feature_event,
1056
			.ordered_events	 = true,
1057 1058
			.ordering_requires_timestamps = true,
		},
1059
		.max_stack		 = PERF_MAX_STACK_DEPTH,
1060
		.pretty_printing_style	 = "normal",
1061
		.socket_filter		 = -1,
1062
		.annotation_opts	 = annotation__default_options,
1063 1064
	};
	const struct option options[] = {
1065
	OPT_STRING('i', "input", &input_name, "file",
1066
		    "input file name"),
1067
	OPT_INCR('v', "verbose", &verbose,
1068
		    "be more verbose (show symbol address, etc)"),
1069
	OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
1070 1071
	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
		    "dump raw trace in ASCII"),
1072
	OPT_BOOLEAN(0, "stats", &report.stats_mode, "Display event stats"),
1073
	OPT_BOOLEAN(0, "tasks", &report.tasks_mode, "Display recorded tasks"),
1074
	OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"),
1075 1076
	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
1077 1078
	OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
                    "don't load vmlinux even if found"),
1079 1080
	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
		   "file", "kallsyms pathname"),
1081
	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
1082
	OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
1083
		    "load module symbols - WARNING: use only with -k and LIVE kernel"),
1084
	OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1085
		    "Show a column with the number of samples"),
1086
	OPT_BOOLEAN('T', "threads", &report.show_threads,
1087
		    "Show per-thread event counters"),
1088
	OPT_STRING(0, "pretty", &report.pretty_printing_style, "key",
1089
		   "pretty printing style key: normal raw"),
1090
	OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"),
1091
	OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
1092 1093
	OPT_BOOLEAN(0, "stdio", &report.use_stdio,
		    "Use the stdio interface"),
1094 1095 1096
	OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
	OPT_BOOLEAN(0, "header-only", &report.header_only,
		    "Show only data header."),
1097
	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1098
		   sort_help("sort by key(s):")),
1099
	OPT_STRING('F', "fields", &field_order, "key[,keys...]",
1100
		   sort_help("output field(s): overhead period sample ")),
1101
	OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
1102
		    "Show sample percentage for different cpu modes"),
1103 1104
	OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
		    "Show sample percentage for different cpu modes", PARSE_OPT_HIDDEN),
1105 1106
	OPT_STRING('p', "parent", &parent_pattern, "regex",
		   "regex filter to identify parent, see: '--sort parent'"),
1107
	OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
1108
		    "Only display entries with parent-match"),
1109
	OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
1110
			     "print_type,threshold[,print_limit],order,sort_key[,branch],value",
1111 1112
			     report_callchain_help, &report_parse_callchain_opt,
			     callchain_default_opt),
1113 1114
	OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
		    "Accumulate callchains of children and show total overhead as well"),
1115 1116 1117
	OPT_INTEGER(0, "max-stack", &report.max_stack,
		    "Set the maximum stack depth when parsing the callchain, "
		    "anything beyond the specified depth will be ignored. "
1118
		    "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
1119 1120
	OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
		    "alias for inverted call graph"),
1121 1122 1123
	OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
		   "ignore callees of these functions in call graphs",
		   report_parse_ignore_callees_opt),
1124
	OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
1125
		   "only consider symbols in these dsos"),
1126
	OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1127
		   "only consider symbols in these comms"),
1128 1129 1130 1131
	OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
		   "only consider symbols in these pids"),
	OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
		   "only consider symbols in these tids"),
1132
	OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1133
		   "only consider these symbols"),
1134 1135
	OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
		   "only show symbols that (partially) match with this filter"),
1136
	OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
1137 1138
		   "width[,width...]",
		   "don't try to adjust column width, use these fixed values"),
1139
	OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
1140 1141
		   "separator for columns, no spaces will be added between "
		   "columns '.' is reserved."),
1142
	OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
1143
		    "Only display entries resolved to a symbol"),
1144 1145 1146
	OPT_CALLBACK(0, "symfs", NULL, "directory",
		     "Look for files with symbols relative to this directory",
		     symbol__config_symfs),
1147
	OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
1148 1149
		   "list of cpus to profile"),
	OPT_BOOLEAN('I', "show-info", &report.show_full_info,
1150
		    "Display extended information about perf.data file"),
1151
	OPT_BOOLEAN(0, "source", &report.annotation_opts.annotate_src,
1152
		    "Interleave source code with assembly code (default)"),
1153
	OPT_BOOLEAN(0, "asm-raw", &report.annotation_opts.show_asm_raw,
1154
		    "Display raw encoding of assembly instructions (default)"),
1155
	OPT_STRING('M', "disassembler-style", &report.annotation_opts.disassembler_style, "disassembler style",
1156
		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
1157 1158
	OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
		    "Show a column with the sum of periods"),
1159
	OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set,
N
Namhyung Kim 已提交
1160
		    "Show event group information together"),
1161
	OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
1162 1163 1164 1165
		    "use branch records for per branch histogram filling",
		    parse_branch_mode),
	OPT_BOOLEAN(0, "branch-history", &branch_call_mode,
		    "add last branch records to call history"),
1166
	OPT_STRING(0, "objdump", &report.annotation_opts.objdump_path, "path",
1167
		   "objdump binary to use for disassembly and annotations"),
1168 1169
	OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
		    "Disable symbol demangling"),
1170 1171
	OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
		    "Enable kernel symbol demangling"),
1172
	OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
1173 1174
	OPT_INTEGER(0, "samples", &symbol_conf.res_sample,
		    "Number of samples to save per histogram entry for individual browsing"),
1175 1176
	OPT_CALLBACK(0, "percent-limit", &report, "percent",
		     "Don't show entries under that percent", parse_percent_limit),
1177
	OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
N
Namhyung Kim 已提交
1178
		     "how to display percentage of filtered entries", parse_filter_percentage),
1179
	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
1180
			    "Instruction Tracing options\n" ITRACE_HELP,
1181
			    itrace_parse_synth_opts),
1182 1183
	OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
			"Show full source file name path for source lines"),
1184 1185
	OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
		    "Show callgraph from reference event"),
1186 1187
	OPT_INTEGER(0, "socket-filter", &report.socket_filter,
		    "only show processor socket that match with this filter"),
1188 1189
	OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace,
		    "Show raw trace event output (do not use print fmt or plugins)"),
1190 1191
	OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
		    "Show entries in a hierarchy"),
1192 1193 1194
	OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
			     "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
			     stdio__config_color, "always"),
1195 1196
	OPT_STRING(0, "time", &report.time_str, "str",
		   "Time span of interest (start,stop)"),
J
Jin Yao 已提交
1197 1198
	OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
		    "Show inline function"),
1199 1200 1201
	OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
		     "Set percent type local/global-period/hits",
		     annotate_parse_percent_type),
1202
	OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, "Show times in nanosecs"),
A
Andi Kleen 已提交
1203 1204 1205
	OPT_CALLBACK(0, "time-quantum", &symbol_conf.time_quantum, "time (ms|us|ns|s)",
		     "Set time quantum for time sort key (default 100ms)",
		     parse_time_quantum),
1206
	OPTS_EVSWITCH(&report.evswitch),
1207
	OPT_END()
1208
	};
1209
	struct perf_data data = {
1210 1211
		.mode  = PERF_DATA_MODE_READ,
	};
1212
	int ret = hists__init();
1213
	char sort_tmp[128];
1214 1215 1216

	if (ret < 0)
		return ret;
1217

1218 1219 1220
	ret = perf_config(report__config, &report);
	if (ret)
		return ret;
1221

1222
	argc = parse_options(argc, argv, options, report_usage, 0);
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
	if (argc) {
		/*
		 * Special case: if there's an argument left then assume that
		 * it's a symbol filter:
		 */
		if (argc > 1)
			usage_with_options(report_usage, options);

		report.symbol_filter_str = argv[0];
	}
1233

1234 1235 1236
	if (report.mmaps_mode)
		report.tasks_mode = true;

1237 1238 1239
	if (quiet)
		perf_quiet_option();

1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250
	if (symbol_conf.vmlinux_name &&
	    access(symbol_conf.vmlinux_name, R_OK)) {
		pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name);
		return -EINVAL;
	}
	if (symbol_conf.kallsyms_name &&
	    access(symbol_conf.kallsyms_name, R_OK)) {
		pr_err("Invalid file: %s\n", symbol_conf.kallsyms_name);
		return -EINVAL;
	}

1251
	if (report.inverted_callchain)
1252
		callchain_param.order = ORDER_CALLER;
1253 1254
	if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
		callchain_param.order = ORDER_CALLER;
1255

1256 1257 1258 1259
	if (itrace_synth_opts.callchain &&
	    (int)itrace_synth_opts.callchain_sz > report.max_stack)
		report.max_stack = itrace_synth_opts.callchain_sz;

1260
	if (!input_name || !strlen(input_name)) {
1261
		if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
1262
			input_name = "-";
1263
		else
1264
			input_name = "perf.data";
1265
	}
1266

J
Jiri Olsa 已提交
1267 1268
	data.path  = input_name;
	data.force = symbol_conf.force;
1269

1270
repeat:
1271
	session = perf_session__new(&data, false, &report.tool);
1272
	if (session == NULL)
1273
		return -1;
1274

1275 1276 1277 1278
	ret = evswitch__init(&report.evswitch, session->evlist, stderr);
	if (ret)
		return ret;

1279 1280 1281
	if (zstd_init(&(session->zstd_data), 0) < 0)
		pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");

1282 1283 1284 1285 1286
	if (report.queue_size) {
		ordered_events__set_alloc_size(&session->ordered_events,
					       report.queue_size);
	}

1287 1288
	session->itrace_synth_opts = &itrace_synth_opts;

1289 1290 1291 1292
	report.session = session;

	has_br_stack = perf_header__has_feat(&session->header,
					     HEADER_BRANCH_STACK);
1293 1294
	if (perf_evlist__combined_sample_type(session->evlist) & PERF_SAMPLE_STACK_USER)
		has_br_stack = false;
1295

1296
	setup_forced_leader(&report, session->evlist);
1297

1298 1299 1300
	if (itrace_synth_opts.last_branch)
		has_br_stack = true;

1301 1302 1303
	if (has_br_stack && branch_call_mode)
		symbol_conf.show_branchflag_count = true;

1304 1305
	memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat));

1306 1307 1308 1309 1310 1311
	/*
	 * Branch mode is a tristate:
	 * -1 means default, so decide based on the file having branch data.
	 * 0/1 means the user chose a mode.
	 */
	if (((branch_mode == -1 && has_br_stack) || branch_mode == 1) &&
1312
	    !branch_call_mode) {
1313
		sort__mode = SORT_MODE__BRANCH;
1314 1315
		symbol_conf.cumulate_callchain = false;
	}
1316
	if (branch_call_mode) {
1317
		callchain_param.key = CCKEY_ADDRESS;
1318 1319 1320 1321 1322 1323
		callchain_param.branch_callstack = 1;
		symbol_conf.use_callchain = true;
		callchain_register_param(&callchain_param);
		if (sort_order == NULL)
			sort_order = "srcline,symbol,dso";
	}
1324

1325
	if (report.mem_mode) {
1326
		if (sort__mode == SORT_MODE__BRANCH) {
1327
			pr_err("branch and mem mode incompatible\n");
1328 1329
			goto error;
		}
1330
		sort__mode = SORT_MODE__MEMORY;
1331
		symbol_conf.cumulate_callchain = false;
1332
	}
1333

1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
	if (symbol_conf.report_hierarchy) {
		/* disable incompatible options */
		symbol_conf.cumulate_callchain = false;

		if (field_order) {
			pr_err("Error: --hierarchy and --fields options cannot be used together\n");
			parse_options_usage(report_usage, options, "F", 1);
			parse_options_usage(NULL, options, "hierarchy", 0);
			goto error;
		}

1345
		perf_hpp_list.need_collapse = true;
1346 1347
	}

1348 1349 1350 1351 1352 1353 1354
	if (report.use_stdio)
		use_browser = 0;
	else if (report.use_tui)
		use_browser = 1;
	else if (report.use_gtk)
		use_browser = 2;

1355 1356
	/* Force tty output for header output and per-thread stat. */
	if (report.header || report.header_only || report.show_threads)
1357
		use_browser = 0;
1358 1359 1360 1361
	if (report.header || report.header_only)
		report.tool.show_feat_hdr = SHOW_FEAT_HEADER;
	if (report.show_full_info)
		report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
1362
	if (report.stats_mode || report.tasks_mode)
1363
		use_browser = 0;
1364
	if (report.stats_mode && report.tasks_mode) {
1365
		pr_err("Error: --tasks and --mmaps can't be used together with --stats\n");
1366 1367
		goto error;
	}
1368

1369 1370
	if (strcmp(input_name, "-") != 0)
		setup_browser(true);
1371
	else
1372 1373
		use_browser = 0;

1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
	if (sort_order && strstr(sort_order, "ipc")) {
		parse_options_usage(report_usage, options, "s", 1);
		goto error;
	}

	if (sort_order && strstr(sort_order, "symbol")) {
		if (sort__mode == SORT_MODE__BRANCH) {
			snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
				 sort_order, "ipc_lbr");
			report.symbol_ipc = true;
		} else {
			snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
				 sort_order, "ipc_null");
		}

		sort_order = sort_tmp;
	}

1392 1393 1394 1395 1396 1397 1398 1399 1400
	if (setup_sorting(session->evlist) < 0) {
		if (sort_order)
			parse_options_usage(report_usage, options, "s", 1);
		if (field_order)
			parse_options_usage(sort_order ? NULL : report_usage,
					    options, "F", 1);
		goto error;
	}

1401
	if ((report.header || report.header_only) && !quiet) {
1402 1403
		perf_session__fprintf_info(session, stdout,
					   report.show_full_info);
1404 1405 1406 1407
		if (report.header_only) {
			ret = 0;
			goto error;
		}
1408 1409
	} else if (use_browser == 0 && !quiet &&
		   !report.stats_mode && !report.tasks_mode) {
1410 1411 1412 1413
		fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
		      stdout);
	}

1414
	/*
1415
	 * Only in the TUI browser we are doing integrated annotation,
1416 1417 1418
	 * so don't allocate extra space that won't be used in the stdio
	 * implementation.
	 */
1419
	if (ui__has_annotation() || report.symbol_ipc) {
1420 1421 1422
		ret = symbol__annotation_init();
		if (ret < 0)
			goto error;
1423 1424 1425 1426 1427
		/*
 		 * For searching by name on the "Browse map details".
 		 * providing it only in verbose mode not to bloat too
 		 * much struct symbol.
 		 */
1428
		if (verbose > 0) {
1429 1430 1431 1432 1433 1434 1435 1436 1437
			/*
			 * XXX: Need to provide a less kludgy way to ask for
			 * more space per symbol, the u32 is for the index on
			 * the ui browser.
			 * See symbol__browser_index.
			 */
			symbol_conf.priv_size += sizeof(u32);
			symbol_conf.sort_by_name = true;
		}
1438
		annotation_config__init();
1439
	}
1440

1441
	if (symbol__init(&session->header.env) < 0)
1442
		goto error;
1443

1444 1445 1446 1447 1448 1449
	if (report.time_str) {
		ret = perf_time__parse_for_ranges(report.time_str, session,
						  &report.ptime_range,
						  &report.range_size,
						  &report.range_num);
		if (ret < 0)
1450
			goto error;
1451 1452 1453 1454

		itrace_synth_opts__set_time_range(&itrace_synth_opts,
						  report.ptime_range,
						  report.range_num);
1455 1456
	}

1457
	if (session->tevent.pevent &&
1458 1459 1460
	    tep_set_function_resolver(session->tevent.pevent,
				      machine__resolve_kernel_addr,
				      &session->machines.host) < 0) {
1461 1462 1463 1464 1465
		pr_err("%s: failed to set libtraceevent function resolver\n",
		       __func__);
		return -1;
	}

1466
	sort__setup_elide(stdout);
1467

1468
	ret = __cmd_report(&report);
1469 1470 1471 1472 1473 1474
	if (ret == K_SWITCH_INPUT_DATA) {
		perf_session__delete(session);
		goto repeat;
	} else
		ret = 0;

1475
error:
1476 1477
	if (report.ptime_range) {
		itrace_synth_opts__clear_time_range(&itrace_synth_opts);
1478
		zfree(&report.ptime_range);
1479
	}
1480
	zstd_fini(&(session->zstd_data));
1481 1482
	perf_session__delete(session);
	return ret;
1483
}