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

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

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

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

 into perf/core

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

User visible changes:

  - Callchain improvements from Andi Kleen including:
    * Enable printing the srcline in the history
    * Make get_srcline fall back to sym+offset

  - Allow to force redirect pr_debug to stderr. (Andi Kleen)

  - TUI hist_entry browser fixes, including showing missing overhead
    value for first level callchain. Detected comparing the output of
    --stdio/--gui (that matched) with --tui, that had this problem. (Namhyung Kim)

  - Fix segfault due to invalid kernel dso access (Namhyung Kim)

Infrastructure changes:

  - Move bfd_demangle stubbing to its only user (Arnaldo Carvalho de Melo)

  - 'perf stat' refactorings, moving stuff from it to evsel.c to use in
    per-pkg/snapshot format changes (Jiri Olsa)

  - Add per-pkg format file parsing (Matt Fleming)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 4e6e311e 1d9e446b
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -227,10 +227,14 @@ static void callchain_node__init_have_children_rb_tree(struct callchain_node *no
	}
}

static void callchain_node__init_have_children(struct callchain_node *node)
static void callchain_node__init_have_children(struct callchain_node *node,
					       bool has_sibling)
{
	struct callchain_list *chain;

	chain = list_entry(node->val.next, struct callchain_list, list);
	chain->ms.has_children = has_sibling;

	if (!list_empty(&node->val)) {
		chain = list_entry(node->val.prev, struct callchain_list, list);
		chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root);
@@ -241,11 +245,12 @@ static void callchain_node__init_have_children(struct callchain_node *node)

static void callchain__init_have_children(struct rb_root *root)
{
	struct rb_node *nd;
	struct rb_node *nd = rb_first(root);
	bool has_sibling = nd && rb_next(nd);

	for (nd = rb_first(root); nd; nd = rb_next(nd)) {
		struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
		callchain_node__init_have_children(node);
		callchain_node__init_have_children(node, has_sibling);
	}
}

@@ -542,8 +547,11 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
	struct rb_node *node;
	int first_row = row, offset = level * LEVEL_OFFSET_STEP;
	u64 new_total;
	bool need_percent;

	node = rb_first(root);
	need_percent = !!rb_next(node);

	while (node) {
		struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
		struct rb_node *next = rb_next(node);
@@ -560,7 +568,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser,

			if (first)
				first = false;
			else if (level > 1)
			else if (need_percent)
				extra_offset = LEVEL_OFFSET_STEP;

			folded_sign = callchain_list__folded(chain);
@@ -573,7 +581,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
			str = callchain_list__sym_name(chain, bf, sizeof(bf),
						       browser->show_dso);

			if (was_first && level > 1) {
			if (was_first && need_percent) {
				double percent = cumul * 100.0 / total;

				if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
@@ -790,6 +798,13 @@ static int hist_browser__show_entry(struct hist_browser *browser,
			.is_current_entry = current_entry,
		};

		if (callchain_param.mode == CHAIN_GRAPH_REL) {
			if (symbol_conf.cumulate_callchain)
				total = entry->stat_acc->period;
			else
				total = entry->stat.period;
		}

		printed += hist_browser__show_callchain(browser,
					&entry->sorted_chain, 1, row, total,
					hist_browser__show_callchain_entry, &arg,
+1 −1
Original line number Diff line number Diff line
@@ -1192,7 +1192,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
			goto next;

		offset = start + i;
		src_line->path = get_srcline(map->dso, offset);
		src_line->path = get_srcline(map->dso, offset, NULL, false);
		insert_source_line(&tmp_root, src_line);

	next:
+11 −1
Original line number Diff line number Diff line
@@ -815,6 +815,16 @@ char *callchain_list__sym_name(struct callchain_list *cl,
	int printed;

	if (cl->ms.sym) {
		if (callchain_param.key == CCKEY_ADDRESS &&
		    cl->ms.map && !cl->srcline)
			cl->srcline = get_srcline(cl->ms.map->dso,
						  map__rip_2objdump(cl->ms.map,
								    cl->ip),
						  cl->ms.sym, false);
		if (cl->srcline)
			printed = scnprintf(bf, bfsize, "%s %s",
					cl->ms.sym->name, cl->srcline);
		else
			printed = scnprintf(bf, bfsize, "%s", cl->ms.sym->name);
	} else
		printed = scnprintf(bf, bfsize, "%#" PRIx64, cl->ip);
+1 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ extern struct callchain_param callchain_param;
struct callchain_list {
	u64			ip;
	struct map_symbol	ms;
	char		       *srcline;
	struct list_head	list;
};

+3 −1
Original line number Diff line number Diff line
@@ -19,13 +19,14 @@
int verbose;
bool dump_trace = false, quiet = false;
int debug_ordered_events;
static int redirect_to_stderr;

static int _eprintf(int level, int var, const char *fmt, va_list args)
{
	int ret = 0;

	if (var >= level) {
		if (use_browser >= 1)
		if (use_browser >= 1 && !redirect_to_stderr)
			ui_helpline__vshow(fmt, args);
		else
			ret = vfprintf(stderr, fmt, args);
@@ -145,6 +146,7 @@ static struct debug_variable {
} debug_variables[] = {
	{ .name = "verbose",		.ptr = &verbose },
	{ .name = "ordered-events",	.ptr = &debug_ordered_events},
	{ .name = "stderr",		.ptr = &redirect_to_stderr},
	{ .name = NULL, }
};

Loading