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

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

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

Merge tag 'perf-core-for-mingo-20160505' 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:

- Order output of 'perf trace --summary' better, now the threads will
  appear ascending order of number of events, and then, for each, in
  descending order of syscalls by the time spent in the syscalls, so
  that the last page produced can be the one about the most interesting
  thread straced, suggested by Milian Wolff (Arnaldo Carvalho de Melo)

- Do not show the runtime_ms for a thread when not collecting it, that
  is done so far only with 'perf trace --sched' (Arnaldo Carvalho de Melo)

- Fix kallsyms perf test on ppc64le (Naveen N. Rao)

Infrastructure changes:

- Move global variables related to presence of some keys in the sort order to a
  per hist struct, to allow code like the hists browser to work with multiple
  hists with different lists of columns (Jiri Olsa)

- Add support for generating bpf prologue in powerpc (Naveen N. Rao)

- Fix kprobe and kretprobe handling with kallsyms on ppc64le (Naveen N. Rao)

- evlist mmap changes, prep work for supporting reading backwards (Wang Nan)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 1b6de591 b6b85dad
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,4 +3,5 @@ PERF_HAVE_DWARF_REGS := 1
endif

HAVE_KVM_STAT_SUPPORT := 1
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
PERF_HAVE_JITDUMP := 1
+28 −12
Original line number Diff line number Diff line
@@ -10,19 +10,26 @@
 */

#include <stddef.h>
#include <errno.h>
#include <string.h>
#include <dwarf-regs.h>

#include <linux/ptrace.h>
#include <linux/kernel.h>
#include "util.h"

struct pt_regs_dwarfnum {
	const char *name;
	unsigned int dwarfnum;
	unsigned int ptregs_offset;
};

#define STR(s) #s
#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
#define REG_DWARFNUM_NAME(r, num)					\
		{.name = STR(%)STR(r), .dwarfnum = num,			\
		.ptregs_offset = offsetof(struct pt_regs, r)}
#define GPR_DWARFNUM_NAME(num)						\
	{.name = STR(%gpr##num), .dwarfnum = num}
#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
		{.name = STR(%gpr##num), .dwarfnum = num,		\
		.ptregs_offset = offsetof(struct pt_regs, gpr[num])}
#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0, .ptregs_offset = 0}

/*
 * Reference:
@@ -61,12 +68,12 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
	GPR_DWARFNUM_NAME(29),
	GPR_DWARFNUM_NAME(30),
	GPR_DWARFNUM_NAME(31),
	REG_DWARFNUM_NAME("%msr",   66),
	REG_DWARFNUM_NAME("%ctr",   109),
	REG_DWARFNUM_NAME("%link",  108),
	REG_DWARFNUM_NAME("%xer",   101),
	REG_DWARFNUM_NAME("%dar",   119),
	REG_DWARFNUM_NAME("%dsisr", 118),
	REG_DWARFNUM_NAME(msr,   66),
	REG_DWARFNUM_NAME(ctr,   109),
	REG_DWARFNUM_NAME(link,  108),
	REG_DWARFNUM_NAME(xer,   101),
	REG_DWARFNUM_NAME(dar,   119),
	REG_DWARFNUM_NAME(dsisr, 118),
	REG_DWARFNUM_END,
};

@@ -86,3 +93,12 @@ const char *get_arch_regstr(unsigned int n)
			return roff->name;
	return NULL;
}

int regs_query_register_offset(const char *name)
{
	const struct pt_regs_dwarfnum *roff;
	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
		if (!strcmp(roff->name, name))
			return roff->ptregs_offset;
	return -EINVAL;
}
+32 −11
Original line number Diff line number Diff line
@@ -19,12 +19,6 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
	       ehdr.e_type == ET_DYN;
}

#if defined(_CALL_ELF) && _CALL_ELF == 2
void arch__elf_sym_adjust(GElf_Sym *sym)
{
	sym->st_value += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
}
#endif
#endif

#if !defined(_CALL_ELF) || _CALL_ELF != 2
@@ -65,18 +59,45 @@ bool arch__prefers_symtab(void)
	return true;
}

#ifdef HAVE_LIBELF_SUPPORT
void arch__sym_update(struct symbol *s, GElf_Sym *sym)
{
	s->arch_sym = sym->st_other;
}
#endif

#define PPC64LE_LEP_OFFSET	8

void arch__fix_tev_from_maps(struct perf_probe_event *pev,
			     struct probe_trace_event *tev, struct map *map)
			     struct probe_trace_event *tev, struct map *map,
			     struct symbol *sym)
{
	int lep_offset;

	/*
	 * ppc64 ABIv2 local entry point is currently always 2 instructions
	 * (8 bytes) after the global entry point.
	 * When probing at a function entry point, we normally always want the
	 * LEP since that catches calls to the function through both the GEP and
	 * the LEP. Hence, we would like to probe at an offset of 8 bytes if
	 * the user only specified the function entry.
	 *
	 * However, if the user specifies an offset, we fall back to using the
	 * GEP since all userspace applications (objdump/readelf) show function
	 * disassembly with offsets from the GEP.
	 *
	 * In addition, we shouldn't specify an offset for kretprobes.
	 */
	if (!pev->uprobes && map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
		tev->point.address += PPC64LE_LEP_OFFSET;
	if (pev->point.offset || pev->point.retprobe || !map || !sym)
		return;

	lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);

	if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
		tev->point.offset += PPC64LE_LEP_OFFSET;
	else if (lep_offset) {
		if (pev->uprobes)
			tev->point.address += lep_offset;
		else
			tev->point.offset += lep_offset;
	}
}
#endif
+2 −2
Original line number Diff line number Diff line
@@ -428,7 +428,7 @@ static void hists__baseline_only(struct hists *hists)
	struct rb_root *root;
	struct rb_node *next;

	if (sort__need_collapse)
	if (hists__has(hists, need_collapse))
		root = &hists->entries_collapsed;
	else
		root = hists->entries_in;
@@ -450,7 +450,7 @@ static void hists__precompute(struct hists *hists)
	struct rb_root *root;
	struct rb_node *next;

	if (sort__need_collapse)
	if (hists__has(hists, need_collapse))
		root = &hists->entries_collapsed;
	else
		root = hists->entries_in;
+2 −2
Original line number Diff line number Diff line
@@ -234,7 +234,7 @@ static int report__setup_sample_type(struct report *rep)
		sample_type |= PERF_SAMPLE_BRANCH_STACK;

	if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
		if (sort__has_parent) {
		if (perf_hpp_list.parent) {
			ui__error("Selected --sort parent, but no "
				    "callchain data. Did you call "
				    "'perf record' without -g?\n");
@@ -936,7 +936,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
			goto error;
		}

		sort__need_collapse = true;
		perf_hpp_list.need_collapse = true;
	}

	/* Force tty output for header output and per-thread stat. */
Loading