aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorChristy Lee <christylee@fb.com>2022-02-11 23:30:54 -0800
committerArnaldo Carvalho de Melo <acme@redhat.com>2022-02-14 15:50:02 -0300
commite8eaadf45b906572724bf0f198e1be97b663b3d5 (patch)
tree0d9a168e9b3fa97e0864cc4d2c5f02210164509a /tools
parentperf bpf: Stop using deprecated bpf_load_program() API (diff)
downloadlinux-dev-e8eaadf45b906572724bf0f198e1be97b663b3d5.tar.xz
linux-dev-e8eaadf45b906572724bf0f198e1be97b663b3d5.zip
perf bpf: Stop using deprecated bpf_object__next() API
Libbpf has deprecated the ability to keep track of object list inside libbpf, it now requires applications to track usage multiple bpf objects directly. Remove usage of bpf_object__next() API and hoist the tracking logic to perf. Signed-off-by: Christy Lee <christylee@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: bpf@vger.kernel.org Cc: kernel-team@fb.com Link: https://lore.kernel.org/bpf/20220212073054.1052880-3-andrii@kernel.org Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/bpf-loader.c98
1 files changed, 79 insertions, 19 deletions
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 7ecfaac7536a..db61e09be585 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -49,8 +49,52 @@ struct bpf_prog_priv {
int *type_mapping;
};
+struct bpf_perf_object {
+ struct list_head list;
+ struct bpf_object *obj;
+};
+
+static LIST_HEAD(bpf_objects_list);
+
+static struct bpf_perf_object *
+bpf_perf_object__next(struct bpf_perf_object *prev)
+{
+ struct bpf_perf_object *next;
+
+ if (!prev)
+ next = list_first_entry(&bpf_objects_list,
+ struct bpf_perf_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;
+}
+
+#define bpf_perf_object__for_each(perf_obj, tmp) \
+ for ((perf_obj) = bpf_perf_object__next(NULL), \
+ (tmp) = bpf_perf_object__next(perf_obj); \
+ (perf_obj) != NULL; \
+ (perf_obj) = (tmp), (tmp) = bpf_perf_object__next(tmp))
+
static bool libbpf_initialized;
+static int bpf_perf_object__add(struct bpf_object *obj)
+{
+ struct bpf_perf_object *perf_obj = zalloc(sizeof(*perf_obj));
+
+ if (perf_obj) {
+ INIT_LIST_HEAD(&perf_obj->list);
+ perf_obj->obj = obj;
+ list_add_tail(&perf_obj->list, &bpf_objects_list);
+ }
+ return perf_obj ? 0 : -ENOMEM;
+}
+
struct bpf_object *
bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
{
@@ -67,9 +111,21 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
return ERR_PTR(-EINVAL);
}
+ if (bpf_perf_object__add(obj)) {
+ bpf_object__close(obj);
+ return ERR_PTR(-ENOMEM);
+ }
+
return obj;
}
+static void bpf_perf_object__close(struct bpf_perf_object *perf_obj)
+{
+ list_del(&perf_obj->list);
+ bpf_object__close(perf_obj->obj);
+ free(perf_obj);
+}
+
struct bpf_object *bpf__prepare_load(const char *filename, bool source)
{
struct bpf_object *obj;
@@ -100,24 +156,30 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
llvm__dump_obj(filename, obj_buf, obj_buf_sz);
free(obj_buf);
- } else
+ } else {
obj = bpf_object__open(filename);
+ }
if (IS_ERR_OR_NULL(obj)) {
pr_debug("bpf: failed to load %s\n", filename);
return obj;
}
+ if (bpf_perf_object__add(obj)) {
+ bpf_object__close(obj);
+ return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
+ }
+
return obj;
}
void bpf__clear(void)
{
- struct bpf_object *obj, *tmp;
+ struct bpf_perf_object *perf_obj, *tmp;
- bpf_object__for_each_safe(obj, tmp) {
- bpf__unprobe(obj);
- bpf_object__close(obj);
+ bpf_perf_object__for_each(perf_obj, tmp) {
+ bpf__unprobe(perf_obj->obj);
+ bpf_perf_object__close(perf_obj);
}
}
@@ -1501,11 +1563,11 @@ apply_obj_config_object(struct bpf_object *obj)
int bpf__apply_obj_config(void)
{
- struct bpf_object *obj, *tmp;
+ struct bpf_perf_object *perf_obj, *tmp;
int err;
- bpf_object__for_each_safe(obj, tmp) {
- err = apply_obj_config_object(obj);
+ bpf_perf_object__for_each(perf_obj, tmp) {
+ err = apply_obj_config_object(perf_obj->obj);
if (err)
return err;
}
@@ -1513,26 +1575,24 @@ int bpf__apply_obj_config(void)
return 0;
}
-#define bpf__for_each_map(pos, obj, objtmp) \
- bpf_object__for_each_safe(obj, objtmp) \
- bpf_object__for_each_map(pos, obj)
+#define bpf__perf_for_each_map(map, pobj, tmp) \
+ bpf_perf_object__for_each(pobj, tmp) \
+ bpf_object__for_each_map(map, pobj->obj)
-#define bpf__for_each_map_named(pos, obj, objtmp, name) \
- bpf__for_each_map(pos, obj, objtmp) \
- if (bpf_map__name(pos) && \
- (strcmp(name, \
- bpf_map__name(pos)) == 0))
+#define bpf__perf_for_each_map_named(map, pobj, pobjtmp, name) \
+ bpf__perf_for_each_map(map, pobj, pobjtmp) \
+ if (bpf_map__name(map) && (strcmp(name, bpf_map__name(map)) == 0))
struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
{
struct bpf_map_priv *tmpl_priv = NULL;
- struct bpf_object *obj, *tmp;
+ struct bpf_perf_object *perf_obj, *tmp;
struct evsel *evsel = NULL;
struct bpf_map *map;
int err;
bool need_init = false;
- bpf__for_each_map_named(map, obj, tmp, name) {
+ bpf__perf_for_each_map_named(map, perf_obj, tmp, name) {
struct bpf_map_priv *priv = bpf_map__priv(map);
if (IS_ERR(priv))
@@ -1568,7 +1628,7 @@ struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
evsel = evlist__last(evlist);
}
- bpf__for_each_map_named(map, obj, tmp, name) {
+ bpf__perf_for_each_map_named(map, perf_obj, tmp, name) {
struct bpf_map_priv *priv = bpf_map__priv(map);
if (IS_ERR(priv))