Commit c3a3800f authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo-4.14-20170728' of...

Merge tag 'perf-core-for-mingo-4.14-20170728' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf/core improvements and fixes for 4.14 from Arnaldo Carvalho de Melo:

New features:

 - Add PERF_SAMPLE_CALLCHAIN and PERF_RECORD_MMAP[2] to 'perf data' CTF
   conversion, allowing CTF trace visualization tools to show callchains
   and to resolve symbols (Geneviève Bastien)

Improvements:

 - Use group read for event groups in 'perf stat', reducing overhead when
   groups are defined in the event specification, i.e. when using {} to
   enclose a list of events, asking them to be read at the same time,
   e.g.: "perf stat -e '{cycles,instructions}'" (Jiri Olsa)

Fixes:

 - Do not overwrite perf_sample->weight in 'perf annotate' when
   processing samples, use whatever came from the kernel when
   perf_event_attr.sample_type has PERF_SAMPLE_WEIGHT set or just handle
   its default value, 0, when that is not set and "weight" is one of the
   sort orders chosen (Arnaldo Carvalho de Melo)

 - 'perf annotate --show-total-period' fixes:
    - TUI should show period, not nr_samples
    - Set appropriate column width for period/percent
    - Fix the column header to show "Period" when when that is what
      is being asked for
   (Taeung Song, Arnaldo Carvalho de Melo)

 - Use default sort if evlist is empty, fixing pipe mode (David Carrillo-Cisneros)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents f5db340f 6b7007af
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -177,8 +177,6 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
	 */
	 */
	process_branch_stack(sample->branch_stack, al, sample);
	process_branch_stack(sample->branch_stack, al, sample);


	sample->weight = 1;

	he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true);
	he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true);
	if (he == NULL)
	if (he == NULL)
		return -ENOMEM;
		return -ENOMEM;
+1 −1
Original line number Original line Diff line number Diff line
@@ -69,7 +69,7 @@ static int cmd_data_convert(int argc, const char **argv)
	};
	};


#ifndef HAVE_LIBBABELTRACE_SUPPORT
#ifndef HAVE_LIBBABELTRACE_SUPPORT
	pr_err("No conversion support compiled in.\n");
	pr_err("No conversion support compiled in. perf should be compiled with environment variables LIBBABELTRACE=1 and LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n");
	return -1;
	return -1;
#endif
#endif


+27 −3
Original line number Original line Diff line number Diff line
@@ -213,10 +213,20 @@ static void perf_stat__reset_stats(void)
static int create_perf_stat_counter(struct perf_evsel *evsel)
static int create_perf_stat_counter(struct perf_evsel *evsel)
{
{
	struct perf_event_attr *attr = &evsel->attr;
	struct perf_event_attr *attr = &evsel->attr;
	struct perf_evsel *leader = evsel->leader;


	if (stat_config.scale)
	if (stat_config.scale) {
		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
				    PERF_FORMAT_TOTAL_TIME_RUNNING;
				    PERF_FORMAT_TOTAL_TIME_RUNNING;
	}

	/*
	 * The event is part of non trivial group, let's enable
	 * the group read (for leader) and ID retrieval for all
	 * members.
	 */
	if (leader->nr_members > 1)
		attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP;


	attr->inherit = !no_inherit;
	attr->inherit = !no_inherit;


@@ -333,13 +343,21 @@ static int read_counter(struct perf_evsel *counter)
			struct perf_counts_values *count;
			struct perf_counts_values *count;


			count = perf_counts(counter->counts, cpu, thread);
			count = perf_counts(counter->counts, cpu, thread);
			if (perf_evsel__read(counter, cpu, thread, count)) {

			/*
			 * The leader's group read loads data into its group members
			 * (via perf_evsel__read_counter) and sets threir count->loaded.
			 */
			if (!count->loaded &&
			    perf_evsel__read_counter(counter, cpu, thread)) {
				counter->counts->scaled = -1;
				counter->counts->scaled = -1;
				perf_counts(counter->counts, cpu, thread)->ena = 0;
				perf_counts(counter->counts, cpu, thread)->ena = 0;
				perf_counts(counter->counts, cpu, thread)->run = 0;
				perf_counts(counter->counts, cpu, thread)->run = 0;
				return -1;
				return -1;
			}
			}


			count->loaded = false;

			if (STAT_RECORD) {
			if (STAT_RECORD) {
				if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
				if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
					pr_err("failed to write stat event\n");
					pr_err("failed to write stat event\n");
@@ -559,6 +577,11 @@ static int store_counter_ids(struct perf_evsel *counter)
	return __store_counter_ids(counter, cpus, threads);
	return __store_counter_ids(counter, cpus, threads);
}
}


static bool perf_evsel__should_store_id(struct perf_evsel *counter)
{
	return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID;
}

static int __run_perf_stat(int argc, const char **argv)
static int __run_perf_stat(int argc, const char **argv)
{
{
	int interval = stat_config.interval;
	int interval = stat_config.interval;
@@ -631,7 +654,8 @@ static int __run_perf_stat(int argc, const char **argv)
		if (l > unit_width)
		if (l > unit_width)
			unit_width = l;
			unit_width = l;


		if (STAT_RECORD && store_counter_ids(counter))
		if (perf_evsel__should_store_id(counter) &&
		    store_counter_ids(counter))
			return -1;
			return -1;
	}
	}


+20 −16
Original line number Original line Diff line number Diff line
@@ -18,7 +18,7 @@


struct disasm_line_samples {
struct disasm_line_samples {
	double		      percent;
	double		      percent;
	u64		nr;
	struct sym_hist_entry he;
};
};


#define IPC_WIDTH 6
#define IPC_WIDTH 6
@@ -110,11 +110,12 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br


static int annotate_browser__pcnt_width(struct annotate_browser *ab)
static int annotate_browser__pcnt_width(struct annotate_browser *ab)
{
{
	int w = 7 * ab->nr_events;
	return (annotate_browser__opts.show_total_period ? 12 : 7) * ab->nr_events;
}


	if (ab->have_cycles)
static int annotate_browser__cycles_width(struct annotate_browser *ab)
		w += IPC_WIDTH + CYCLES_WIDTH;
{
	return w;
	return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0;
}
}


static void annotate_browser__write(struct ui_browser *browser, void *entry, int row)
static void annotate_browser__write(struct ui_browser *browser, void *entry, int row)
@@ -127,7 +128,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
			     (!current_entry || (browser->use_navkeypressed &&
			     (!current_entry || (browser->use_navkeypressed &&
					         !browser->navkeypressed)));
					         !browser->navkeypressed)));
	int width = browser->width, printed;
	int width = browser->width, printed;
	int i, pcnt_width = annotate_browser__pcnt_width(ab);
	int i, pcnt_width = annotate_browser__pcnt_width(ab),
	       cycles_width = annotate_browser__cycles_width(ab);
	double percent_max = 0.0;
	double percent_max = 0.0;
	char bf[256];
	char bf[256];
	bool show_title = false;
	bool show_title = false;
@@ -151,8 +153,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
						bdl->samples[i].percent,
						bdl->samples[i].percent,
						current_entry);
						current_entry);
			if (annotate_browser__opts.show_total_period) {
			if (annotate_browser__opts.show_total_period) {
				ui_browser__printf(browser, "%6" PRIu64 " ",
				ui_browser__printf(browser, "%11" PRIu64 " ",
						   bdl->samples[i].nr);
						   bdl->samples[i].he.period);
			} else {
			} else {
				ui_browser__printf(browser, "%6.2f ",
				ui_browser__printf(browser, "%6.2f ",
						   bdl->samples[i].percent);
						   bdl->samples[i].percent);
@@ -162,9 +164,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
		ui_browser__set_percent_color(browser, 0, current_entry);
		ui_browser__set_percent_color(browser, 0, current_entry);


		if (!show_title)
		if (!show_title)
			ui_browser__write_nstring(browser, " ", 7 * ab->nr_events);
			ui_browser__write_nstring(browser, " ", pcnt_width);
		else
		else {
			ui_browser__printf(browser, "%*s", 7, "Percent");
			ui_browser__printf(browser, "%*s", pcnt_width,
					   annotate_browser__opts.show_total_period ? "Period" : "Percent");
		}
	}
	}
	if (ab->have_cycles) {
	if (ab->have_cycles) {
		if (dl->ipc)
		if (dl->ipc)
@@ -190,7 +194,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
		width += 1;
		width += 1;


	if (!*dl->line)
	if (!*dl->line)
		ui_browser__write_nstring(browser, " ", width - pcnt_width);
		ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width);
	else if (dl->offset == -1) {
	else if (dl->offset == -1) {
		if (dl->line_nr && annotate_browser__opts.show_linenr)
		if (dl->line_nr && annotate_browser__opts.show_linenr)
			printed = scnprintf(bf, sizeof(bf), "%-*d ",
			printed = scnprintf(bf, sizeof(bf), "%-*d ",
@@ -199,7 +203,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
			printed = scnprintf(bf, sizeof(bf), "%*s  ",
			printed = scnprintf(bf, sizeof(bf), "%*s  ",
				    ab->addr_width, " ");
				    ab->addr_width, " ");
		ui_browser__write_nstring(browser, bf, printed);
		ui_browser__write_nstring(browser, bf, printed);
		ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width + 1);
		ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1);
	} else {
	} else {
		u64 addr = dl->offset;
		u64 addr = dl->offset;
		int color = -1;
		int color = -1;
@@ -256,7 +260,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
		}
		}


		disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset);
		disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset);
		ui_browser__write_nstring(browser, bf, width - pcnt_width - 3 - printed);
		ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed);
	}
	}


	if (current_entry)
	if (current_entry)
@@ -457,7 +461,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
						pos->offset,
						pos->offset,
						next ? next->offset : len,
						next ? next->offset : len,
						&path, &sample);
						&path, &sample);
			bpos->samples[i].nr = sample.nr_samples;
			bpos->samples[i].he = sample;


			if (max_percent < bpos->samples[i].percent)
			if (max_percent < bpos->samples[i].percent)
				max_percent = bpos->samples[i].percent;
				max_percent = bpos->samples[i].percent;
+6 −5
Original line number Original line Diff line number Diff line
@@ -963,8 +963,9 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset,
		u64 period = 0;
		u64 period = 0;


		while (offset < end) {
		while (offset < end) {
			hits += h->addr[offset++].nr_samples;
			hits   += h->addr[offset].nr_samples;
			period += h->addr[offset++].period;
			period += h->addr[offset].period;
			++offset;
		}
		}


		if (h->nr_samples) {
		if (h->nr_samples) {
@@ -1142,7 +1143,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
			color = get_percent_color(percent);
			color = get_percent_color(percent);


			if (symbol_conf.show_total_period)
			if (symbol_conf.show_total_period)
				color_fprintf(stdout, color, " %7" PRIu64,
				color_fprintf(stdout, color, " %11" PRIu64,
					      sample.period);
					      sample.period);
			else
			else
				color_fprintf(stdout, color, " %7.2f", percent);
				color_fprintf(stdout, color, " %7.2f", percent);
@@ -1165,7 +1166,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
	} else if (max_lines && printed >= max_lines)
	} else if (max_lines && printed >= max_lines)
		return 1;
		return 1;
	else {
	else {
		int width = 8;
		int width = symbol_conf.show_total_period ? 12 : 8;


		if (queue)
		if (queue)
			return -1;
			return -1;
@@ -1806,7 +1807,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
	int printed = 2, queue_len = 0;
	int printed = 2, queue_len = 0;
	int more = 0;
	int more = 0;
	u64 len;
	u64 len;
	int width = 8;
	int width = symbol_conf.show_total_period ? 12 : 8;
	int graph_dotted_len;
	int graph_dotted_len;


	filename = strdup(dso->long_name);
	filename = strdup(dso->long_name);
Loading