This patch uses bpf_perf_prog_config() to config perf programs using
config section. In bpf_obj_config(), splits config section into lines
and parse config string line by line.

This patch and previous patch should config all eBPF programs. This
patch also makes bpf_obj_validate() to check programs with no config,
and disable further processing if found one.

Since all programs are configed, obj->config_str us useless. Free it
after configuration done.

Signed-off-by: Wang Nan <wangn...@huawei.com>
---
 tools/perf/util/bpf-loader.c | 56 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index b2871fc..6a1c800 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -476,11 +476,22 @@ out:
 
 static int bpf_obj_validate(struct bpf_obj *obj)
 {
+       struct bpf_perf_prog *prog;
+
        if (obj->kern_version == 0) {
                pr_err("bpf: %s doesn't provide kernel version\n",
                        obj->path);
                return -EINVAL;
        }
+
+       list_for_each_entry(prog, &obj->progs_list, list) {
+               if (!prog->pev) {
+                       pr_err("bpf: program %s doesn't have config.\n",
+                               prog->name);
+                       return -EINVAL;
+
+               }
+       }
        return 0;
 }
 
@@ -635,7 +646,9 @@ static int bpf_perf_prog_config(struct bpf_obj *obj,
 static int bpf_obj_config(struct bpf_obj *obj)
 {
        struct bpf_perf_prog *prog;
-       int err;
+       char *config_str = obj->config_str;
+       char *pend;
+       int err = 0;
 
        /* try to config progs based on their names */
        list_for_each_entry(prog, &obj->progs_list, list) {
@@ -644,7 +657,42 @@ static int bpf_obj_config(struct bpf_obj *obj)
                        return err;
        }
 
-       return 0;
+       /* return if no 'config' section provided */
+       if (!config_str)
+               return 0;
+
+       /* config progs use obj->config_str */
+       pend = config_str + strlen(config_str);
+       while (config_str < pend) {
+               char *ptr;
+
+               /* skip blank lines */
+               if (*config_str == '\n') {
+                       config_str ++;
+                       continue;
+               }
+
+               ptr = strpbrk(config_str, "\n");
+               if (ptr)
+                       *ptr = '\0';
+               err = bpf_perf_prog_config(obj, NULL, config_str);
+               if (err) {
+                       pr_err("bpf config: '%s' is not a valid "
+                              "config string: err %d\n",
+                              config_str, err);
+                       goto out;
+               }
+
+               if (!ptr)
+                       break;
+               config_str = ptr + 1;
+       }
+out:
+       if (obj->config_str) {
+               free(obj->config_str);
+               obj->config_str = NULL;
+       }
+       return err;
 }
 
 int bpf__load(const char *path)
@@ -671,10 +719,10 @@ int bpf__load(const char *path)
                goto out;
        if ((err = bpf_obj_elf_collect(obj)))
                goto out;
-       if ((err = bpf_obj_validate(obj)))
-               goto out;
        if ((err = bpf_obj_config(obj)))
                goto out;
+       if ((err = bpf_obj_validate(obj)))
+               goto out;
 
        list_add(&obj->list, &bpf_obj_list);
        return 0;
-- 
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