Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751650AbbEFMty (ORCPT ); Wed, 6 May 2015 08:49:54 -0400 Received: from mail7.hitachi.co.jp ([133.145.228.42]:36965 "EHLO mail7.hitachi.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752438AbbEFMs5 (ORCPT ); Wed, 6 May 2015 08:48:57 -0400 X-AuditID: 85900ec0-a1ec9b9000003d4c-65-554a0dabc8fe Subject: [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions From: Masami Hiramatsu To: Arnaldo Carvalho de Melo Cc: ananth@in.ibm.com, Peter Zijlstra , hemant@linux.vnet.ibm.com, Linux Kernel Mailing List , David Ahern , namhyung@kernel.org, Jiri Olsa , Ingo Molnar Date: Wed, 06 May 2015 21:46:51 +0900 Message-ID: <20150506124651.4961.11.stgit@localhost.localdomain> In-Reply-To: <20150506124638.4961.3172.stgit@localhost.localdomain> References: <20150506124638.4961.3172.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Brightmail-Tracker: AAAAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8534 Lines: 214 Add --no-inlines(--inlines) option to avoid searching inline functions. Searching all functions which matches glob pattern can take a long time and find a lot of inline functions. With this option perf-probe searches target on the non-inlined functions. Signed-off-by: Masami Hiramatsu --- tools/perf/Documentation/perf-probe.txt | 4 ++++ tools/perf/builtin-probe.c | 6 +++++- tools/perf/util/probe-event.c | 25 ++++++++++++++++--------- tools/perf/util/probe-event.h | 3 ++- tools/perf/util/probe-finder.c | 8 +++++--- tools/perf/util/probe-finder.h | 3 ++- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index a272f2e..a1637ce 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -83,6 +83,10 @@ OPTIONS (Only for --vars) Show external defined variables in addition to local variables. +--no-inlines:: + (Only for --add) Search only for non-inlined functions. The functions + which do not have instances are ignored. + -F:: --funcs[=FILTER]:: Show available functions in given module or kernel. With -x/--exec, diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 9c4cf5e..be7f25f 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -53,6 +53,7 @@ static struct { bool force_add; bool show_ext_vars; bool uprobes; + bool no_inlines; bool quiet; bool target_used; int nevents; @@ -382,6 +383,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) OPT_CALLBACK('m', "module", NULL, "modname|path", "target module name (for online) or path (for offline)", opt_set_target), + OPT_BOOLEAN('\0', "no-inlines", ¶ms.no_inlines, + "Don't search inlined functions"), #endif OPT__DRY_RUN(&probe_event_dry_run), OPT_INTEGER('\0', "max-probes", ¶ms.max_probe_points, @@ -501,7 +504,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) ret = add_perf_probe_events(params.events, params.nevents, params.max_probe_points, - params.force_add); + params.force_add, + params.no_inlines); if (ret < 0) { pr_err_with_code(" Error: Failed to add events.", ret); return ret; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 37a3a8b..c9805fd 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -601,7 +601,8 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs, /* Try to find perf_probe_event with debuginfo */ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event **tevs, - int max_tevs, const char *target) + int max_tevs, const char *target, + bool no_inline) { bool need_dwarf = perf_probe_event_need_dwarf(pev); struct perf_probe_point tmp; @@ -619,13 +620,15 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, pr_debug("Try to find probe point from debuginfo.\n"); /* Searching trace events corresponding to a probe event */ - ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs); + ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs, + no_inline); if (ntevs == 0) { /* Not found, retry with an alternative */ ret = get_alternative_probe_event(dinfo, pev, &tmp, target); if (!ret) { ntevs = debuginfo__find_trace_events(dinfo, pev, - tevs, max_tevs); + tevs, max_tevs, + no_inline); /* * Write back to the original probe_event for * setting appropriate (user given) event name @@ -932,7 +935,8 @@ find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused, static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event **tevs __maybe_unused, int max_tevs __maybe_unused, - const char *target __maybe_unused) + const char *target __maybe_unused, + bool no_inline __maybe_unused) { if (perf_probe_event_need_dwarf(pev)) { pr_warning("Debuginfo-analysis is not supported.\n"); @@ -2638,8 +2642,9 @@ err_out: bool __weak arch__prefers_symtab(void) { return false; } static int convert_to_probe_trace_events(struct perf_probe_event *pev, - struct probe_trace_event **tevs, - int max_tevs, const char *target) + struct probe_trace_event **tevs, + int max_tevs, const char *target, + bool no_inline) { int ret; @@ -2659,7 +2664,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, } /* Convert perf_probe_event with debuginfo */ - ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); + ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target, + no_inline); if (ret != 0) return ret; /* Found in debuginfo or got an error */ @@ -2673,7 +2679,7 @@ struct __event_package { }; int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, - int max_tevs, bool force_add) + int max_tevs, bool force_add, bool no_inline) { int i, j, ret; struct __event_package *pkgs; @@ -2697,7 +2703,8 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, ret = convert_to_probe_trace_events(pkgs[i].pev, &pkgs[i].tevs, max_tevs, - pkgs[i].pev->target); + pkgs[i].pev->target, + no_inline); if (ret < 0) goto end; pkgs[i].ntevs = ret; diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index e10aedc..f883670 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -125,7 +125,8 @@ extern int line_range__init(struct line_range *lr); extern const char *kernel_get_module_path(const char *module); extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, - int max_probe_points, bool force_add); + int max_probe_points, bool force_add, + bool no_inline); extern int del_perf_probe_events(struct strfilter *filter); extern int show_perf_probe_events(struct strfilter *filter); extern int show_line_range(struct line_range *lr, const char *module, diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 44554c3..a37b439 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -943,7 +943,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) /* TODO: Check the address in this function */ param->retval = call_probe_finder(sp_die, pf); } - } else + } else if (!pf->no_inline) /* Inlined function: search instances */ param->retval = die_walk_instances(sp_die, probe_point_inline_cb, (void *)pf); @@ -1211,10 +1211,12 @@ end: /* Find probe_trace_events specified by perf_probe_event from debuginfo */ int debuginfo__find_trace_events(struct debuginfo *dbg, struct perf_probe_event *pev, - struct probe_trace_event **tevs, int max_tevs) + struct probe_trace_event **tevs, + int max_tevs, bool no_inline) { struct trace_event_finder tf = { - .pf = {.pev = pev, .callback = add_probe_trace_event}, + .pf = {.pev = pev, .callback = add_probe_trace_event, + .no_inline = no_inline}, .mod = dbg->mod, .max_tevs = max_tevs}; int ret; diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index ebf8c8c..996f007 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -38,7 +38,7 @@ extern void debuginfo__delete(struct debuginfo *dbg); extern int debuginfo__find_trace_events(struct debuginfo *dbg, struct perf_probe_event *pev, struct probe_trace_event **tevs, - int max_tevs); + int max_tevs, bool no_inline); /* Find a perf_probe_point from debuginfo */ extern int debuginfo__find_probe_point(struct debuginfo *dbg, @@ -80,6 +80,7 @@ struct probe_finder { Dwarf_Op *fb_ops; /* Frame base attribute */ struct perf_probe_arg *pvar; /* Current target variable */ struct probe_trace_arg *tvar; /* Current result variable */ + bool no_inline; /* Do not find inlines */ }; struct trace_event_finder { -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/