Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/acme/linux into perf/core

Pull perf/core improvements from Arnaldo Carvalho de Melo:

User visible changes:

 - Don't open the DWARF info multiple times, keeping instead a dwfl handle
   in struct dso, greatly speeding up 'perf report' on powerpc. (Sukadev Bhattiprolu)

 - Introduce PARSE_OPT_DISABLED option flag and use it to avoid showing
   undersired options in tools that provides frontends to 'perf record', like
   sched, kvm, etc (Namhyung Kim)

Infrastructure changes:

 - More Intel PT work, including a facility to export sample data (comms,
   threads, symbol names, etc) in a database friendly way, with an script to use
   this to create a postgresql database. (Adrian Hunter)

 - Use make sure that thread->mg->machine points to the machine where
   the thread exists (it was being set only for the kmaps kernel modules
   case, do it as well for the mmaps) and use it to shorten function
   signatures (Arnaldo Carvalho de Melo)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Oct 30, 2014
2 parents d785452 + a293829 commit 05b2537
Show file tree
Hide file tree
Showing 55 changed files with 1,873 additions and 266 deletions.
40 changes: 36 additions & 4 deletions tools/perf/Makefile.perf
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ include config/utilities.mak
#
# Define NO_LIBDW_DWARF_UNWIND if you do not want libdw support
# for dwarf backtrace post unwind.
#
# Define NO_PERF_READ_VDSO32 if you do not want to build perf-read-vdso32
# for reading the 32-bit compatibility VDSO in 64-bit mode
#
# Define NO_PERF_READ_VDSOX32 if you do not want to build perf-read-vdsox32
# for reading the x32 mode 32-bit compatibility VDSO in 64-bit mode

ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
Expand Down Expand Up @@ -171,11 +177,16 @@ $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)

SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))

#
# Single 'perf' binary right now:
#
PROGRAMS += $(OUTPUT)perf

ifndef NO_PERF_READ_VDSO32
PROGRAMS += $(OUTPUT)perf-read-vdso32
endif

ifndef NO_PERF_READ_VDSOX32
PROGRAMS += $(OUTPUT)perf-read-vdsox32
endif

# what 'all' will build and 'install' will install, in perfexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)

Expand Down Expand Up @@ -247,12 +258,14 @@ LIB_H += util/annotate.h
LIB_H += util/cache.h
LIB_H += util/callchain.h
LIB_H += util/build-id.h
LIB_H += util/db-export.h
LIB_H += util/debug.h
LIB_H += util/pmu.h
LIB_H += util/event.h
LIB_H += util/evsel.h
LIB_H += util/evlist.h
LIB_H += util/exec_cmd.h
LIB_H += util/find-vdso-map.c
LIB_H += util/levenshtein.h
LIB_H += util/machine.h
LIB_H += util/map.h
Expand Down Expand Up @@ -311,6 +324,7 @@ LIB_OBJS += $(OUTPUT)util/annotate.o
LIB_OBJS += $(OUTPUT)util/build-id.o
LIB_OBJS += $(OUTPUT)util/config.o
LIB_OBJS += $(OUTPUT)util/ctype.o
LIB_OBJS += $(OUTPUT)util/db-export.o
LIB_OBJS += $(OUTPUT)util/pmu.o
LIB_OBJS += $(OUTPUT)util/environment.o
LIB_OBJS += $(OUTPUT)util/event.o
Expand Down Expand Up @@ -732,6 +746,16 @@ $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Uti
$(OUTPUT)perf-%: %.o $(PERFLIBS)
$(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)

ifndef NO_PERF_READ_VDSO32
$(OUTPUT)perf-read-vdso32: perf-read-vdso.c util/find-vdso-map.c
$(QUIET_CC)$(CC) -m32 $(filter -static,$(LDFLAGS)) -Wall -Werror -o $@ perf-read-vdso.c
endif

ifndef NO_PERF_READ_VDSOX32
$(OUTPUT)perf-read-vdsox32: perf-read-vdso.c util/find-vdso-map.c
$(QUIET_CC)$(CC) -mx32 $(filter -static,$(LDFLAGS)) -Wall -Werror -o $@ perf-read-vdso.c
endif

$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)

Expand Down Expand Up @@ -876,6 +900,14 @@ install-bin: all install-gtk
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'; \
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \
$(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace'
ifndef NO_PERF_READ_VDSO32
$(call QUIET_INSTALL, perf-read-vdso32) \
$(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(bindir_SQ)';
endif
ifndef NO_PERF_READ_VDSOX32
$(call QUIET_INSTALL, perf-read-vdsox32) \
$(INSTALL) $(OUTPUT)perf-read-vdsox32 '$(DESTDIR_SQ)$(bindir_SQ)';
endif
$(call QUIET_INSTALL, libexec) \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(call QUIET_INSTALL, perf-archive) \
Expand Down Expand Up @@ -928,7 +960,7 @@ config-clean:

clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean
$(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS)
$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf
$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
$(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
$(python-clean)
Expand Down
38 changes: 24 additions & 14 deletions tools/perf/arch/powerpc/util/skip-callchain-idx.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc)
* yet used)
* -1 in case of errors
*/
static int check_return_addr(const char *exec_file, Dwarf_Addr pc)
static int check_return_addr(struct dso *dso, Dwarf_Addr pc)
{
int rc = -1;
Dwfl *dwfl;
Expand All @@ -156,15 +156,27 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc)
Dwarf_Addr end = pc;
bool signalp;

dwfl = dwfl_begin(&offline_callbacks);
if (!dwfl) {
pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1));
return -1;
}
dwfl = dso->dwfl;

if (dwfl_report_offline(dwfl, "", exec_file, -1) == NULL) {
pr_debug("dwfl_report_offline() failed %s\n", dwarf_errmsg(-1));
goto out;
if (!dwfl) {
dwfl = dwfl_begin(&offline_callbacks);
if (!dwfl) {
pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1));
return -1;
}

if (dwfl_report_offline(dwfl, "", dso->long_name, -1) == NULL) {
pr_debug("dwfl_report_offline() failed %s\n",
dwarf_errmsg(-1));
/*
* We normally cache the DWARF debug info and never
* call dwfl_end(). But to prevent fd leak, free in
* case of error.
*/
dwfl_end(dwfl);
goto out;
}
dso->dwfl = dwfl;
}

mod = dwfl_addrmodule(dwfl, pc);
Expand Down Expand Up @@ -194,7 +206,6 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc)
rc = check_return_reg(ra_regno, frame);

out:
dwfl_end(dwfl);
return rc;
}

Expand All @@ -221,8 +232,7 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc)
* index: of callchain entry that needs to be ignored (if any)
* -1 if no entry needs to be ignored or in case of errors
*/
int arch_skip_callchain_idx(struct machine *machine, struct thread *thread,
struct ip_callchain *chain)
int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
{
struct addr_location al;
struct dso *dso = NULL;
Expand All @@ -235,7 +245,7 @@ int arch_skip_callchain_idx(struct machine *machine, struct thread *thread,

ip = chain->ips[2];

thread__find_addr_location(thread, machine, PERF_RECORD_MISC_USER,
thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
MAP__FUNCTION, ip, &al);

if (al.map)
Expand All @@ -246,7 +256,7 @@ int arch_skip_callchain_idx(struct machine *machine, struct thread *thread,
return skip_slot;
}

rc = check_return_addr(dso->long_name, ip);
rc = check_return_addr(dso, ip);

pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n",
dso->long_name, chain->nr, ip, rc);
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/builtin-inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
goto repipe;
}

thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
sample->ip, &al);
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al);

if (al.map != NULL) {
if (!al.map->dso->hit) {
Expand Down Expand Up @@ -410,6 +409,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
.tracing_data = perf_event__repipe_op2_synth,
.finished_round = perf_event__repipe_op2_synth,
.build_id = perf_event__repipe_op2_synth,
.id_index = perf_event__repipe_op2_synth,
},
.input_name = "-",
.samples = LIST_HEAD_INIT(inject.samples),
Expand Down
25 changes: 25 additions & 0 deletions tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,10 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
"-m", "1024",
"-c", "1",
};
const char * const kvm_stat_record_usage[] = {
"perf kvm stat record [<options>]",
NULL
};
const char * const *events_tp;
events_tp_size = 0;

Expand Down Expand Up @@ -1159,6 +1163,27 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
for (j = 1; j < (unsigned int)argc; j++, i++)
rec_argv[i] = argv[j];

set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN);
set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN);
set_option_flag(record_options, 'R', "raw-samples", PARSE_OPT_HIDDEN);

set_option_flag(record_options, 'F', "freq", PARSE_OPT_DISABLED);
set_option_flag(record_options, 0, "group", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'g', NULL, PARSE_OPT_DISABLED);
set_option_flag(record_options, 0, "call-graph", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'd', "data", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'T', "timestamp", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'P', "period", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'n', "no-samples", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'N', "no-buildid-cache", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'B', "no-buildid", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'G', "cgroup", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'b', "branch-any", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'j', "branch-filter", PARSE_OPT_DISABLED);
set_option_flag(record_options, 'W', "weight", PARSE_OPT_DISABLED);
set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED);

record_usage = kvm_stat_record_usage;
return cmd_record(i, rec_argv, NULL);
}

Expand Down
65 changes: 20 additions & 45 deletions tools/perf/builtin-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static struct {
bool show_funcs;
bool mod_events;
bool uprobes;
bool quiet;
int nevents;
struct perf_probe_event events[MAX_PROBES];
struct strlist *dellist;
Expand Down Expand Up @@ -312,9 +313,11 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
#endif
NULL
};
const struct option options[] = {
struct option options[] = {
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show parsed arguments, etc)"),
OPT_BOOLEAN('q', "quiet", &params.quiet,
"be quiet (do not show any mesages)"),
OPT_BOOLEAN('l', "list", &params.list_events,
"list up current probe events"),
OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
Expand Down Expand Up @@ -382,6 +385,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
};
int ret;

set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE);
set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE);
set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE);
#ifdef HAVE_DWARF_SUPPORT
set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE);
#endif

argc = parse_options(argc, argv, options, probe_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (argc > 0) {
Expand All @@ -396,6 +407,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
}
}

if (params.quiet) {
if (verbose != 0) {
pr_err(" Error: -v and -q are exclusive.\n");
return -EINVAL;
}
verbose = -1;
}

if (params.max_probe_points == 0)
params.max_probe_points = MAX_PROBES;

Expand All @@ -409,22 +428,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);

if (params.list_events) {
if (params.mod_events) {
pr_err(" Error: Don't use --list with --add/--del.\n");
usage_with_options(probe_usage, options);
}
if (params.show_lines) {
pr_err(" Error: Don't use --list with --line.\n");
usage_with_options(probe_usage, options);
}
if (params.show_vars) {
pr_err(" Error: Don't use --list with --vars.\n");
usage_with_options(probe_usage, options);
}
if (params.show_funcs) {
pr_err(" Error: Don't use --list with --funcs.\n");
usage_with_options(probe_usage, options);
}
if (params.uprobes) {
pr_warning(" Error: Don't use --list with --exec.\n");
usage_with_options(probe_usage, options);
Expand All @@ -435,19 +438,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
return ret;
}
if (params.show_funcs) {
if (params.nevents != 0 || params.dellist) {
pr_err(" Error: Don't use --funcs with"
" --add/--del.\n");
usage_with_options(probe_usage, options);
}
if (params.show_lines) {
pr_err(" Error: Don't use --funcs with --line.\n");
usage_with_options(probe_usage, options);
}
if (params.show_vars) {
pr_err(" Error: Don't use --funcs with --vars.\n");
usage_with_options(probe_usage, options);
}
if (!params.filter)
params.filter = strfilter__new(DEFAULT_FUNC_FILTER,
NULL);
Expand All @@ -462,28 +452,13 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)

#ifdef HAVE_DWARF_SUPPORT
if (params.show_lines) {
if (params.mod_events) {
pr_err(" Error: Don't use --line with"
" --add/--del.\n");
usage_with_options(probe_usage, options);
}
if (params.show_vars) {
pr_err(" Error: Don't use --line with --vars.\n");
usage_with_options(probe_usage, options);
}

ret = show_line_range(&params.line_range, params.target,
params.uprobes);
if (ret < 0)
pr_err_with_code(" Error: Failed to show lines.", ret);
return ret;
}
if (params.show_vars) {
if (params.mod_events) {
pr_err(" Error: Don't use --vars with"
" --add/--del.\n");
usage_with_options(probe_usage, options);
}
if (!params.filter)
params.filter = strfilter__new(DEFAULT_VAR_FILTER,
NULL);
Expand Down
7 changes: 5 additions & 2 deletions tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,11 +680,12 @@ static int perf_record_config(const char *var, const char *value, void *cb)
return perf_default_config(var, value, cb);
}

static const char * const record_usage[] = {
static const char * const __record_usage[] = {
"perf record [<options>] [<command>]",
"perf record [<options>] -- <command> [<options>]",
NULL
};
const char * const *record_usage = __record_usage;

/*
* XXX Ideally would be local to cmd_record() and passed to a record__new
Expand Down Expand Up @@ -725,7 +726,7 @@ const char record_callchain_help[] = CALLCHAIN_HELP "fp";
* perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
* using pipes, etc.
*/
const struct option record_options[] = {
struct option __record_options[] = {
OPT_CALLBACK('e', "event", &record.evlist, "event",
"event selector. use 'perf list' to list available events",
parse_events_option),
Expand Down Expand Up @@ -802,6 +803,8 @@ const struct option record_options[] = {
OPT_END()
};

struct option *record_options = __record_options;

int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
{
int err = -ENOMEM;
Expand Down
Loading

0 comments on commit 05b2537

Please sign in to comment.