@@ -49,8 +49,52 @@ struct bpf_prog_priv {
49
49
int * type_mapping ;
50
50
};
51
51
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
+
52
84
static bool libbpf_initialized ;
53
85
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
+
54
98
struct bpf_object *
55
99
bpf__prepare_load_buffer (void * obj_buf , size_t obj_buf_sz , const char * name )
56
100
{
@@ -68,9 +112,21 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
68
112
return ERR_PTR (- EINVAL );
69
113
}
70
114
115
+ if (bpf_perf_object__add (obj )) {
116
+ bpf_object__close (obj );
117
+ return ERR_PTR (- ENOMEM );
118
+ }
119
+
71
120
return obj ;
72
121
}
73
122
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
+
74
130
struct bpf_object * bpf__prepare_load (const char * filename , bool source )
75
131
{
76
132
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)
102
158
llvm__dump_obj (filename , obj_buf , obj_buf_sz );
103
159
104
160
free (obj_buf );
105
- } else
161
+ } else {
106
162
obj = bpf_object__open (filename );
163
+ }
107
164
108
165
if (IS_ERR_OR_NULL (obj )) {
109
166
pr_debug ("bpf: failed to load %s\n" , filename );
110
167
return obj ;
111
168
}
112
169
170
+ if (bpf_perf_object__add (obj )) {
171
+ bpf_object__close (obj );
172
+ return ERR_PTR (- BPF_LOADER_ERRNO__COMPILE );
173
+ }
174
+
113
175
return obj ;
114
176
}
115
177
116
178
void bpf__clear (void )
117
179
{
118
- struct bpf_object * obj , * tmp ;
180
+ struct bpf_perf_object * perf_obj , * tmp ;
119
181
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 );
123
185
}
124
186
}
125
187
@@ -1493,38 +1555,36 @@ apply_obj_config_object(struct bpf_object *obj)
1493
1555
1494
1556
int bpf__apply_obj_config (void )
1495
1557
{
1496
- struct bpf_object * obj , * tmp ;
1558
+ struct bpf_perf_object * perf_obj , * tmp ;
1497
1559
int err ;
1498
1560
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 );
1501
1563
if (err )
1502
1564
return err ;
1503
1565
}
1504
1566
1505
1567
return 0 ;
1506
1568
}
1507
1569
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)
1511
1573
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))
1517
1577
1518
1578
struct evsel * bpf__setup_output_event (struct evlist * evlist , const char * name )
1519
1579
{
1520
1580
struct bpf_map_priv * tmpl_priv = NULL ;
1521
- struct bpf_object * obj , * tmp ;
1581
+ struct bpf_perf_object * perf_obj , * tmp ;
1522
1582
struct evsel * evsel = NULL ;
1523
1583
struct bpf_map * map ;
1524
1584
int err ;
1525
1585
bool need_init = false;
1526
1586
1527
- bpf__for_each_map_named (map , obj , tmp , name ) {
1587
+ bpf__perf_for_each_map_named (map , perf_obj , tmp , name ) {
1528
1588
struct bpf_map_priv * priv = bpf_map__priv (map );
1529
1589
1530
1590
if (IS_ERR (priv ))
@@ -1560,7 +1620,7 @@ struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
1560
1620
evsel = evlist__last (evlist );
1561
1621
}
1562
1622
1563
- bpf__for_each_map_named (map , obj , tmp , name ) {
1623
+ bpf__perf_for_each_map_named (map , perf_obj , tmp , name ) {
1564
1624
struct bpf_map_priv * priv = bpf_map__priv (map );
1565
1625
1566
1626
if (IS_ERR (priv ))
0 commit comments