[RFC PATCH v5 22/30] bpf tools: Link all bpf objects onto a list

From: Wang Nan
Date: Mon Jun 01 2015 - 06:01:29 EST


To prevent caller from creating additional structures to hold
pointers of 'struct bpf_object', this patch link all such
structures onto a list (hidden to user). bpf_object__for_each() is
introduced to allow users iterate over each objects.
bpf_object__for_each() is safe even user close the object during
iteration.

Signed-off-by: Wang Nan <wangnan0@xxxxxxxxxx>
---
tools/lib/bpf/libbpf.c | 32 ++++++++++++++++++++++++++++++++
tools/lib/bpf/libbpf.h | 7 +++++++
2 files changed, 39 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 8ff6b05..1497d6b 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -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;
@@ -135,6 +138,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.fd >= 0)
@@ -240,6 +249,9 @@ static struct bpf_object *bpf_object__new(const char *path)
strcpy(obj->path, path);
obj->efile.fd = -1;
obj->loaded = false;
+
+ INIT_LIST_HEAD(&obj->list);
+ list_add(&obj->list, &bpf_objects_list);
return obj;
}

@@ -877,6 +889,7 @@ void bpf_object__close(struct bpf_object *obj)
}
zfree(&obj->programs);

+ list_del(&obj->list);
free(obj);
}

@@ -889,6 +902,25 @@ int bpf_object__get_prog_cnt(struct bpf_object *obj, size_t *pcnt)
return 0;
}

+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)
{
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 6b144f9..ff1f211 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -36,6 +36,13 @@ int bpf_object__unload(struct bpf_object *obj);
/* Accessors of bpf_object */
int bpf_object__get_prog_cnt(struct bpf_object *obj, size_t *pcnt);

+struct bpf_object *bpf_object__next(struct bpf_object *prev);
+#define bpf_object__for_each(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,
--
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/