diff options
Diffstat (limited to 'tools/perf/builtin-report.c')
| -rw-r--r-- | tools/perf/builtin-report.c | 93 | 
1 files changed, 78 insertions, 15 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index fc251005dd3..96b5a7fee4b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -8,6 +8,7 @@  #include "builtin.h"  #include "util/util.h" +#include "util/cache.h"  #include "util/annotate.h"  #include "util/color.h" @@ -54,6 +55,16 @@ struct perf_report {  	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);  }; +static int perf_report_config(const char *var, const char *value, void *cb) +{ +	if (!strcmp(var, "report.group")) { +		symbol_conf.event_group = perf_config_bool(var, value); +		return 0; +	} + +	return perf_default_config(var, value, cb); +} +  static int perf_report__add_branch_hist_entry(struct perf_tool *tool,  					struct addr_location *al,  					struct perf_sample *sample, @@ -299,6 +310,21 @@ static size_t hists__fprintf_nr_sample_events(struct hists *self,  	char unit;  	unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE];  	u64 nr_events = self->stats.total_period; +	struct perf_evsel *evsel = hists_to_evsel(self); +	char buf[512]; +	size_t size = sizeof(buf); + +	if (symbol_conf.event_group && evsel->nr_members > 1) { +		struct perf_evsel *pos; + +		perf_evsel__group_desc(evsel, buf, size); +		evname = buf; + +		for_each_group_member(pos, evsel) { +			nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; +			nr_events += pos->hists.stats.total_period; +		} +	}  	nr_samples = convert_unit(nr_samples, &unit);  	ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit); @@ -319,6 +345,10 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,  		struct hists *hists = &pos->hists;  		const char *evname = perf_evsel__name(pos); +		if (symbol_conf.event_group && +		    !perf_evsel__is_group_leader(pos)) +			continue; +  		hists__fprintf_nr_sample_events(hists, evname, stdout);  		hists__fprintf(hists, true, 0, 0, stdout);  		fprintf(stdout, "\n\n"); @@ -372,7 +402,7 @@ static int __cmd_report(struct perf_report *rep)  	if (ret)  		goto out_delete; -	kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION]; +	kernel_map = session->machines.host.vmlinux_maps[MAP__FUNCTION];  	kernel_kmap = map__kmap(kernel_map);  	if (kernel_map == NULL ||  	    (kernel_map->dso->hit && @@ -416,8 +446,16 @@ static int __cmd_report(struct perf_report *rep)  			hists->symbol_filter_str = rep->symbol_filter_str;  		hists__collapse_resort(hists); -		hists__output_resort(hists);  		nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; + +		/* Non-group events are considered as leader */ +		if (symbol_conf.event_group && +		    !perf_evsel__is_group_leader(pos)) { +			struct hists *leader_hists = &pos->leader->hists; + +			hists__match(leader_hists, hists); +			hists__link(leader_hists, hists); +		}  	}  	if (nr_samples == 0) { @@ -425,11 +463,22 @@ static int __cmd_report(struct perf_report *rep)  		goto out_delete;  	} +	list_for_each_entry(pos, &session->evlist->entries, node) +		hists__output_resort(&pos->hists); +  	if (use_browser > 0) {  		if (use_browser == 1) { -			perf_evlist__tui_browse_hists(session->evlist, help, -						      NULL, -						      &session->header.env); +			ret = perf_evlist__tui_browse_hists(session->evlist, +							help, +							NULL, +							&session->header.env); +			/* +			 * 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; +  		} else if (use_browser == 2) {  			perf_evlist__gtk_browse_hists(session->evlist, help,  						      NULL); @@ -595,8 +644,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)  	OPT_BOOLEAN(0, "stdio", &report.use_stdio,  		    "Use the stdio interface"),  	OPT_STRING('s', "sort", &sort_order, "key[,key2...]", -		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to," -		   " dso_from, symbol_to, symbol_from, mispredict"), +		   "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline," +		   " dso_to, dso_from, symbol_to, symbol_from, mispredict"),  	OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,  		    "Show sample percentage for different cpu modes"),  	OPT_STRING('p', "parent", &parent_pattern, "regex", @@ -638,6 +687,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)  		   "Specify disassembler style (e.g. -M intel for intel syntax)"),  	OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,  		    "Show a column with the sum of periods"), +	OPT_BOOLEAN(0, "group", &symbol_conf.event_group, +		    "Show event group information together"),  	OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "",  		    "use branch records for histogram filling", parse_branch_mode),  	OPT_STRING(0, "objdump", &objdump_path, "path", @@ -645,6 +696,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)  	OPT_END()  	}; +	perf_config(perf_report_config, NULL); +  	argc = parse_options(argc, argv, options, report_usage, 0);  	if (report.use_stdio) @@ -663,6 +716,16 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)  		else  			input_name = "perf.data";  	} + +	if (strcmp(input_name, "-") != 0) +		setup_browser(true); +	else { +		use_browser = 0; +		perf_hpp__column_enable(PERF_HPP__OVERHEAD); +		perf_hpp__init(); +	} + +repeat:  	session = perf_session__new(input_name, O_RDONLY,  				    report.force, false, &report.tool);  	if (session == NULL) @@ -688,14 +751,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)  	} -	if (strcmp(input_name, "-") != 0) -		setup_browser(true); -	else { -		use_browser = 0; -		perf_hpp__init(); -	} - -	setup_sorting(report_usage, options); +	if (setup_sorting() < 0) +		usage_with_options(report_usage, options);  	/*  	 * Only in the newt browser we are doing integrated annotation, @@ -763,6 +820,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)  	}  	ret = __cmd_report(&report); +	if (ret == K_SWITCH_INPUT_DATA) { +		perf_session__delete(session); +		goto repeat; +	} else +		ret = 0; +  error:  	perf_session__delete(session);  	return ret;  |