By extending the syntax of BPF object section names, this patch allows
user to config probing options like what they can do in 'perf probe'.

Test result:

For following BPF file bpf.c:

 SEC("inlines=no\n"
     "func=SyS_dup?")
 int func(void *ctx)
 {
        return 1;
 }

 Cmdline:

 # ./perf record  -e ./test_probe_glob.c ls /
 ...
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.013 MB perf.data ]
 # ./perf evlist
 perf_bpf_probe:func_1
 perf_bpf_probe:func

Change "inlines=no" to "inlines=yes":

Cmdline:

 # ./perf record  -e ./test_probe_glob.c ls /
 ...
 [ perf record: Woken up 2 times to write data ]
 [ perf record: Captured and wrote 0.013 MB perf.data ]
 # ./perf evlist
 perf_bpf_probe:func_3
 perf_bpf_probe:func_2
 perf_bpf_probe:func_1
 perf_bpf_probe:func

Signed-off-by: Wang Nan <wangn...@huawei.com>
Cc: Alexei Starovoitov <a...@kernel.org>
Cc: Arnaldo Carvalho de Melo <a...@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu...@hitachi.com>
Cc: Zefan Li <lize...@huawei.com>
Cc: pi3or...@163.com
---
 tools/perf/util/bpf-loader.c | 50 +++++++++++++++++++++++++++++++++++++++++++-
 tools/perf/util/config.c     |  9 ++++----
 tools/perf/util/util.c       | 18 ++++++++++++++++
 tools/perf/util/util.h       |  2 ++
 4 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 8d78785..a368ead 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -125,6 +125,38 @@ config__module(const char *value, struct perf_probe_event 
*pev)
        return 0;
 }
 
+static int
+config__bool(const char *value,
+            bool *pbool, bool invert)
+{
+       int err;
+       bool bool_value;
+
+       if (!pbool)
+               return -EINVAL;
+
+       err = convert_str_to_bool(value, &bool_value);
+       if (err)
+               return err;
+
+       *pbool = invert ? !bool_value : bool_value;
+       return 0;
+}
+
+static int
+config__inlines(const char *value,
+               struct perf_probe_event *pev __maybe_unused)
+{
+       return config__bool(value, &probe_conf.no_inlines, true);
+}
+
+static int
+config__force(const char *value,
+             struct perf_probe_event *pev __maybe_unused)
+{
+       return config__bool(value, &probe_conf.force_add, false);
+}
+
 static struct {
        const char *key;
        const char *usage;
@@ -142,7 +174,19 @@ static struct {
                "module=<module name>    ",
                "Set kprobe module",
                config__module,
-       }
+       },
+       {
+               "inlines",
+               "inlines=[yes|no]        ",
+               "Probe at inline symbol",
+               config__inlines,
+       },
+       {
+               "force",
+               "force=[yes|no]          ",
+               "Forcibly add events with existing name",
+               config__force,
+       },
 };
 
 static int
@@ -240,6 +284,10 @@ config_bpf_program(struct bpf_program *prog)
        const char *config_str;
        int err;
 
+       /* Initialize per-program probing setting */
+       probe_conf.no_inlines = false;
+       probe_conf.force_add = false;
+
        config_str = bpf_program__title(prog, false);
        if (IS_ERR(config_str)) {
                pr_debug("bpf: unable to get title for program\n");
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 2e452ac..8219798 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -351,15 +351,16 @@ int perf_config_int(const char *name, const char *value)
 
 static int perf_config_bool_or_int(const char *name, const char *value, int 
*is_bool)
 {
+       bool str_bool;
+
        *is_bool = 1;
        if (!value)
                return 1;
        if (!*value)
                return 0;
-       if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || 
!strcasecmp(value, "on"))
-               return 1;
-       if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || 
!strcasecmp(value, "off"))
-               return 0;
+
+       if (convert_str_to_bool(value, &str_bool) == 0)
+               return str_bool ? 1 : 0;
        *is_bool = 0;
        return perf_config_int(name, value);
 }
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 47b1e36..55785d5 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -695,3 +695,21 @@ fetch_kernel_version(unsigned int *puint, char *str,
                *puint = (version << 16) + (patchlevel << 8) + sublevel;
        return 0;
 }
+
+int convert_str_to_bool(const char *str, bool *result)
+{
+       if (!result || !str)
+               return -EINVAL;
+
+       if (!strcasecmp(str, "true") || !strcasecmp(str, "yes") || 
!strcasecmp(str, "on")) {
+               *result = true;
+               return 0;
+       }
+
+       if (!strcasecmp(str, "false") || !strcasecmp(str, "no") || 
!strcasecmp(str, "off")) {
+               *result = false;
+               return 0;
+       }
+
+       return -EINVAL;
+}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index dcc6590..be90932 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -358,4 +358,6 @@ int fetch_kernel_version(unsigned int *puint,
 #define KVER_FMT       "%d.%d.%d"
 #define KVER_PARAM(x)  KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x)
 
+int convert_str_to_bool(const char *str, bool *result);
+
 #endif /* GIT_COMPAT_UTIL_H */
-- 
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
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