[RFC PATCH 15/22] perf bpf: config eBPF programs using config section.

Wang Nan
2015-04-30T11:00:56Z

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 <wangnan0@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