Commit 4ea062ed authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

perf evsel: Add hists helper

Not all tools need a hists instance per perf_evsel, so lets pave the way
to remove evsel->hists while leaving a way to access the hists from a
specially allocated evsel, one that comes with space at the end where
lives the evsel.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-qlktkhe31w4mgtbd84035sr2@git.kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 49c23f2d
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
				  struct addr_location *al,
				  struct perf_annotate *ann)
{
	struct hists *hists = evsel__hists(evsel);
	struct hist_entry *he;
	int ret;

@@ -66,13 +67,12 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
		return 0;
	}

	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0,
				true);
	he = __hists__add_entry(hists, al, NULL, NULL, NULL, 1, 1, 0, true);
	if (he == NULL)
		return -ENOMEM;

	ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
	hists__inc_nr_samples(&evsel->hists, true);
	hists__inc_nr_samples(hists, true);
	return ret;
}

@@ -225,7 +225,7 @@ static int __cmd_annotate(struct perf_annotate *ann)

	total_nr_samples = 0;
	evlist__for_each(session->evlist, pos) {
		struct hists *hists = &pos->hists;
		struct hists *hists = evsel__hists(pos);
		u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];

		if (nr_samples > 0) {
+12 −9
Original line number Diff line number Diff line
@@ -327,6 +327,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
				      struct machine *machine)
{
	struct addr_location al;
	struct hists *hists = evsel__hists(evsel);

	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
		pr_warning("problem processing %d event, skipping it.\n",
@@ -334,7 +335,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
		return -1;
	}

	if (hists__add_entry(&evsel->hists, &al, sample->period,
	if (hists__add_entry(hists, &al, sample->period,
			     sample->weight, sample->transaction)) {
		pr_warning("problem incrementing symbol period, skipping event\n");
		return -1;
@@ -346,9 +347,9 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
	 * hists__output_resort() and precompute needs the total
	 * period in order to sort entries by percentage delta.
	 */
	evsel->hists.stats.total_period += sample->period;
	hists->stats.total_period += sample->period;
	if (!al.filtered)
		evsel->hists.stats.total_non_filtered_period += sample->period;
		hists->stats.total_non_filtered_period += sample->period;

	return 0;
}
@@ -382,7 +383,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
	struct perf_evsel *evsel;

	evlist__for_each(evlist, evsel) {
		struct hists *hists = &evsel->hists;
		struct hists *hists = evsel__hists(evsel);

		hists__collapse_resort(hists, NULL);
	}
@@ -631,24 +632,26 @@ static void data_process(void)
	bool first = true;

	evlist__for_each(evlist_base, evsel_base) {
		struct hists *hists_base = evsel__hists(evsel_base);
		struct data__file *d;
		int i;

		data__for_each_file_new(i, d) {
			struct perf_evlist *evlist = d->session->evlist;
			struct perf_evsel *evsel;
			struct hists *hists;

			evsel = evsel_match(evsel_base, evlist);
			if (!evsel)
				continue;

			d->hists = &evsel->hists;
			hists = evsel__hists(evsel);
			d->hists = hists;

			hists__match(&evsel_base->hists, &evsel->hists);
			hists__match(hists_base, hists);

			if (!show_baseline_only)
				hists__link(&evsel_base->hists,
					    &evsel->hists);
				hists__link(hists_base, hists);
		}

		fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
@@ -659,7 +662,7 @@ static void data_process(void)
		if (verbose || data__files_cnt > 2)
			data__fprintf();

		hists__process(&evsel_base->hists);
		hists__process(hists_base);
	}
}

+10 −8
Original line number Diff line number Diff line
@@ -288,12 +288,14 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
		evname = buf;

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

			if (symbol_conf.filter_relative) {
				nr_samples += pos->hists.stats.nr_non_filtered_samples;
				nr_events += pos->hists.stats.total_non_filtered_period;
				nr_samples += pos_hists->stats.nr_non_filtered_samples;
				nr_events += pos_hists->stats.total_non_filtered_period;
			} else {
				nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE];
				nr_events += pos->hists.stats.total_period;
				nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
				nr_events += pos_hists->stats.total_period;
			}
		}
	}
@@ -318,7 +320,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
	struct perf_evsel *pos;

	evlist__for_each(evlist, pos) {
		struct hists *hists = &pos->hists;
		struct hists *hists = evsel__hists(pos);
		const char *evname = perf_evsel__name(pos);

		if (symbol_conf.event_group &&
@@ -427,7 +429,7 @@ static void report__collapse_hists(struct report *rep)
	ui_progress__init(&prog, rep->nr_entries, "Merging related events...");

	evlist__for_each(rep->session->evlist, pos) {
		struct hists *hists = &pos->hists;
		struct hists *hists = evsel__hists(pos);

		if (pos->idx == 0)
			hists->symbol_filter_str = rep->symbol_filter_str;
@@ -437,7 +439,7 @@ static void report__collapse_hists(struct report *rep)
		/* 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;
			struct hists *leader_hists = evsel__hists(pos->leader);

			hists__match(leader_hists, hists);
			hists__link(leader_hists, hists);
@@ -500,7 +502,7 @@ static int __cmd_report(struct report *rep)
	}

	evlist__for_each(session->evlist, pos)
		hists__output_resort(&pos->hists);
		hists__output_resort(evsel__hists(pos));

	return report__browse_hists(rep);
}
+30 −25
Original line number Diff line number Diff line
@@ -251,6 +251,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
	char bf[160];
	int printed = 0;
	const int win_width = top->winsize.ws_col - 1;
	struct hists *hists = evsel__hists(top->sym_evsel);

	puts(CONSOLE_CLEAR);

@@ -261,13 +262,13 @@ static void perf_top__print_sym_table(struct perf_top *top)

	printf("%-*.*s\n", win_width, win_width, graph_dotted_line);

	if (top->sym_evsel->hists.stats.nr_lost_warned !=
	    top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) {
		top->sym_evsel->hists.stats.nr_lost_warned =
			top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST];
	if (hists->stats.nr_lost_warned !=
	    hists->stats.nr_events[PERF_RECORD_LOST]) {
		hists->stats.nr_lost_warned =
			      hists->stats.nr_events[PERF_RECORD_LOST];
		color_fprintf(stdout, PERF_COLOR_RED,
			      "WARNING: LOST %d chunks, Check IO/CPU overload",
			      top->sym_evsel->hists.stats.nr_lost_warned);
			      hists->stats.nr_lost_warned);
		++printed;
	}

@@ -277,21 +278,18 @@ static void perf_top__print_sym_table(struct perf_top *top)
	}

	if (top->zero) {
		hists__delete_entries(&top->sym_evsel->hists);
		hists__delete_entries(hists);
	} else {
		hists__decay_entries(&top->sym_evsel->hists,
				     top->hide_user_symbols,
		hists__decay_entries(hists, top->hide_user_symbols,
				     top->hide_kernel_symbols);
	}

	hists__collapse_resort(&top->sym_evsel->hists, NULL);
	hists__output_resort(&top->sym_evsel->hists);
	hists__collapse_resort(hists, NULL);
	hists__output_resort(hists);

	hists__output_recalc_col_len(&top->sym_evsel->hists,
				     top->print_entries - printed);
	hists__output_recalc_col_len(hists, top->print_entries - printed);
	putchar('\n');
	hists__fprintf(&top->sym_evsel->hists, false,
		       top->print_entries - printed, win_width,
	hists__fprintf(hists, false, top->print_entries - printed, win_width,
		       top->min_percent, stdout);
}

@@ -334,6 +332,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg)
{
	char *buf = malloc(0), *p;
	struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL;
	struct hists *hists = evsel__hists(top->sym_evsel);
	struct rb_node *next;
	size_t dummy = 0;

@@ -351,7 +350,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg)
	if (p)
		*p = 0;

	next = rb_first(&top->sym_evsel->hists.entries);
	next = rb_first(&hists->entries);
	while (next) {
		n = rb_entry(next, struct hist_entry, rb_node);
		if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) {
@@ -538,21 +537,24 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
static void perf_top__sort_new_samples(void *arg)
{
	struct perf_top *t = arg;
	struct hists *hists;

	perf_top__reset_sample_counters(t);

	if (t->evlist->selected != NULL)
		t->sym_evsel = t->evlist->selected;

	hists = evsel__hists(t->sym_evsel);

	if (t->zero) {
		hists__delete_entries(&t->sym_evsel->hists);
		hists__delete_entries(hists);
	} else {
		hists__decay_entries(&t->sym_evsel->hists,
				     t->hide_user_symbols,
		hists__decay_entries(hists, t->hide_user_symbols,
				     t->hide_kernel_symbols);
	}

	hists__collapse_resort(&t->sym_evsel->hists, NULL);
	hists__output_resort(&t->sym_evsel->hists);
	hists__collapse_resort(hists, NULL);
	hists__output_resort(hists);
}

static void *display_thread_tui(void *arg)
@@ -573,8 +575,10 @@ static void *display_thread_tui(void *arg)
	 * Zooming in/out UIDs. For now juse use whatever the user passed
	 * via --uid.
	 */
	evlist__for_each(top->evlist, pos)
		pos->hists.uid_filter_str = top->record_opts.target.uid_str;
	evlist__for_each(top->evlist, pos) {
		struct hists *hists = evsel__hists(pos);
		hists->uid_filter_str = top->record_opts.target.uid_str;
	}

	perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
				      &top->session->header.env);
@@ -768,6 +772,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
	}

	if (al.sym == NULL || !al.sym->ignore) {
		struct hists *hists = evsel__hists(evsel);
		struct hist_entry_iter iter = {
			.add_entry_cb = hist_iter__top_callback,
		};
@@ -777,14 +782,14 @@ static void perf_event__process_sample(struct perf_tool *tool,
		else
			iter.ops = &hist_iter_normal;

		pthread_mutex_lock(&evsel->hists.lock);
		pthread_mutex_lock(&hists->lock);

		err = hist_entry_iter__add(&iter, &al, evsel, sample,
					   top->max_stack, top);
		if (err < 0)
			pr_err("Problem incrementing symbol period, skipping event\n");

		pthread_mutex_unlock(&evsel->hists.lock);
		pthread_mutex_unlock(&hists->lock);
	}

	return;
@@ -849,7 +854,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
			perf_event__process_sample(&top->tool, event, evsel,
						   &sample, machine);
		} else if (event->header.type < PERF_RECORD_MAX) {
			hists__inc_nr_events(&evsel->hists, event->header.type);
			hists__inc_nr_events(evsel__hists(evsel), event->header.type);
			machine__process_event(machine, event, &sample);
		} else
			++session->stats.nr_unknown_events;
+4 −4
Original line number Diff line number Diff line
@@ -245,7 +245,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec
static int test1(struct perf_evsel *evsel, struct machine *machine)
{
	int err;
	struct hists *hists = &evsel->hists;
	struct hists *hists = evsel__hists(evsel);
	/*
	 * expected output:
	 *
@@ -295,7 +295,7 @@ out:
static int test2(struct perf_evsel *evsel, struct machine *machine)
{
	int err;
	struct hists *hists = &evsel->hists;
	struct hists *hists = evsel__hists(evsel);
	/*
	 * expected output:
	 *
@@ -442,7 +442,7 @@ out:
static int test3(struct perf_evsel *evsel, struct machine *machine)
{
	int err;
	struct hists *hists = &evsel->hists;
	struct hists *hists = evsel__hists(evsel);
	/*
	 * expected output:
	 *
@@ -498,7 +498,7 @@ out:
static int test4(struct perf_evsel *evsel, struct machine *machine)
{
	int err;
	struct hists *hists = &evsel->hists;
	struct hists *hists = evsel__hists(evsel);
	/*
	 * expected output:
	 *
Loading