[PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions
From: Masami Hiramatsu
Date: Wed May 06 2015 - 08:49:56 EST
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 <masami.hiramatsu.pt@xxxxxxxxxxx>
---
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@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/