[PATCH perf/core 4/6] perf-probe: Add --no-inlines option to avoid searching inline functions

From: Masami Hiramatsu
Date: Fri Oct 31 2014 - 06:55:57 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 | 21 +++++++++++++--------
tools/perf/util/probe-event.h | 3 ++-
tools/perf/util/probe-finder.c | 8 +++++---
tools/perf/util/probe-finder.h | 3 ++-
6 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 6f183ab..835f685 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -81,6 +81,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::
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 c2fa3a3..a910cbc 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -55,6 +55,7 @@ static struct {
bool show_funcs;
bool mod_events;
bool uprobes;
+ bool no_inlines;
bool quiet;
int nevents;
struct perf_probe_event events[MAX_PROBES];
@@ -386,6 +387,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", &params.no_inlines,
+ "Don't search inlined functions"),
#endif
OPT__DRY_RUN(&probe_event_dry_run),
OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -512,7 +515,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.target, params.output,
- 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 2aab9c9..0062114 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -462,7 +462,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 debuginfo *dinfo;
@@ -479,7 +480,8 @@ 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);

debuginfo__delete(dinfo);

@@ -812,7 +814,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");
@@ -2349,8 +2352,9 @@ err_out:
}

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;

@@ -2364,7 +2368,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 */

@@ -2379,7 +2384,7 @@ struct __event_package {

int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
int max_tevs, const char *target, const char *output,
- bool force_add)
+ bool force_add, bool no_inline)
{
int i, j, ret;
struct __event_package *pkgs;
@@ -2416,7 +2421,7 @@ 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,
- target);
+ 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 df91d0a..93d0b10 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -125,7 +125,8 @@ 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, const char *module,
- const char *output, bool force_add);
+ const char *output, bool force_add,
+ bool no_inline);
extern int del_perf_probe_events(struct strlist *dellist);
extern int show_perf_probe_events(void);
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 1914dfd..0c6f6f2 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -926,7 +926,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);
@@ -1178,10 +1178,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 92590b2..2b77339 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,
@@ -76,6 +76,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/