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 <[email protected]>
---
 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", &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,
@@ -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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to