@@ -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+
5284static 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+
5498struct bpf_object *
5599bpf__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+
74130struct 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
116178void 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
14941556int 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
15181578struct 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