@cryptotaxi247 / netdata-1 / commits / d127c108e

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