Fix eBPF load on RH 8.x family and improve code. (#14090)
thiagoftsm committed
Dec 12, 2022 at 12:39 UTC
d127c108eb9050693c8c7c92d72d4b3177b84959
19 files changed
+147
-55
collectors/ebpf.plugin/ebpf.h
+3
@@ -123,6 +123,9 @@ enum ebpf_threads_status {
123
#endif
124
#endif
125
126
+// Messages
127
+#define NETDATA_EBPF_DEFAULT_FNT_NOT_FOUND "Cannot find the necessary functions to monitor"
128
+
129
// Chart definitions
130
#define NETDATA_EBPF_FAMILY "ebpf"
131
#define NETDATA_EBPF_IP_FAMILY "ip"
collectors/ebpf.plugin/ebpf_cachestat.c
+45
-18
@@ -51,6 +51,9 @@ netdata_ebpf_targets_t cachestat_targets[] = { {.name = "add_to_page_cache_lru",
51
{.name = "mark_buffer_dirty", .mode = EBPF_LOAD_TRAMPOLINE},
52
{.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
53
54
+static char *account_page[NETDATA_CACHESTAT_ACCOUNT_DIRTY_END] ={ "account_page_dirtied",
55
+ "__set_page_dirty", "__folio_mark_dirty" };
56
+
57
#ifdef LIBBPF_MAJOR_VERSION
58
#include "includes/cachestat.skel.h" // BTF code
59
@@ -83,10 +86,12 @@ static void ebpf_cachestat_disable_probe(struct cachestat_bpf *obj)
86
*/
87
static void ebpf_cachestat_disable_specific_probe(struct cachestat_bpf *obj)
88
{
86
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_16) {
89
+ if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
90
+ account_page[NETDATA_CACHESTAT_FOLIO_DIRTY])) {
91
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_kprobe, false);
92
bpf_program__set_autoload(obj->progs.netdata_set_page_dirty_kprobe, false);
89
- } else if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_15) {
93
+ } else if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
94
+ account_page[NETDATA_CACHESTAT_SET_PAGE_DIRTY])) {
95
bpf_program__set_autoload(obj->progs.netdata_folio_mark_dirty_kprobe, false);
96
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_kprobe, false);
97
} else {
@@ -122,10 +127,12 @@ static void ebpf_cachestat_disable_trampoline(struct cachestat_bpf *obj)
127
*/
128
static void ebpf_cachestat_disable_specific_trampoline(struct cachestat_bpf *obj)
129
{
125
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_16) {
130
+ if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
131
+ account_page[NETDATA_CACHESTAT_FOLIO_DIRTY])) {
132
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_fentry, false);
133
bpf_program__set_autoload(obj->progs.netdata_set_page_dirty_fentry, false);
128
- } else if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_15) {
134
+ } else if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
135
+ account_page[NETDATA_CACHESTAT_SET_PAGE_DIRTY])) {
136
bpf_program__set_autoload(obj->progs.netdata_folio_mark_dirty_fentry, false);
137
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_fentry, false);
138
} else {
@@ -149,10 +156,12 @@ static inline void netdata_set_trampoline_target(struct cachestat_bpf *obj)
156
bpf_program__set_attach_target(obj->progs.netdata_mark_page_accessed_fentry, 0,
157
cachestat_targets[NETDATA_KEY_CALLS_MARK_PAGE_ACCESSED].name);
158
152
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_16) {
159
+ if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
160
+ account_page[NETDATA_CACHESTAT_FOLIO_DIRTY])) {
161
bpf_program__set_attach_target(obj->progs.netdata_folio_mark_dirty_fentry, 0,
162
cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name);
155
- } else if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_15) {
163
+ } else if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
164
+ account_page[NETDATA_CACHESTAT_SET_PAGE_DIRTY])) {
165
bpf_program__set_attach_target(obj->progs.netdata_set_page_dirty_fentry, 0,
166
cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name);
167
} else {
@@ -192,12 +201,14 @@ static int ebpf_cachestat_attach_probe(struct cachestat_bpf *obj)
201
if (ret)
202
return -1;
203
195
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_16) {
204
+ if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
205
+ account_page[NETDATA_CACHESTAT_FOLIO_DIRTY])) {
206
obj->links.netdata_folio_mark_dirty_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_folio_mark_dirty_kprobe,
207
false,
208
cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name);
209
ret = libbpf_get_error(obj->links.netdata_folio_mark_dirty_kprobe);
200
- } else if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_15) {
210
+ } else if (!strcmp(cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name,
211
+ account_page[NETDATA_CACHESTAT_SET_PAGE_DIRTY])) {
212
obj->links.netdata_set_page_dirty_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_set_page_dirty_kprobe,
213
false,
214
cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name);
@@ -363,7 +374,8 @@ static void ebpf_cachestat_free(ebpf_module_t *em)
374
static void ebpf_cachestat_exit(void *ptr)
375
{
376
ebpf_module_t *em = (ebpf_module_t *)ptr;
366
- netdata_thread_cancel(*cachestat_threads.thread);
377
+ if (cachestat_threads.thread)
378
+ netdata_thread_cancel(*cachestat_threads.thread);
379
ebpf_cachestat_free(em);
380
}
381
@@ -1237,16 +1249,28 @@ static void ebpf_cachestat_allocate_global_vectors(int apps)
1249
* Update Internal value
1250
*
1251
* Update values used during runtime.
1252
+ *
1253
+ * @return It returns 0 when one of the functions is present and -1 otherwise.
1254
*/
1241
-static void ebpf_cachestat_set_internal_value()
1255
+static int ebpf_cachestat_set_internal_value()
1256
{
1243
- static char *account_page[] = { "account_page_dirtied", "__set_page_dirty", "__folio_mark_dirty" };
1244
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_16)
1245
- cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name = account_page[NETDATA_CACHESTAT_FOLIO_DIRTY];
1246
- else if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_15)
1247
- cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name = account_page[NETDATA_CACHESTAT_SET_PAGE_DIRTY];
1248
- else
1249
- cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name = account_page[NETDATA_CACHESTAT_ACCOUNT_PAGE_DIRTY];
1257
+ ebpf_addresses_t address = {.function = NULL, .hash = 0, .addr = 0};
1258
+ int i;
1259
+ for (i = 0; i < NETDATA_CACHESTAT_ACCOUNT_DIRTY_END ; i++) {
1260
+ address.function = account_page[i];
1261
+ ebpf_load_addresses(&address, -1);
1262
+ if (address.addr)
1263
+ break;
1264
+ }
1265
+
1266
+ if (!address.addr) {
1267
+ error("%s cachestat.", NETDATA_EBPF_DEFAULT_FNT_NOT_FOUND);
1268
+ return -1;
1269
+ }
1270
+
1271
+ cachestat_targets[NETDATA_KEY_CALLS_ACCOUNT_PAGE_DIRTIED].name = address.function;
1272
+
1273
+ return 0;
1274
}
1275
1276
/*
@@ -1300,7 +1324,10 @@ void *ebpf_cachestat_thread(void *ptr)
1324
1325
ebpf_update_pid_table(&cachestat_maps[NETDATA_CACHESTAT_PID_STATS], em);
1326
1303
- ebpf_cachestat_set_internal_value();
1327
+ if (ebpf_cachestat_set_internal_value()) {
1328
+ em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1329
+ goto endcachestat;
1330
+ }
1331
1332
#ifdef LIBBPF_MAJOR_VERSION
1333
ebpf_adjust_thread_load(em, default_btf);
collectors/ebpf.plugin/ebpf_cachestat.h
+3
-1
@@ -48,7 +48,9 @@ enum cachestat_counters {
48
enum cachestat_account_dirty_pages {
49
NETDATA_CACHESTAT_ACCOUNT_PAGE_DIRTY,
50
NETDATA_CACHESTAT_SET_PAGE_DIRTY,
51
- NETDATA_CACHESTAT_FOLIO_DIRTY
51
+ NETDATA_CACHESTAT_FOLIO_DIRTY,
52
+
53
+ NETDATA_CACHESTAT_ACCOUNT_DIRTY_END
54
};
55
56
enum cachestat_indexes {
collectors/ebpf.plugin/ebpf_dcstat.c
+2
-1
@@ -338,7 +338,8 @@ static void ebpf_dcstat_free(ebpf_module_t *em )
338
static void ebpf_dcstat_exit(void *ptr)
339
{
340
ebpf_module_t *em = (ebpf_module_t *)ptr;
341
- netdata_thread_cancel(*dcstat_threads.thread);
341
+ if (dcstat_threads.thread)
342
+ netdata_thread_cancel(*dcstat_threads.thread);
343
ebpf_dcstat_free(em);
344
}
345
collectors/ebpf.plugin/ebpf_disk.c
+2
-1
@@ -473,7 +473,8 @@ static void ebpf_disk_free(ebpf_module_t *em)
473
static void ebpf_disk_exit(void *ptr)
474
{
475
ebpf_module_t *em = (ebpf_module_t *)ptr;
476
- netdata_thread_cancel(*disk_threads.thread);
476
+ if (disk_threads.thread)
477
+ netdata_thread_cancel(*disk_threads.thread);
478
ebpf_disk_free(em);
479
}
480
collectors/ebpf.plugin/ebpf_fd.c
+51
-17
@@ -6,6 +6,9 @@
6
static char *fd_dimension_names[NETDATA_FD_SYSCALL_END] = { "open", "close" };
7
static char *fd_id_names[NETDATA_FD_SYSCALL_END] = { "do_sys_open", "__close_fd" };
8
9
+static char *close_targets[NETDATA_EBPF_MAX_FD_TARGETS] = {"close_fd", "__close_fd"};
10
+static char *open_targets[NETDATA_EBPF_MAX_FD_TARGETS] = {"do_sys_openat2", "do_sys_open"};
11
+
12
static netdata_syscall_stat_t fd_aggregated_data[NETDATA_FD_SYSCALL_END];
13
static netdata_publish_syscall_t fd_publish_aggregated[NETDATA_FD_SYSCALL_END];
14
@@ -65,7 +68,7 @@ static inline void ebpf_fd_disable_probes(struct fd_bpf *obj)
68
bpf_program__set_autoload(obj->progs.netdata_sys_open_kprobe, false);
69
bpf_program__set_autoload(obj->progs.netdata_sys_open_kretprobe, false);
70
bpf_program__set_autoload(obj->progs.netdata_release_task_fd_kprobe, false);
68
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
71
+ if (!strcmp(fd_targets[NETDATA_FD_SYSCALL_CLOSE].name, close_targets[NETDATA_FD_CLOSE_FD])) {
72
bpf_program__set_autoload(obj->progs.netdata___close_fd_kretprobe, false);
73
bpf_program__set_autoload(obj->progs.netdata___close_fd_kprobe, false);
74
bpf_program__set_autoload(obj->progs.netdata_close_fd_kprobe, false);
@@ -85,7 +88,7 @@ static inline void ebpf_fd_disable_probes(struct fd_bpf *obj)
88
*/
89
static inline void ebpf_disable_specific_probes(struct fd_bpf *obj)
90
{
88
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
91
+ if (!strcmp(fd_targets[NETDATA_FD_SYSCALL_CLOSE].name, close_targets[NETDATA_FD_CLOSE_FD])) {
92
bpf_program__set_autoload(obj->progs.netdata___close_fd_kretprobe, false);
93
bpf_program__set_autoload(obj->progs.netdata___close_fd_kprobe, false);
94
} else {
@@ -121,7 +124,7 @@ static inline void ebpf_disable_trampoline(struct fd_bpf *obj)
124
*/
125
static inline void ebpf_disable_specific_trampoline(struct fd_bpf *obj)
126
{
124
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
127
+ if (!strcmp(fd_targets[NETDATA_FD_SYSCALL_CLOSE].name, close_targets[NETDATA_FD_CLOSE_FD])) {
128
bpf_program__set_autoload(obj->progs.netdata___close_fd_fentry, false);
129
bpf_program__set_autoload(obj->progs.netdata___close_fd_fexit, false);
130
} else {
@@ -143,7 +146,7 @@ static void ebpf_set_trampoline_target(struct fd_bpf *obj)
146
bpf_program__set_attach_target(obj->progs.netdata_sys_open_fexit, 0, fd_targets[NETDATA_FD_SYSCALL_OPEN].name);
147
bpf_program__set_attach_target(obj->progs.netdata_release_task_fd_fentry, 0, EBPF_COMMON_FNCT_CLEAN_UP);
148
146
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
149
+ if (!strcmp(fd_targets[NETDATA_FD_SYSCALL_CLOSE].name, close_targets[NETDATA_FD_CLOSE_FD])) {
150
bpf_program__set_attach_target(
151
obj->progs.netdata_close_fd_fentry, 0, fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
152
bpf_program__set_attach_target(obj->progs.netdata_close_fd_fexit, 0, fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
@@ -185,7 +188,7 @@ static int ebpf_fd_attach_probe(struct fd_bpf *obj)
188
if (ret)
189
return -1;
190
188
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
191
+ if (!strcmp(fd_targets[NETDATA_FD_SYSCALL_CLOSE].name, close_targets[NETDATA_FD_CLOSE_FD])) {
192
obj->links.netdata_close_fd_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_close_fd_kretprobe, true,
193
fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
194
ret = libbpf_get_error(obj->links.netdata_close_fd_kretprobe);
@@ -216,22 +219,48 @@ static int ebpf_fd_attach_probe(struct fd_bpf *obj)
219
return 0;
220
}
221
222
+/**
223
+ * FD Fill Address
224
+ *
225
+ * Fill address value used to load probes/trampoline.
226
+ */
227
+static inline void ebpf_fd_fill_address(ebpf_addresses_t *address, char **targets)
228
+{
229
+ int i;
230
+ for (i = 0; i < NETDATA_EBPF_MAX_FD_TARGETS; i++) {
231
+ address->function = targets[i];
232
+ ebpf_load_addresses(address, -1);
233
+ if (address->addr)
234
+ break;
235
+ }
236
+}
237
+
238
/**
239
* Set target values
240
*
241
* Set pointers used to laod data.
242
+ *
243
+ * @return It returns 0 on success and -1 otherwise.
244
*/
224
-static void ebpf_fd_set_target_values()
245
+static int ebpf_fd_set_target_values()
246
{
226
- static char *close_targets[] = {"close_fd", "__close_fd"};
227
- static char *open_targets[] = {"do_sys_openat2", "do_sys_open"};
228
- if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
229
- fd_targets[NETDATA_FD_SYSCALL_OPEN].name = open_targets[0];
230
- fd_targets[NETDATA_FD_SYSCALL_CLOSE].name = close_targets[0];
231
- } else {
232
- fd_targets[NETDATA_FD_SYSCALL_OPEN].name = open_targets[1];
233
- fd_targets[NETDATA_FD_SYSCALL_CLOSE].name = close_targets[1];
234
- }
247
+ ebpf_addresses_t address = {.function = NULL, .hash = 0, .addr = 0};
248
+ ebpf_fd_fill_address(&address, close_targets);
249
+
250
+ if (!address.addr)
251
+ return -1;
252
+
253
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name = address.function;
254
+
255
+ address.addr = 0;
256
+ ebpf_fd_fill_address(&address, open_targets);
257
+
258
+ if (!address.addr)
259
+ return -1;
260
+
261
+ fd_targets[NETDATA_FD_SYSCALL_OPEN].name = address.function;
262
+
263
+ return 0;
264
}
265
266
/**
@@ -290,7 +319,11 @@ static inline int ebpf_fd_load_and_attach(struct fd_bpf *obj, ebpf_module_t *em)
319
netdata_ebpf_targets_t *mt = em->targets;
320
netdata_ebpf_program_loaded_t test = mt[NETDATA_FD_SYSCALL_OPEN].mode;
321
293
- ebpf_fd_set_target_values();
322
+ if (ebpf_fd_set_target_values()) {
323
+ error("%s file descriptor.", NETDATA_EBPF_DEFAULT_FNT_NOT_FOUND);
324
+ return -1;
325
+ }
326
+
327
if (test == EBPF_LOAD_TRAMPOLINE) {
328
ebpf_fd_disable_probes(obj);
329
ebpf_disable_specific_trampoline(obj);
@@ -372,7 +405,8 @@ static void ebpf_fd_free(ebpf_module_t *em)
405
static void ebpf_fd_exit(void *ptr)
406
{
407
ebpf_module_t *em = (ebpf_module_t *)ptr;
375
- netdata_thread_cancel(*fd_thread.thread);
408
+ if (fd_thread.thread)
409
+ netdata_thread_cancel(*fd_thread.thread);
410
ebpf_fd_free(em);
411
}
412
collectors/ebpf.plugin/ebpf_fd.h
+8
@@ -74,6 +74,14 @@ enum fd_syscalls {
74
NETDATA_FD_SYSCALL_END
75
};
76
77
+enum fd_close_syscall {
78
+ NETDATA_FD_CLOSE_FD,
79
+ NETDATA_FD___CLOSE_FD,
80
+
81
+ NETDATA_FD_CLOSE_END
82
+};
83
+
84
+#define NETDATA_EBPF_MAX_FD_TARGETS 2
85
86
void *ebpf_fd_thread(void *ptr);
87
void ebpf_fd_create_apps_charts(struct ebpf_module *em, void *ptr);
collectors/ebpf.plugin/ebpf_filesystem.c
+2
-1
@@ -367,7 +367,8 @@ static void ebpf_filesystem_free(ebpf_module_t *em)
367
static void ebpf_filesystem_exit(void *ptr)
368
{
369
ebpf_module_t *em = (ebpf_module_t *)ptr;
370
- netdata_thread_cancel(*filesystem_threads.thread);
370
+ if (filesystem_threads.thread)
371
+ netdata_thread_cancel(*filesystem_threads.thread);
372
ebpf_filesystem_free(em);
373
}
374
collectors/ebpf.plugin/ebpf_hardirq.c
+2
-1
@@ -183,7 +183,8 @@ static void ebpf_hardirq_free(ebpf_module_t *em)
183
static void hardirq_exit(void *ptr)
184
{
185
ebpf_module_t *em = (ebpf_module_t *)ptr;
186
- netdata_thread_cancel(*hardirq_threads.thread);
186
+ if (hardirq_threads.thread)
187
+ netdata_thread_cancel(*hardirq_threads.thread);
188
ebpf_hardirq_free(em);
189
}
190
collectors/ebpf.plugin/ebpf_mdflush.c
+2
-1
@@ -92,7 +92,8 @@ static void mdflush_exit(void *ptr)
92
static void mdflush_cleanup(void *ptr)
93
{
94
ebpf_module_t *em = (ebpf_module_t *)ptr;
95
- netdata_thread_cancel(*mdflush_threads.thread);
95
+ if (mdflush_threads.thread)
96
+ netdata_thread_cancel(*mdflush_threads.thread);
97
ebpf_mdflush_free(em);
98
}
99
collectors/ebpf.plugin/ebpf_mount.c
+2
-1
@@ -269,7 +269,8 @@ static void ebpf_mount_free(ebpf_module_t *em)
269
static void ebpf_mount_exit(void *ptr)
270
{
271
ebpf_module_t *em = (ebpf_module_t *)ptr;
272
- netdata_thread_cancel(*mount_thread.thread);
272
+ if (mount_thread.thread)
273
+ netdata_thread_cancel(*mount_thread.thread);
274
ebpf_mount_free(em);
275
}
276
collectors/ebpf.plugin/ebpf_process.c
+2
-1
@@ -745,7 +745,8 @@ static void ebpf_process_exit(void *ptr)
745
pthread_mutex_lock(&ebpf_exit_cleanup);
746
em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
747
pthread_mutex_unlock(&ebpf_exit_cleanup);
748
- pthread_cancel(*cgroup_thread.thread);
748
+ if (cgroup_thread.thread)
749
+ pthread_cancel(*cgroup_thread.thread);
750
}
751
752
/*****************************************************************
collectors/ebpf.plugin/ebpf_shm.c
+2
-1
@@ -329,7 +329,8 @@ static void ebpf_shm_free(ebpf_module_t *em)
329
static void ebpf_shm_exit(void *ptr)
330
{
331
ebpf_module_t *em = (ebpf_module_t *)ptr;
332
- netdata_thread_cancel(*shm_threads.thread);
332
+ if (shm_threads.thread)
333
+ netdata_thread_cancel(*shm_threads.thread);
334
ebpf_shm_free(em);
335
}
336
collectors/ebpf.plugin/ebpf_socket.c
+2
-1
@@ -647,7 +647,8 @@ static void ebpf_socket_free(ebpf_module_t *em )
647
static void ebpf_socket_exit(void *ptr)
648
{
649
ebpf_module_t *em = (ebpf_module_t *)ptr;
650
- netdata_thread_cancel(*socket_threads.thread);
650
+ if (socket_threads.thread)
651
+ netdata_thread_cancel(*socket_threads.thread);
652
ebpf_socket_free(em);
653
}
654
collectors/ebpf.plugin/ebpf_softirq.c
+2
-1
@@ -104,7 +104,8 @@ static void ebpf_softirq_free(ebpf_module_t *em)
104
static void softirq_exit(void *ptr)
105
{
106
ebpf_module_t *em = (ebpf_module_t *)ptr;
107
- netdata_thread_cancel(*softirq_threads.thread);
107
+ if (softirq_threads.thread)
108
+ netdata_thread_cancel(*softirq_threads.thread);
109
ebpf_softirq_free(em);
110
}
111
collectors/ebpf.plugin/ebpf_swap.c
+2
-1
@@ -268,7 +268,8 @@ static void ebpf_swap_free(ebpf_module_t *em)
268
static void ebpf_swap_exit(void *ptr)
269
{
270
ebpf_module_t *em = (ebpf_module_t *)ptr;
271
- netdata_thread_cancel(*swap_threads.thread);
271
+ if (swap_threads.thread)
272
+ netdata_thread_cancel(*swap_threads.thread);
273
ebpf_swap_free(em);
274
}
275
collectors/ebpf.plugin/ebpf_sync.c
+2
-1
@@ -243,7 +243,8 @@ static void ebpf_sync_free(ebpf_module_t *em)
243
static void ebpf_sync_exit(void *ptr)
244
{
245
ebpf_module_t *em = (ebpf_module_t *)ptr;
246
- netdata_thread_cancel(*sync_threads.thread);
246
+ if (sync_threads.thread)
247
+ netdata_thread_cancel(*sync_threads.thread);
248
ebpf_sync_free(em);
249
}
250
collectors/ebpf.plugin/ebpf_vfs.c
+2
-1
@@ -440,7 +440,8 @@ static void ebpf_vfs_free(ebpf_module_t *em)
440
static void ebpf_vfs_exit(void *ptr)
441
{
442
ebpf_module_t *em = (ebpf_module_t *)ptr;
443
- netdata_thread_cancel(*vfs_threads.thread);
443
+ if (vfs_threads.thread)
444
+ netdata_thread_cancel(*vfs_threads.thread);
445
ebpf_vfs_free(em);
446
}
447
libnetdata/ebpf/ebpf.c
+11
-6
@@ -1160,7 +1160,8 @@ void ebpf_adjust_apps_cgroup(ebpf_module_t *em, netdata_ebpf_program_loaded_t mo
1160
* Helper used to get address from /proc/kallsym
1161
*
1162
* @param fa address structure
1163
- * @param fd file descriptor loaded inside kernel.
1163
+ * @param fd file descriptor loaded inside kernel. If a negative value is given
1164
+ * the function will load address and it won't update hash table.
1165
*/
1166
void ebpf_load_addresses(ebpf_addresses_t *fa, int fd)
1167
{
@@ -1182,11 +1183,15 @@ void ebpf_load_addresses(ebpf_addresses_t *fa, int fd)
1183
char *fcnt = procfile_lineword(ff, l, 2);
1184
uint32_t hash = simple_hash(fcnt);
1185
if (fa->hash == hash && !strcmp(fcnt, fa->function)) {
1185
- char addr[128];
1186
- snprintf(addr, 127, "0x%s", procfile_lineword(ff, l, 0));
1187
- fa->addr = (unsigned long) strtoul(addr, NULL, 16);
1188
- uint32_t key = 0;
1189
- bpf_map_update_elem(fd, &key, &fa->addr, BPF_ANY);
1186
+ if (fd > 0) {
1187
+ char addr[128];
1188
+ snprintf(addr, 127, "0x%s", procfile_lineword(ff, l, 0));
1189
+ fa->addr = (unsigned long) strtoul(addr, NULL, 16);
1190
+ uint32_t key = 0;
1191
+ bpf_map_update_elem(fd, &key, &fa->addr, BPF_ANY);
1192
+ } else
1193
+ fa->addr = 1;
1194
+ break;
1195
}
1196
}
1197