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>
This commit is contained in:
Christy Lee 2022-02-11 23:30:54 -08:00 committed by Arnaldo Carvalho de Melo
parent 710f6c38bc
commit e8eaadf45b

View File

@ -49,8 +49,52 @@ struct bpf_prog_priv {
int *type_mapping; 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 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 * struct bpf_object *
bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) 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); return ERR_PTR(-EINVAL);
} }
if (bpf_perf_object__add(obj)) {
bpf_object__close(obj);
return ERR_PTR(-ENOMEM);
}
return obj; 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 *bpf__prepare_load(const char *filename, bool source)
{ {
struct bpf_object *obj; 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); llvm__dump_obj(filename, obj_buf, obj_buf_sz);
free(obj_buf); free(obj_buf);
} else } else {
obj = bpf_object__open(filename); obj = bpf_object__open(filename);
}
if (IS_ERR_OR_NULL(obj)) { if (IS_ERR_OR_NULL(obj)) {
pr_debug("bpf: failed to load %s\n", filename); pr_debug("bpf: failed to load %s\n", filename);
return obj; return obj;
} }
if (bpf_perf_object__add(obj)) {
bpf_object__close(obj);
return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
}
return obj; return obj;
} }
void bpf__clear(void) void bpf__clear(void)
{ {
struct bpf_object *obj, *tmp; struct bpf_perf_object *perf_obj, *tmp;
bpf_object__for_each_safe(obj, tmp) { bpf_perf_object__for_each(perf_obj, tmp) {
bpf__unprobe(obj); bpf__unprobe(perf_obj->obj);
bpf_object__close(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) int bpf__apply_obj_config(void)
{ {
struct bpf_object *obj, *tmp; struct bpf_perf_object *perf_obj, *tmp;
int err; int err;
bpf_object__for_each_safe(obj, tmp) { bpf_perf_object__for_each(perf_obj, tmp) {
err = apply_obj_config_object(obj); err = apply_obj_config_object(perf_obj->obj);
if (err) if (err)
return err; return err;
} }
@ -1513,26 +1575,24 @@ int bpf__apply_obj_config(void)
return 0; return 0;
} }
#define bpf__for_each_map(pos, obj, objtmp) \ #define bpf__perf_for_each_map(map, pobj, tmp) \
bpf_object__for_each_safe(obj, objtmp) \ bpf_perf_object__for_each(pobj, tmp) \
bpf_object__for_each_map(pos, obj) bpf_object__for_each_map(map, pobj->obj)
#define bpf__for_each_map_named(pos, obj, objtmp, name) \ #define bpf__perf_for_each_map_named(map, pobj, pobjtmp, name) \
bpf__for_each_map(pos, obj, objtmp) \ bpf__perf_for_each_map(map, pobj, pobjtmp) \
if (bpf_map__name(pos) && \ if (bpf_map__name(map) && (strcmp(name, bpf_map__name(map)) == 0))
(strcmp(name, \
bpf_map__name(pos)) == 0))
struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name) struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
{ {
struct bpf_map_priv *tmpl_priv = NULL; struct bpf_map_priv *tmpl_priv = NULL;
struct bpf_object *obj, *tmp; struct bpf_perf_object *perf_obj, *tmp;
struct evsel *evsel = NULL; struct evsel *evsel = NULL;
struct bpf_map *map; struct bpf_map *map;
int err; int err;
bool need_init = false; 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); struct bpf_map_priv *priv = bpf_map__priv(map);
if (IS_ERR(priv)) if (IS_ERR(priv))
@ -1568,7 +1628,7 @@ struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
evsel = evlist__last(evlist); 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); struct bpf_map_priv *priv = bpf_map__priv(map);
if (IS_ERR(priv)) if (IS_ERR(priv))