Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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 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);

	sample->weight = 1;

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

#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;
#endif

+27 −3
Original line number 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)
{
	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 |
				    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;

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

			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;
				perf_counts(counter->counts, cpu, thread)->ena = 0;
				perf_counts(counter->counts, cpu, thread)->run = 0;
				return -1;
			}

			count->loaded = false;

			if (STAT_RECORD) {
				if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
					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);
}

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

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

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

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

#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)
{
	int w = 7 * ab->nr_events;
	return (annotate_browser__opts.show_total_period ? 12 : 7) * ab->nr_events;
}

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

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 &&
					         !browser->navkeypressed)));
	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;
	char bf[256];
	bool show_title = false;
@@ -151,8 +153,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
						bdl->samples[i].percent,
						current_entry);
			if (annotate_browser__opts.show_total_period) {
				ui_browser__printf(browser, "%6" PRIu64 " ",
						   bdl->samples[i].nr);
				ui_browser__printf(browser, "%11" PRIu64 " ",
						   bdl->samples[i].he.period);
			} else {
				ui_browser__printf(browser, "%6.2f ",
						   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);

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

	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) {
		if (dl->line_nr && annotate_browser__opts.show_linenr)
			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  ",
				    ab->addr_width, " ");
		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 {
		u64 addr = dl->offset;
		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);
		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)
@@ -457,7 +461,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
						pos->offset,
						next ? next->offset : len,
						&path, &sample);
			bpos->samples[i].nr = sample.nr_samples;
			bpos->samples[i].he = sample;

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

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

		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);

			if (symbol_conf.show_total_period)
				color_fprintf(stdout, color, " %7" PRIu64,
				color_fprintf(stdout, color, " %11" PRIu64,
					      sample.period);
			else
				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)
		return 1;
	else {
		int width = 8;
		int width = symbol_conf.show_total_period ? 12 : 8;

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

	filename = strdup(dso->long_name);
Loading