This patch creates maps based on 'map' section in object file using
bpf_create_map(), and store the fds into an array in 'struct bpf_obj'.

Signed-off-by: Wang Nan <wangn...@huawei.com>
---
 tools/perf/util/bpf-loader.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/bpf-loader.h |  2 ++
 2 files changed, 55 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 6a1c800..34ccc10 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -117,6 +117,15 @@ static void bpf_obj_close(struct bpf_obj *obj)
                free(obj->maps);
        if (obj->config_str)
                free(obj->config_str);
+       if (obj->maps_fds) {
+               size_t i;
+
+               for (i = 0; i < obj->nr_maps; i++) {
+                       if (obj->maps_fds[i] >= 0)
+                               close(obj->maps_fds[i]);
+               }
+               free(obj->maps_fds);
+       }
        free(obj);
 }
 
@@ -695,6 +704,48 @@ out:
        return err;
 }
 
+static int
+bpf_obj_create_maps(struct bpf_obj *obj)
+{
+       unsigned int i;
+       size_t nr_maps = obj->nr_maps;
+       int *pfd;
+
+       if (!nr_maps) {
+               pr_debug("bpf: don't need create maps for %s\n",
+                        obj->path);
+               return 0;
+       }
+
+       obj->maps_fds = malloc(sizeof(int) * nr_maps);
+       if (!obj->maps_fds) {
+               pr_err("bpf: realloc perf_bpf_maps_fds failed\n");
+               return -ENOMEM;
+       }
+
+       /* fill all fd with -1 */
+       memset(obj->maps_fds, 0xff, sizeof(int) * nr_maps);
+       
+       pfd = obj->maps_fds;
+       for (i = 0; i < nr_maps; i++) {
+               *pfd = bpf_create_map(&obj->maps[i]);
+               if (*pfd < 0) {
+                       size_t j;
+
+                       pr_err("bpf: failed to create map: %s\n",
+                               strerror(errno));
+                       for (j = 0; j < i; i++) {
+                               close(obj->maps_fds[j]);
+                               obj->maps_fds[j] = -1;
+                       }
+                       return *pfd;
+               }
+               pr_debug("bpf: create map: fd=%d\n", *pfd);
+               pfd ++;
+       }
+       return 0;
+}
+
 int bpf__load(const char *path)
 {
        struct bpf_obj *obj;
@@ -723,6 +774,8 @@ int bpf__load(const char *path)
                goto out;
        if ((err = bpf_obj_validate(obj)))
                goto out;
+       if ((err = bpf_obj_create_maps(obj)))
+               goto out;
 
        list_add(&obj->list, &bpf_obj_list);
        return 0;
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 09f77a5..756ac2e 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -46,6 +46,8 @@ struct bpf_obj {
        size_t nr_maps;
        char *config_str;
 
+       int *maps_fds;
+
        /*
         * Information when doing elf related work. Only valid if fd
         * is valid.
-- 
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