Skip to content

Commit 06b9d72

Browse files
christycyleeNobody
authored andcommitted
perf: 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. Acked-by: Song Liu <[email protected]> Signed-off-by: Christy Lee <[email protected]> Signed-off-by: Jiri Olsa <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]>
1 parent 27f32b9 commit 06b9d72

File tree

1 file changed

+79
-19
lines changed

1 file changed

+79
-19
lines changed

tools/perf/util/bpf-loader.c

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,52 @@ struct bpf_prog_priv {
4949
int *type_mapping;
5050
};
5151

52+
struct bpf_perf_object {
53+
struct list_head list;
54+
struct bpf_object *obj;
55+
};
56+
57+
static LIST_HEAD(bpf_objects_list);
58+
59+
static struct bpf_perf_object *
60+
bpf_perf_object__next(struct bpf_perf_object *prev)
61+
{
62+
struct bpf_perf_object *next;
63+
64+
if (!prev)
65+
next = list_first_entry(&bpf_objects_list,
66+
struct bpf_perf_object,
67+
list);
68+
else
69+
next = list_next_entry(prev, list);
70+
71+
/* Empty list is noticed here so don't need checking on entry. */
72+
if (&next->list == &bpf_objects_list)
73+
return NULL;
74+
75+
return next;
76+
}
77+
78+
#define bpf_perf_object__for_each(perf_obj, tmp) \
79+
for ((perf_obj) = bpf_perf_object__next(NULL), \
80+
(tmp) = bpf_perf_object__next(perf_obj); \
81+
(perf_obj) != NULL; \
82+
(perf_obj) = (tmp), (tmp) = bpf_perf_object__next(tmp))
83+
5284
static bool libbpf_initialized;
5385

86+
static int bpf_perf_object__add(struct bpf_object *obj)
87+
{
88+
struct bpf_perf_object *perf_obj = zalloc(sizeof(*perf_obj));
89+
90+
if (perf_obj) {
91+
INIT_LIST_HEAD(&perf_obj->list);
92+
perf_obj->obj = obj;
93+
list_add_tail(&perf_obj->list, &bpf_objects_list);
94+
}
95+
return perf_obj ? 0 : -ENOMEM;
96+
}
97+
5498
struct bpf_object *
5599
bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
56100
{
@@ -68,9 +112,21 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
68112
return ERR_PTR(-EINVAL);
69113
}
70114

115+
if (bpf_perf_object__add(obj)) {
116+
bpf_object__close(obj);
117+
return ERR_PTR(-ENOMEM);
118+
}
119+
71120
return obj;
72121
}
73122

123+
static void bpf_perf_object__close(struct bpf_perf_object *perf_obj)
124+
{
125+
list_del(&perf_obj->list);
126+
bpf_object__close(perf_obj->obj);
127+
free(perf_obj);
128+
}
129+
74130
struct bpf_object *bpf__prepare_load(const char *filename, bool source)
75131
{
76132
LIBBPF_OPTS(bpf_object_open_opts, opts, .object_name = filename);
@@ -102,24 +158,30 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
102158
llvm__dump_obj(filename, obj_buf, obj_buf_sz);
103159

104160
free(obj_buf);
105-
} else
161+
} else {
106162
obj = bpf_object__open(filename);
163+
}
107164

108165
if (IS_ERR_OR_NULL(obj)) {
109166
pr_debug("bpf: failed to load %s\n", filename);
110167
return obj;
111168
}
112169

170+
if (bpf_perf_object__add(obj)) {
171+
bpf_object__close(obj);
172+
return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
173+
}
174+
113175
return obj;
114176
}
115177

116178
void bpf__clear(void)
117179
{
118-
struct bpf_object *obj, *tmp;
180+
struct bpf_perf_object *perf_obj, *tmp;
119181

120-
bpf_object__for_each_safe(obj, tmp) {
121-
bpf__unprobe(obj);
122-
bpf_object__close(obj);
182+
bpf_perf_object__for_each(perf_obj, tmp) {
183+
bpf__unprobe(perf_obj->obj);
184+
bpf_perf_object__close(perf_obj);
123185
}
124186
}
125187

@@ -1493,38 +1555,36 @@ apply_obj_config_object(struct bpf_object *obj)
14931555

14941556
int bpf__apply_obj_config(void)
14951557
{
1496-
struct bpf_object *obj, *tmp;
1558+
struct bpf_perf_object *perf_obj, *tmp;
14971559
int err;
14981560

1499-
bpf_object__for_each_safe(obj, tmp) {
1500-
err = apply_obj_config_object(obj);
1561+
bpf_perf_object__for_each(perf_obj, tmp) {
1562+
err = apply_obj_config_object(perf_obj->obj);
15011563
if (err)
15021564
return err;
15031565
}
15041566

15051567
return 0;
15061568
}
15071569

1508-
#define bpf__for_each_map(pos, obj, objtmp) \
1509-
bpf_object__for_each_safe(obj, objtmp) \
1510-
bpf_object__for_each_map(pos, obj)
1570+
#define bpf__perf_for_each_map(map, pobj, tmp) \
1571+
bpf_perf_object__for_each(pobj, tmp) \
1572+
bpf_object__for_each_map(map, pobj->obj)
15111573

1512-
#define bpf__for_each_map_named(pos, obj, objtmp, name) \
1513-
bpf__for_each_map(pos, obj, objtmp) \
1514-
if (bpf_map__name(pos) && \
1515-
(strcmp(name, \
1516-
bpf_map__name(pos)) == 0))
1574+
#define bpf__perf_for_each_map_named(map, pobj, pobjtmp, name) \
1575+
bpf__perf_for_each_map(map, pobj, pobjtmp) \
1576+
if (bpf_map__name(map) && (strcmp(name, bpf_map__name(map)) == 0))
15171577

15181578
struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
15191579
{
15201580
struct bpf_map_priv *tmpl_priv = NULL;
1521-
struct bpf_object *obj, *tmp;
1581+
struct bpf_perf_object *perf_obj, *tmp;
15221582
struct evsel *evsel = NULL;
15231583
struct bpf_map *map;
15241584
int err;
15251585
bool need_init = false;
15261586

1527-
bpf__for_each_map_named(map, obj, tmp, name) {
1587+
bpf__perf_for_each_map_named(map, perf_obj, tmp, name) {
15281588
struct bpf_map_priv *priv = bpf_map__priv(map);
15291589

15301590
if (IS_ERR(priv))
@@ -1560,7 +1620,7 @@ struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
15601620
evsel = evlist__last(evlist);
15611621
}
15621622

1563-
bpf__for_each_map_named(map, obj, tmp, name) {
1623+
bpf__perf_for_each_map_named(map, perf_obj, tmp, name) {
15641624
struct bpf_map_priv *priv = bpf_map__priv(map);
15651625

15661626
if (IS_ERR(priv))

0 commit comments

Comments
 (0)