bpf tools: Link all bpf objects onto a list
authorWang Nan <wangnan0@huawei.com>
Wed, 1 Jul 2015 02:14:10 +0000 (02:14 +0000)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 7 Aug 2015 13:16:59 +0000 (10:16 -0300)
To allow enumeration of all bpf_objects, keep them in a list (hidden to
caller). bpf_object__for_each_safe() is introduced to do this iteration.
It is safe even user close the object during iteration.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1435716878-189507-23-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf.h

index ae1c5cbd815869e70cc098e79470a7f3e4710881..4fa4bc4505f5b5ecec02758efe3af453f49ec01a 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/unistd.h>
 #include <linux/kernel.h>
 #include <linux/bpf.h>
+#include <linux/list.h>
 #include <libelf.h>
 #include <gelf.h>
 
@@ -104,6 +105,8 @@ struct bpf_program {
        bpf_program_clear_priv_t clear_priv;
 };
 
+static LIST_HEAD(bpf_objects_list);
+
 struct bpf_object {
        char license[64];
        u32 kern_version;
@@ -137,6 +140,12 @@ struct bpf_object {
                } *reloc;
                int nr_reloc;
        } efile;
+       /*
+        * All loaded bpf_object is linked in a list, which is
+        * hidden to caller. bpf_objects__<func> handlers deal with
+        * all objects.
+        */
+       struct list_head list;
        char path[];
 };
 #define obj_elf_valid(o)       ((o)->efile.elf)
@@ -265,6 +274,9 @@ static struct bpf_object *bpf_object__new(const char *path,
        obj->efile.obj_buf_sz = obj_buf_sz;
 
        obj->loaded = false;
+
+       INIT_LIST_HEAD(&obj->list);
+       list_add(&obj->list, &bpf_objects_list);
        return obj;
 }
 
@@ -940,9 +952,29 @@ void bpf_object__close(struct bpf_object *obj)
        }
        zfree(&obj->programs);
 
+       list_del(&obj->list);
        free(obj);
 }
 
+struct bpf_object *
+bpf_object__next(struct bpf_object *prev)
+{
+       struct bpf_object *next;
+
+       if (!prev)
+               next = list_first_entry(&bpf_objects_list,
+                                       struct bpf_object,
+                                       list);
+       else
+               next = list_next_entry(prev, list);
+
+       /* Empty list is noticed here so don't need checking on entry. */
+       if (&next->list == &bpf_objects_list)
+               return NULL;
+
+       return next;
+}
+
 struct bpf_program *
 bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
 {
index 657e497bd5864674d9ff264b3f7082dc83a1242a..ea8adc206b6242ec08dfcc0659b839f7cc79145d 100644 (file)
@@ -35,6 +35,13 @@ void bpf_object__close(struct bpf_object *object);
 int bpf_object__load(struct bpf_object *obj);
 int bpf_object__unload(struct bpf_object *obj);
 
+struct bpf_object *bpf_object__next(struct bpf_object *prev);
+#define bpf_object__for_each_safe(pos, tmp)                    \
+       for ((pos) = bpf_object__next(NULL),            \
+               (tmp) = bpf_object__next(pos);          \
+            (pos) != NULL;                             \
+            (pos) = (tmp), (tmp) = bpf_object__next(tmp))
+
 /* Accessors of bpf_program. */
 struct bpf_program;
 struct bpf_program *bpf_program__next(struct bpf_program *prog,