@cryptotaxi247 / netdata-1 / commits / 24880f912

Address issues on `EC2` (eBPF). (#14902)

thiagoftsm committed Apr 24, 2023 at 16:43 UTC 24880f912a5c347527b654302f4f1784a19ff2ce
31 files changed +793 -700
collectors/cgroups.plugin/sys_fs_cgroup.c
+1
@@ -4790,6 +4790,7 @@ static void cgroup_main_cleanup(void *ptr) {
4790 }
4791
4792 if (shm_cgroup_ebpf.header) {
4793 + shm_cgroup_ebpf.header->cgroup_root_count = 0;
4794 munmap(shm_cgroup_ebpf.header, shm_cgroup_ebpf.header->body_length);
4795 }
4796
collectors/ebpf.plugin/ebpf.c
+246 -63
@@ -28,11 +28,22 @@ int running_on_kernel = 0;
28 int ebpf_nprocs;
29 int isrh = 0;
30 int main_thread_id = 0;
31 +int process_pid_fd = -1;
32
33 pthread_mutex_t lock;
34 pthread_mutex_t ebpf_exit_cleanup;
35 pthread_mutex_t collect_data_mutex;
35 -pthread_cond_t collect_data_cond_var;
36 +
37 +struct netdata_static_thread cgroup_integration_thread = {
38 + .name = "EBPF CGROUP INT",
39 + .config_section = NULL,
40 + .config_name = NULL,
41 + .env_name = NULL,
42 + .enabled = 1,
43 + .thread = NULL,
44 + .init_routine = NULL,
45 + .start_routine = NULL
46 +};
47
48 ebpf_module_t ebpf_modules[] = {
49 { .thread_name = "process", .config_name = "process", .enabled = 0, .start_routine = ebpf_process_thread,
@@ -451,6 +462,14 @@ ebpf_plugin_stats_t plugin_statistics = {.core = 0, .legacy = 0, .running = 0, .
462
463 #ifdef LIBBPF_MAJOR_VERSION
464 struct btf *default_btf = NULL;
465 +struct cachestat_bpf *cachestat_bpf_obj = NULL;
466 +struct dc_bpf *dc_bpf_obj = NULL;
467 +struct fd_bpf *fd_bpf_obj = NULL;
468 +struct mount_bpf *mount_bpf_obj = NULL;
469 +struct shm_bpf *shm_bpf_obj = NULL;
470 +struct socket_bpf *socket_bpf_obj = NULL;
471 +struct swap_bpf *bpf_obj = NULL;
472 +struct vfs_bpf *vfs_bpf_obj = NULL;
473 #else
474 void *default_btf = NULL;
475 #endif
@@ -515,10 +534,12 @@ static void ebpf_exit()
534 #endif
535 printf("DISABLE\n");
536
537 + pthread_mutex_lock(&mutex_cgroup_shm);
538 if (shm_ebpf_cgroup.header) {
519 - munmap(shm_ebpf_cgroup.header, shm_ebpf_cgroup.header->body_length);
539 + ebpf_unmap_cgroup_shared_memory();
540 shm_unlink(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME);
541 }
542 + pthread_mutex_unlock(&mutex_cgroup_shm);
543
544 exit(0);
545 }
@@ -545,6 +566,126 @@ static void ebpf_unload_legacy_code(struct bpf_object *objects, struct bpf_link
566 bpf_object__close(objects);
567 }
568
569 +/**
570 + * Unload Unique maps
571 + *
572 + * This function unload all BPF maps from threads using one unique BPF object.
573 + */
574 +static void ebpf_unload_unique_maps()
575 +{
576 + int i;
577 + for (i = 0; ebpf_modules[i].thread_name; i++) {
578 + if (ebpf_modules[i].enabled != NETDATA_THREAD_EBPF_STOPPED) {
579 + if (ebpf_modules[i].enabled != NETDATA_THREAD_EBPF_NOT_RUNNING)
580 + error("Cannot unload maps for thread %s, because it is not stopped.", ebpf_modules[i].thread_name);
581 +
582 + continue;
583 + }
584 +
585 + ebpf_unload_legacy_code(ebpf_modules[i].objects, ebpf_modules[i].probe_links);
586 + switch (i) {
587 + case EBPF_MODULE_CACHESTAT_IDX: {
588 +#ifdef LIBBPF_MAJOR_VERSION
589 + if (cachestat_bpf_obj)
590 + cachestat_bpf__destroy(cachestat_bpf_obj);
591 +#endif
592 + break;
593 + }
594 + case EBPF_MODULE_DCSTAT_IDX: {
595 +#ifdef LIBBPF_MAJOR_VERSION
596 + if (dc_bpf_obj)
597 + dc_bpf__destroy(dc_bpf_obj);
598 +#endif
599 + break;
600 + }
601 + case EBPF_MODULE_FD_IDX: {
602 +#ifdef LIBBPF_MAJOR_VERSION
603 + if (fd_bpf_obj)
604 + fd_bpf__destroy(fd_bpf_obj);
605 +#endif
606 + break;
607 + }
608 + case EBPF_MODULE_MOUNT_IDX: {
609 +#ifdef LIBBPF_MAJOR_VERSION
610 + if (mount_bpf_obj)
611 + mount_bpf__destroy(mount_bpf_obj);
612 +#endif
613 + break;
614 + }
615 + case EBPF_MODULE_SHM_IDX: {
616 +#ifdef LIBBPF_MAJOR_VERSION
617 + if (shm_bpf_obj)
618 + shm_bpf__destroy(shm_bpf_obj);
619 +#endif
620 + break;
621 + }
622 + case EBPF_MODULE_SOCKET_IDX: {
623 +#ifdef LIBBPF_MAJOR_VERSION
624 + if (socket_bpf_obj)
625 + socket_bpf__destroy(socket_bpf_obj);
626 +#endif
627 + break;
628 + }
629 + case EBPF_MODULE_SWAP_IDX: {
630 +#ifdef LIBBPF_MAJOR_VERSION
631 + if (bpf_obj)
632 + swap_bpf__destroy(bpf_obj);
633 +#endif
634 + break;
635 + }
636 + case EBPF_MODULE_VFS_IDX: {
637 +#ifdef LIBBPF_MAJOR_VERSION
638 + if (vfs_bpf_obj)
639 + vfs_bpf__destroy(vfs_bpf_obj);
640 +#endif
641 + break;
642 + }
643 + case EBPF_MODULE_PROCESS_IDX:
644 + case EBPF_MODULE_DISK_IDX:
645 + case EBPF_MODULE_HARDIRQ_IDX:
646 + case EBPF_MODULE_SOFTIRQ_IDX:
647 + case EBPF_MODULE_OOMKILL_IDX:
648 + case EBPF_MODULE_MDFLUSH_IDX:
649 + default:
650 + continue;
651 + }
652 + }
653 +}
654 +
655 +/**
656 + * Unload filesystem maps
657 + *
658 + * This function unload all BPF maps from filesystem thread.
659 + */
660 +static void ebpf_unload_filesystems()
661 +{
662 + if (ebpf_modules[EBPF_MODULE_FILESYSTEM_IDX].enabled == NETDATA_THREAD_EBPF_NOT_RUNNING ||
663 + ebpf_modules[EBPF_MODULE_SYNC_IDX].enabled == NETDATA_THREAD_EBPF_RUNNING)
664 + return;
665 +
666 + int i;
667 + for (i = 0; localfs[i].filesystem != NULL; i++) {
668 + ebpf_unload_legacy_code(localfs[i].objects, localfs[i].probe_links);
669 + }
670 +}
671 +
672 +/**
673 + * Unload sync maps
674 + *
675 + * This function unload all BPF maps from sync thread.
676 + */
677 +static void ebpf_unload_sync()
678 +{
679 + if (ebpf_modules[EBPF_MODULE_SYNC_IDX].enabled == NETDATA_THREAD_EBPF_NOT_RUNNING ||
680 + ebpf_modules[EBPF_MODULE_SYNC_IDX].enabled == NETDATA_THREAD_EBPF_RUNNING)
681 + return;
682 +
683 + int i;
684 + for (i = 0; local_syscalls[i].syscall != NULL; i++) {
685 + ebpf_unload_legacy_code(local_syscalls[i].objects, local_syscalls[i].probe_links);
686 + }
687 +}
688 +
689 int ebpf_exit_plugin = 0;
690 /**
691 * Close the collector gracefully
@@ -556,7 +697,6 @@ static void ebpf_stop_threads(int sig)
697 UNUSED(sig);
698 static int only_one = 0;
699
559 - int i;
700 // Child thread should be closed by itself.
701 pthread_mutex_lock(&ebpf_exit_cleanup);
702 if (main_thread_id != gettid() || only_one) {
@@ -564,13 +704,26 @@ static void ebpf_stop_threads(int sig)
704 return;
705 }
706 only_one = 1;
567 - for (i = 0; ebpf_threads[i].name != NULL; i++) {
568 - if (ebpf_threads[i].enabled != NETDATA_THREAD_EBPF_STOPPED)
569 - netdata_thread_cancel(*ebpf_threads[i].thread);
707 + int i;
708 + for (i = 0; ebpf_modules[i].thread_name != NULL; i++) {
709 + if (ebpf_modules[i].enabled == NETDATA_THREAD_EBPF_RUNNING) {
710 + netdata_thread_cancel(*ebpf_modules[i].thread->thread);
711 +#ifdef NETDATA_DEV_MODE
712 + info("Sending cancel for thread %s", ebpf_modules[i].thread_name);
713 +#endif
714 + }
715 }
716 pthread_mutex_unlock(&ebpf_exit_cleanup);
717
718 + pthread_mutex_lock(&mutex_cgroup_shm);
719 + netdata_thread_cancel(*cgroup_integration_thread.thread);
720 +#ifdef NETDATA_DEV_MODE
721 + info("Sending cancel for thread %s", cgroup_integration_thread.name);
722 +#endif
723 + pthread_mutex_unlock(&mutex_cgroup_shm);
724 +
725 ebpf_exit_plugin = 1;
726 +
727 usec_t max = USEC_PER_SEC, step = 100000;
728 while (i && max) {
729 max -= step;
@@ -578,42 +731,18 @@ static void ebpf_stop_threads(int sig)
731 i = 0;
732 int j;
733 pthread_mutex_lock(&ebpf_exit_cleanup);
581 - for (j = 0; ebpf_threads[j].name != NULL; j++) {
582 - if (ebpf_threads[j].enabled != NETDATA_THREAD_EBPF_STOPPED)
734 + for (j = 0; ebpf_modules[j].thread_name != NULL; j++) {
735 + if (ebpf_modules[j].enabled == NETDATA_THREAD_EBPF_RUNNING)
736 i++;
737 }
738 pthread_mutex_unlock(&ebpf_exit_cleanup);
739 }
740
588 - if (!i) {
589 - //Unload threads(except sync and filesystem)
590 - pthread_mutex_lock(&ebpf_exit_cleanup);
591 - for (i = 0; ebpf_threads[i].name != NULL; i++) {
592 - if (ebpf_threads[i].enabled == NETDATA_THREAD_EBPF_STOPPED && i != EBPF_MODULE_FILESYSTEM_IDX &&
593 - i != EBPF_MODULE_SYNC_IDX)
594 - ebpf_unload_legacy_code(ebpf_modules[i].objects, ebpf_modules[i].probe_links);
595 - }
596 - pthread_mutex_unlock(&ebpf_exit_cleanup);
597 -
598 - //Unload filesystem
599 - pthread_mutex_lock(&ebpf_exit_cleanup);
600 - if (ebpf_threads[EBPF_MODULE_FILESYSTEM_IDX].enabled == NETDATA_THREAD_EBPF_STOPPED) {
601 - for (i = 0; localfs[i].filesystem != NULL; i++) {
602 - ebpf_unload_legacy_code(localfs[i].objects, localfs[i].probe_links);
603 - }
604 - }
605 - pthread_mutex_unlock(&ebpf_exit_cleanup);
606 -
607 - //Unload Sync
608 - pthread_mutex_lock(&ebpf_exit_cleanup);
609 - if (ebpf_threads[EBPF_MODULE_SYNC_IDX].enabled == NETDATA_THREAD_EBPF_STOPPED) {
610 - for (i = 0; local_syscalls[i].syscall != NULL; i++) {
611 - ebpf_unload_legacy_code(local_syscalls[i].objects, local_syscalls[i].probe_links);
612 - }
613 - }
614 - pthread_mutex_unlock(&ebpf_exit_cleanup);
615 -
616 - }
741 + pthread_mutex_lock(&ebpf_exit_cleanup);
742 + ebpf_unload_unique_maps();
743 + ebpf_unload_filesystems();
744 + ebpf_unload_sync();
745 + pthread_mutex_unlock(&ebpf_exit_cleanup);
746
747 ebpf_exit();
748 }
@@ -624,6 +753,58 @@ static void ebpf_stop_threads(int sig)
753 *
754 *****************************************************************/
755
756 +/**
757 + * Create apps charts
758 + *
759 + * Call ebpf_create_chart to create the charts on apps submenu.
760 + *
761 + * @param root a pointer for the targets.
762 + */
763 +static void ebpf_create_apps_charts(struct ebpf_target *root)
764 +{
765 + if (unlikely(!ebpf_all_pids))
766 + return;
767 +
768 + struct ebpf_target *w;
769 + int newly_added = 0;
770 +
771 + for (w = root; w; w = w->next) {
772 + if (w->target)
773 + continue;
774 +
775 + if (unlikely(w->processes && (debug_enabled || w->debug_enabled))) {
776 + struct ebpf_pid_on_target *pid_on_target;
777 +
778 + fprintf(
779 + stderr, "ebpf.plugin: target '%s' has aggregated %u process%s:", w->name, w->processes,
780 + (w->processes == 1) ? "" : "es");
781 +
782 + for (pid_on_target = w->root_pid; pid_on_target; pid_on_target = pid_on_target->next) {
783 + fprintf(stderr, " %d", pid_on_target->pid);
784 + }
785 +
786 + fputc('\n', stderr);
787 + }
788 +
789 + if (!w->exposed && w->processes) {
790 + newly_added++;
791 + w->exposed = 1;
792 + if (debug_enabled || w->debug_enabled)
793 + debug_log_int("%s just added - regenerating charts.", w->name);
794 + }
795 + }
796 +
797 + if (!newly_added)
798 + return;
799 +
800 + int counter;
801 + for (counter = 0; ebpf_modules[counter].thread_name; counter++) {
802 + ebpf_module_t *current = &ebpf_modules[counter];
803 + if (current->enabled == NETDATA_THREAD_EBPF_RUNNING && current->apps_charts && current->apps_routine)
804 + current->apps_routine(current, root);
805 + }
806 +}
807 +
808 /**
809 * Get a value from a structure.
810 *
@@ -1044,7 +1225,7 @@ void ebpf_global_labels(netdata_syscall_stat_t *is, netdata_publish_syscall_t *p
1225
1226 pio[i].dimension = dim[i];
1227 pio[i].name = name[i];
1047 - pio[i].algorithm = strdupz(ebpf_algorithms[algorithm[i]]);
1228 + pio[i].algorithm = ebpf_algorithms[algorithm[i]];
1229 if (publish_prev) {
1230 publish_prev->next = &pio[i];
1231 }
@@ -1442,21 +1623,13 @@ static void read_local_addresses()
1623 * Start Pthread Variable
1624 *
1625 * This function starts all pthread variables.
1445 - *
1446 - * @return It returns 0 on success and -1.
1626 */
1448 -int ebpf_start_pthread_variables()
1627 +void ebpf_start_pthread_variables()
1628 {
1629 pthread_mutex_init(&lock, NULL);
1630 pthread_mutex_init(&ebpf_exit_cleanup, NULL);
1631 pthread_mutex_init(&collect_data_mutex, NULL);
1453 -
1454 - if (pthread_cond_init(&collect_data_cond_var, NULL)) {
1455 - error("Cannot start conditional variable to control Apps charts.");
1456 - return -1;
1457 - }
1458 -
1459 - return 0;
1632 + pthread_mutex_init(&mutex_cgroup_shm, NULL);
1633 }
1634
1635 /**
@@ -2320,10 +2493,7 @@ int main(int argc, char **argv)
2493 signal(SIGTERM, ebpf_stop_threads);
2494 signal(SIGPIPE, ebpf_stop_threads);
2495
2323 - if (ebpf_start_pthread_variables()) {
2324 - error("Cannot start mutex to control overall charts.");
2325 - ebpf_exit();
2326 - }
2496 + ebpf_start_pthread_variables();
2497
2498 netdata_configured_host_prefix = getenv("NETDATA_HOST_PREFIX");
2499 if(verify_netdata_host_prefix() == -1) ebpf_exit(6);
@@ -2342,6 +2512,12 @@ int main(int argc, char **argv)
2512
2513 ebpf_set_static_routine();
2514
2515 + cgroup_integration_thread.thread = mallocz(sizeof(netdata_thread_t));
2516 + cgroup_integration_thread.start_routine = ebpf_cgroup_integration;
2517 +
2518 + netdata_thread_create(cgroup_integration_thread.thread, cgroup_integration_thread.name,
2519 + NETDATA_THREAD_OPTION_DEFAULT, ebpf_cgroup_integration, NULL);
2520 +
2521 int i;
2522 for (i = 0; ebpf_threads[i].name != NULL; i++) {
2523 struct netdata_static_thread *st = &ebpf_threads[i];
@@ -2352,30 +2528,37 @@ int main(int argc, char **argv)
2528 if (em->enabled || !i) {
2529 st->thread = mallocz(sizeof(netdata_thread_t));
2530 em->thread_id = i;
2355 - st->enabled = NETDATA_THREAD_EBPF_RUNNING;
2531 + em->enabled = NETDATA_THREAD_EBPF_RUNNING;
2532 netdata_thread_create(st->thread, st->name, NETDATA_THREAD_OPTION_DEFAULT, st->start_routine, em);
2533 } else {
2358 - st->enabled = NETDATA_THREAD_EBPF_STOPPED;
2534 + em->enabled = NETDATA_THREAD_EBPF_NOT_RUNNING;
2535 }
2536 }
2537
2538 usec_t step = USEC_PER_SEC;
2363 - int counter = NETDATA_EBPF_CGROUP_UPDATE - 1;
2539 heartbeat_t hb;
2540 heartbeat_init(&hb);
2541 + int update_apps_every = (int) EBPF_CFG_UPDATE_APPS_EVERY_DEFAULT;
2542 + int update_apps_list = update_apps_every - 1;
2543 //Plugin will be killed when it receives a signal
2544 while (!ebpf_exit_plugin) {
2545 (void)heartbeat_next(&hb, step);
2546
2370 - // We are using a small heartbeat time to wake up thread,
2371 - // but we should not update so frequently the shared memory data
2372 - if (++counter >= NETDATA_EBPF_CGROUP_UPDATE) {
2373 - counter = 0;
2374 - if (!shm_ebpf_cgroup.header)
2375 - ebpf_map_cgroup_shared_memory();
2376 -
2377 - ebpf_parse_cgroup_shm_data();
2547 + pthread_mutex_lock(&ebpf_exit_cleanup);
2548 + if (ebpf_modules[i].enabled == NETDATA_THREAD_EBPF_RUNNING && process_pid_fd != -1) {
2549 + pthread_mutex_lock(&collect_data_mutex);
2550 + if (++update_apps_list == update_apps_every) {
2551 + update_apps_list = 0;
2552 + cleanup_exited_pids();
2553 + collect_data_for_all_processes(process_pid_fd);
2554 +
2555 + pthread_mutex_lock(&lock);
2556 + ebpf_create_apps_charts(apps_groups_root_target);
2557 + pthread_mutex_unlock(&lock);
2558 + }
2559 + pthread_mutex_unlock(&collect_data_mutex);
2560 }
2561 + pthread_mutex_unlock(&ebpf_exit_cleanup);
2562 }
2563
2564 ebpf_stop_threads(0);
collectors/ebpf.plugin/ebpf.d.conf
+1 -1
@@ -62,7 +62,7 @@
62 process = yes
63 shm = yes
64 socket = no
65 - softirq = no
65 + softirq = yes
66 sync = yes
67 swap = yes
68 vfs = no
collectors/ebpf.plugin/ebpf.h
+21 -9
@@ -36,6 +36,26 @@
36 #define NETDATA_EBPF_OLD_CONFIG_FILE "ebpf.conf"
37 #define NETDATA_EBPF_CONFIG_FILE "ebpf.d.conf"
38
39 +#ifdef LIBBPF_MAJOR_VERSION // BTF code
40 +#include "includes/cachestat.skel.h"
41 +#include "includes/dc.skel.h"
42 +#include "includes/fd.skel.h"
43 +#include "includes/mount.skel.h"
44 +#include "includes/shm.skel.h"
45 +#include "includes/socket.skel.h"
46 +#include "includes/swap.skel.h"
47 +#include "includes/vfs.skel.h"
48 +
49 +extern struct cachestat_bpf *cachestat_bpf_obj;
50 +extern struct dc_bpf *dc_bpf_obj;
51 +extern struct fd_bpf *fd_bpf_obj;
52 +extern struct mount_bpf *mount_bpf_obj;
53 +extern struct shm_bpf *shm_bpf_obj;
54 +extern struct socket_bpf *socket_bpf_obj;
55 +extern struct swap_bpf *bpf_obj;
56 +extern struct vfs_bpf *vfs_bpf_obj;
57 +#endif
58 +
59 typedef struct netdata_syscall_stat {
60 unsigned long bytes; // total number of bytes
61 uint64_t call; // total number of calls
@@ -108,12 +128,6 @@ typedef struct ebpf_tracepoint {
128 char *event;
129 } ebpf_tracepoint_t;
130
111 -enum ebpf_threads_status {
112 - NETDATA_THREAD_EBPF_RUNNING,
113 - NETDATA_THREAD_EBPF_STOPPING,
114 - NETDATA_THREAD_EBPF_STOPPED
115 -};
116 -
131 // Copied from musl header
132 #ifndef offsetof
133 #if __GNUC__ > 3
@@ -178,9 +192,9 @@ extern int ebpf_nprocs;
192 extern int running_on_kernel;
193 extern int isrh;
194 extern char *ebpf_plugin_dir;
195 +extern int process_pid_fd;
196
197 extern pthread_mutex_t collect_data_mutex;
183 -extern pthread_cond_t collect_data_cond_var;
198
199 // Common functions
200 void ebpf_global_labels(netdata_syscall_stat_t *is,
@@ -243,8 +257,6 @@ void ebpf_create_charts_on_apps(char *name,
257
258 void write_end_chart();
259
246 -void ebpf_cleanup_publish_syscall(netdata_publish_syscall_t *nps);
247 -
260 int ebpf_enable_tracepoint(ebpf_tracepoint_t *tp);
261 int ebpf_disable_tracepoint(ebpf_tracepoint_t *tp);
262 uint32_t ebpf_enable_tracepoints(ebpf_tracepoint_t *tps);
collectors/ebpf.plugin/ebpf_apps.c
+263
@@ -8,6 +8,23 @@
8 // ARAL vectors used to speed up processing
9 ARAL *ebpf_aral_apps_pid_stat = NULL;
10 ARAL *ebpf_aral_process_stat = NULL;
11 +ARAL *ebpf_aral_socket_pid = NULL;
12 +ARAL *ebpf_aral_cachestat_pid = NULL;
13 +ARAL *ebpf_aral_dcstat_pid = NULL;
14 +ARAL *ebpf_aral_vfs_pid = NULL;
15 +ARAL *ebpf_aral_fd_pid = NULL;
16 +ARAL *ebpf_aral_shm_pid = NULL;
17 +
18 +// ----------------------------------------------------------------------------
19 +// Global vectors used with apps
20 +ebpf_socket_publish_apps_t **socket_bandwidth_curr = NULL;
21 +netdata_publish_cachestat_t **cachestat_pid = NULL;
22 +netdata_publish_dcstat_t **dcstat_pid = NULL;
23 +netdata_publish_swap_t **swap_pid = NULL;
24 +netdata_publish_vfs_t **vfs_pid = NULL;
25 +netdata_fd_stat_t **fd_pid = NULL;
26 +netdata_publish_shm_t **shm_pid = NULL;
27 +ebpf_process_stat_t **global_process_stats = NULL;
28
29 /**
30 * eBPF ARAL Init
@@ -55,6 +72,12 @@ void ebpf_pid_stat_release(struct ebpf_pid_stat *stat)
72 aral_freez(ebpf_aral_apps_pid_stat, stat);
73 }
74
75 +/*****************************************************************
76 + *
77 + * PROCESS ARAL FUNCTIONS
78 + *
79 + *****************************************************************/
80 +
81 /**
82 * eBPF process stat get
83 *
@@ -79,6 +102,246 @@ void ebpf_process_stat_release(ebpf_process_stat_t *stat)
102 aral_freez(ebpf_aral_process_stat, stat);
103 }
104
105 +/*****************************************************************
106 + *
107 + * SOCKET ARAL FUNCTIONS
108 + *
109 + *****************************************************************/
110 +
111 +/**
112 + * eBPF socket Aral init
113 + *
114 + * Initiallize array allocator that will be used when integration with apps is enabled.
115 + */
116 +void ebpf_socket_aral_init()
117 +{
118 + ebpf_aral_socket_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SOCKET_ARAL_NAME, sizeof(ebpf_socket_publish_apps_t));
119 +}
120 +
121 +/**
122 + * eBPF socket get
123 + *
124 + * Get a ebpf_socket_publish_apps_t entry to be used with a specific PID.
125 + *
126 + * @return it returns the address on success.
127 + */
128 +ebpf_socket_publish_apps_t *ebpf_socket_stat_get(void)
129 +{
130 + ebpf_socket_publish_apps_t *target = aral_mallocz(ebpf_aral_socket_pid);
131 + memset(target, 0, sizeof(ebpf_socket_publish_apps_t));
132 + return target;
133 +}
134 +
135 +/**
136 + * eBPF socket release
137 + *
138 + * @param stat Release a target after usage.
139 + */
140 +void ebpf_socket_release(ebpf_socket_publish_apps_t *stat)
141 +{
142 + aral_freez(ebpf_aral_socket_pid, stat);
143 +}
144 +
145 +/*****************************************************************
146 + *
147 + * CACHESTAT ARAL FUNCTIONS
148 + *
149 + *****************************************************************/
150 +
151 +/**
152 + * eBPF Cachestat Aral init
153 + *
154 + * Initiallize array allocator that will be used when integration with apps is enabled.
155 + */
156 +void ebpf_cachestat_aral_init()
157 +{
158 + ebpf_aral_cachestat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_CACHESTAT_ARAL_NAME, sizeof(netdata_publish_cachestat_t));
159 +}
160 +
161 +/**
162 + * eBPF publish cachestat get
163 + *
164 + * Get a netdata_publish_cachestat_t entry to be used with a specific PID.
165 + *
166 + * @return it returns the address on success.
167 + */
168 +netdata_publish_cachestat_t *ebpf_publish_cachestat_get(void)
169 +{
170 + netdata_publish_cachestat_t *target = aral_mallocz(ebpf_aral_cachestat_pid);
171 + memset(target, 0, sizeof(netdata_publish_cachestat_t));
172 + return target;
173 +}
174 +
175 +/**
176 + * eBPF cachestat release
177 + *
178 + * @param stat Release a target after usage.
179 + */
180 +void ebpf_cachestat_release(netdata_publish_cachestat_t *stat)
181 +{
182 + aral_freez(ebpf_aral_cachestat_pid, stat);
183 +}
184 +
185 +/*****************************************************************
186 + *
187 + * DCSTAT ARAL FUNCTIONS
188 + *
189 + *****************************************************************/
190 +
191 +/**
192 + * eBPF directory cache Aral init
193 + *
194 + * Initiallize array allocator that will be used when integration with apps is enabled.
195 + */
196 +void ebpf_dcstat_aral_init()
197 +{
198 + ebpf_aral_dcstat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_DCSTAT_ARAL_NAME, sizeof(netdata_publish_dcstat_t));
199 +}
200 +
201 +/**
202 + * eBPF publish dcstat get
203 + *
204 + * Get a netdata_publish_dcstat_t entry to be used with a specific PID.
205 + *
206 + * @return it returns the address on success.
207 + */
208 +netdata_publish_dcstat_t *ebpf_publish_dcstat_get(void)
209 +{
210 + netdata_publish_dcstat_t *target = aral_mallocz(ebpf_aral_dcstat_pid);
211 + memset(target, 0, sizeof(netdata_publish_dcstat_t));
212 + return target;
213 +}
214 +
215 +/**
216 + * eBPF dcstat release
217 + *
218 + * @param stat Release a target after usage.
219 + */
220 +void ebpf_dcstat_release(netdata_publish_dcstat_t *stat)
221 +{
222 + aral_freez(ebpf_aral_dcstat_pid, stat);
223 +}
224 +
225 +/*****************************************************************
226 + *
227 + * VFS ARAL FUNCTIONS
228 + *
229 + *****************************************************************/
230 +
231 +/**
232 + * eBPF VFS Aral init
233 + *
234 + * Initiallize array allocator that will be used when integration with apps is enabled.
235 + */
236 +void ebpf_vfs_aral_init()
237 +{
238 + ebpf_aral_vfs_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_VFS_ARAL_NAME, sizeof(netdata_publish_vfs_t));
239 +}
240 +
241 +/**
242 + * eBPF publish VFS get
243 + *
244 + * Get a netdata_publish_vfs_t entry to be used with a specific PID.
245 + *
246 + * @return it returns the address on success.
247 + */
248 +netdata_publish_vfs_t *ebpf_vfs_get(void)
249 +{
250 + netdata_publish_vfs_t *target = aral_mallocz(ebpf_aral_vfs_pid);
251 + memset(target, 0, sizeof(netdata_publish_vfs_t));
252 + return target;
253 +}
254 +
255 +/**
256 + * eBPF VFS release
257 + *
258 + * @param stat Release a target after usage.
259 + */
260 +void ebpf_vfs_release(netdata_publish_vfs_t *stat)
261 +{
262 + aral_freez(ebpf_aral_vfs_pid, stat);
263 +}
264 +
265 +/*****************************************************************
266 + *
267 + * FD ARAL FUNCTIONS
268 + *
269 + *****************************************************************/
270 +
271 +/**
272 + * eBPF file descriptor Aral init
273 + *
274 + * Initiallize array allocator that will be used when integration with apps is enabled.
275 + */
276 +void ebpf_fd_aral_init()
277 +{
278 + ebpf_aral_fd_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_FD_ARAL_NAME, sizeof(netdata_fd_stat_t));
279 +}
280 +
281 +/**
282 + * eBPF publish file descriptor get
283 + *
284 + * Get a netdata_fd_stat_t entry to be used with a specific PID.
285 + *
286 + * @return it returns the address on success.
287 + */
288 +netdata_fd_stat_t *ebpf_fd_stat_get(void)
289 +{
290 + netdata_fd_stat_t *target = aral_mallocz(ebpf_aral_fd_pid);
291 + memset(target, 0, sizeof(netdata_fd_stat_t));
292 + return target;
293 +}
294 +
295 +/**
296 + * eBPF file descriptor release
297 + *
298 + * @param stat Release a target after usage.
299 + */
300 +void ebpf_fd_release(netdata_fd_stat_t *stat)
301 +{
302 + aral_freez(ebpf_aral_fd_pid, stat);
303 +}
304 +
305 +/*****************************************************************
306 + *
307 + * SHM ARAL FUNCTIONS
308 + *
309 + *****************************************************************/
310 +
311 +/**
312 + * eBPF shared memory Aral init
313 + *
314 + * Initiallize array allocator that will be used when integration with apps is enabled.
315 + */
316 +void ebpf_shm_aral_init()
317 +{
318 + ebpf_aral_shm_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SHM_ARAL_NAME, sizeof(netdata_publish_shm_t));
319 +}
320 +
321 +/**
322 + * eBPF shared memory get
323 + *
324 + * Get a netdata_publish_shm_t entry to be used with a specific PID.
325 + *
326 + * @return it returns the address on success.
327 + */
328 +netdata_publish_shm_t *ebpf_shm_stat_get(void)
329 +{
330 + netdata_publish_shm_t *target = aral_mallocz(ebpf_aral_shm_pid);
331 + memset(target, 0, sizeof(netdata_publish_shm_t));
332 + return target;
333 +}
334 +
335 +/**
336 + * eBPF shared memory release
337 + *
338 + * @param stat Release a target after usage.
339 + */
340 +void ebpf_shm_release(netdata_publish_shm_t *stat)
341 +{
342 + aral_freez(ebpf_aral_shm_pid, stat);
343 +}
344 +
345 // ----------------------------------------------------------------------------
346 // internal flags
347 // handled in code (automatically set)
collectors/ebpf.plugin/ebpf_apps.h
+41
@@ -218,6 +218,10 @@ void collect_data_for_all_processes(int tbl_pid_stats_fd);
218 extern ebpf_process_stat_t **global_process_stats;
219 extern netdata_publish_cachestat_t **cachestat_pid;
220 extern netdata_publish_dcstat_t **dcstat_pid;
221 +extern netdata_publish_swap_t **swap_pid;
222 +extern netdata_publish_vfs_t **vfs_pid;
223 +extern netdata_fd_stat_t **fd_pid;
224 +extern netdata_publish_shm_t **shm_pid;
225
226 // The default value is at least 32 times smaller than maximum number of PIDs allowed on system,
227 // this is only possible because we are using ARAL (https://github.com/netdata/netdata/tree/master/libnetdata/aral).
@@ -226,11 +230,48 @@ extern netdata_publish_dcstat_t **dcstat_pid;
230 #endif
231 #define NETDATA_EBPF_ALLOC_MIN_ELEMENTS 256
232
233 +// ARAL Sectiion
234 extern void ebpf_aral_init(void);
235
236 extern ebpf_process_stat_t *ebpf_process_stat_get(void);
237 extern void ebpf_process_stat_release(ebpf_process_stat_t *stat);
238
239 +extern ARAL *ebpf_aral_socket_pid;
240 +void ebpf_socket_aral_init();
241 +ebpf_socket_publish_apps_t *ebpf_socket_stat_get(void);
242 +void ebpf_socket_release(ebpf_socket_publish_apps_t *stat);
243 +
244 +extern ARAL *ebpf_aral_cachestat_pid;
245 +void ebpf_cachestat_aral_init();
246 +netdata_publish_cachestat_t *ebpf_publish_cachestat_get(void);
247 +void ebpf_cachestat_release(netdata_publish_cachestat_t *stat);
248 +
249 +extern ARAL *ebpf_aral_dcstat_pid;
250 +void ebpf_dcstat_aral_init();
251 +netdata_publish_dcstat_t *ebpf_publish_dcstat_get(void);
252 +void ebpf_dcstat_release(netdata_publish_dcstat_t *stat);
253 +
254 +extern ARAL *ebpf_aral_vfs_pid;
255 +void ebpf_vfs_aral_init();
256 +netdata_publish_vfs_t *ebpf_vfs_get(void);
257 +void ebpf_vfs_release(netdata_publish_vfs_t *stat);
258 +
259 +extern ARAL *ebpf_aral_fd_pid;
260 +void ebpf_fd_aral_init();
261 +netdata_fd_stat_t *ebpf_fd_stat_get(void);
262 +void ebpf_fd_release(netdata_fd_stat_t *stat);
263 +
264 +extern ARAL *ebpf_aral_shm_pid;
265 +void ebpf_shm_aral_init();
266 +netdata_publish_shm_t *ebpf_shm_stat_get(void);
267 +void ebpf_shm_release(netdata_publish_shm_t *stat);
268 +
269 +// ARAL Section end
270 +
271 +// Threads integrated with apps
272 +extern ebpf_socket_publish_apps_t **socket_bandwidth_curr;
273 +// Threads integrated with apps
274 +
275 #include "libnetdata/threads/threads.h"
276
277 // ARAL variables
collectors/ebpf.plugin/ebpf_cachestat.c
+5 -63
@@ -3,12 +3,6 @@
3 #include "ebpf.h"
4 #include "ebpf_cachestat.h"
5
6 -// ----------------------------------------------------------------------------
7 -// ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_cachestat_pid = NULL;
9 -
10 -netdata_publish_cachestat_t **cachestat_pid;
11 -
6 static char *cachestat_counter_dimension_name[NETDATA_CACHESTAT_END] = { "ratio", "dirty", "hit",
7 "miss" };
8 static netdata_syscall_stat_t cachestat_counter_aggregated_data[NETDATA_CACHESTAT_END];
@@ -50,10 +44,6 @@ static char *account_page[NETDATA_CACHESTAT_ACCOUNT_DIRTY_END] ={ "account_page_
44 "__set_page_dirty", "__folio_mark_dirty" };
45
46 #ifdef LIBBPF_MAJOR_VERSION
53 -#include "includes/cachestat.skel.h" // BTF code
54 -
55 -static struct cachestat_bpf *bpf_obj = NULL;
56 -
47 /**
48 * Disable probe
49 *
@@ -337,20 +327,14 @@ static inline int ebpf_cachestat_load_and_attach(struct cachestat_bpf *obj, ebpf
327 static void ebpf_cachestat_free(ebpf_module_t *em)
328 {
329 pthread_mutex_lock(&ebpf_exit_cleanup);
340 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
330 + em->enabled = NETDATA_THREAD_EBPF_STOPPING;
331 pthread_mutex_unlock(&ebpf_exit_cleanup);
332
343 - ebpf_cleanup_publish_syscall(cachestat_counter_publish_aggregated);
344 -
333 freez(cachestat_vector);
334 freez(cachestat_values);
335
348 -#ifdef LIBBPF_MAJOR_VERSION
349 - if (bpf_obj)
350 - cachestat_bpf__destroy(bpf_obj);
351 -#endif
336 pthread_mutex_lock(&ebpf_exit_cleanup);
353 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
337 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
338 pthread_mutex_unlock(&ebpf_exit_cleanup);
339 }
340
@@ -368,46 +352,6 @@ static void ebpf_cachestat_exit(void *ptr)
352 ebpf_cachestat_free(em);
353 }
354
371 -/*****************************************************************
372 - *
373 - * ARAL FUNCTIONS
374 - *
375 - *****************************************************************/
376 -
377 -/**
378 - * eBPF Cachestat Aral init
379 - *
380 - * Initiallize array allocator that will be used when integration with apps is enabled.
381 - */
382 -static inline void ebpf_cachestat_aral_init()
383 -{
384 - ebpf_aral_cachestat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_CACHESTAT_ARAL_NAME, sizeof(netdata_publish_cachestat_t));
385 -}
386 -
387 -/**
388 - * eBPF publish cachestat get
389 - *
390 - * Get a netdata_publish_cachestat_t entry to be used with a specific PID.
391 - *
392 - * @return it returns the address on success.
393 - */
394 -netdata_publish_cachestat_t *ebpf_publish_cachestat_get(void)
395 -{
396 - netdata_publish_cachestat_t *target = aral_mallocz(ebpf_aral_cachestat_pid);
397 - memset(target, 0, sizeof(netdata_publish_cachestat_t));
398 - return target;
399 -}
400 -
401 -/**
402 - * eBPF cachestat release
403 - *
404 - * @param stat Release a target after usage.
405 - */
406 -void ebpf_cachestat_release(netdata_publish_cachestat_t *stat)
407 -{
408 - aral_freez(ebpf_aral_cachestat_pid, stat);
409 -}
410 -
355 /*****************************************************************
356 *
357 * COMMON FUNCTIONS
@@ -1282,11 +1226,11 @@ static int ebpf_cachestat_load_bpf(ebpf_module_t *em)
1226 }
1227 #ifdef LIBBPF_MAJOR_VERSION
1228 else {
1285 - bpf_obj = cachestat_bpf__open();
1286 - if (!bpf_obj)
1229 + cachestat_bpf_obj = cachestat_bpf__open();
1230 + if (!cachestat_bpf_obj)
1231 ret = -1;
1232 else
1289 - ret = ebpf_cachestat_load_and_attach(bpf_obj, em);
1233 + ret = ebpf_cachestat_load_and_attach(cachestat_bpf_obj, em);
1234 }
1235 #endif
1236
@@ -1315,7 +1259,6 @@ void *ebpf_cachestat_thread(void *ptr)
1259 ebpf_update_pid_table(&cachestat_maps[NETDATA_CACHESTAT_PID_STATS], em);
1260
1261 if (ebpf_cachestat_set_internal_value()) {
1318 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1262 goto endcachestat;
1263 }
1264
@@ -1323,7 +1266,6 @@ void *ebpf_cachestat_thread(void *ptr)
1266 ebpf_adjust_thread_load(em, default_btf);
1267 #endif
1268 if (ebpf_cachestat_load_bpf(em)) {
1326 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1269 goto endcachestat;
1270 }
1271
collectors/ebpf.plugin/ebpf_cgroup.c
+110 -35
@@ -6,6 +6,7 @@
6 #include "ebpf_cgroup.h"
7
8 ebpf_cgroup_target_t *ebpf_cgroup_pids = NULL;
9 +static void *ebpf_mapped_memory = NULL;
10 int send_cgroup_chart = 0;
11
12 // --------------------------------------------------------------------------------------------------------------------
@@ -19,7 +20,7 @@ int send_cgroup_chart = 0;
20 * @param fd file descriptor returned after shm_open was called.
21 * @param length length of the shared memory
22 *
22 - * @return It returns a pointer to the region mapped.
23 + * @return It returns a pointer to the region mapped on success and MAP_FAILED otherwise.
24 */
25 static inline void *ebpf_cgroup_map_shm_locally(int fd, size_t length)
26 {
@@ -36,6 +37,16 @@ static inline void *ebpf_cgroup_map_shm_locally(int fd, size_t length)
37 return value;
38 }
39
40 +/**
41 + * Unmap Shared Memory
42 + *
43 + * Unmap shared memory used to integrate eBPF and cgroup plugin
44 + */
45 +void ebpf_unmap_cgroup_shared_memory()
46 +{
47 + munmap(ebpf_mapped_memory, shm_ebpf_cgroup.header->body_length);
48 +}
49 +
50 /**
51 * Map cgroup shared memory
52 *
@@ -56,40 +67,47 @@ void ebpf_map_cgroup_shared_memory()
67 limit_try++;
68 next_try = curr_time + NETDATA_EBPF_CGROUP_NEXT_TRY_SEC;
69
59 - shm_fd_ebpf_cgroup = shm_open(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME, O_RDWR, 0660);
70 if (shm_fd_ebpf_cgroup < 0) {
61 - if (limit_try == NETDATA_EBPF_CGROUP_MAX_TRIES)
62 - error("Shared memory was not initialized, integration between processes won't happen.");
71 + shm_fd_ebpf_cgroup = shm_open(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME, O_RDWR, 0660);
72 + if (shm_fd_ebpf_cgroup < 0) {
73 + if (limit_try == NETDATA_EBPF_CGROUP_MAX_TRIES)
74 + error("Shared memory was not initialized, integration between processes won't happen.");
75
64 - return;
76 + return;
77 + }
78 }
79
80 // Map only header
68 - shm_ebpf_cgroup.header = (netdata_ebpf_cgroup_shm_header_t *) ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup,
69 - sizeof(netdata_ebpf_cgroup_shm_header_t));
70 - if (!shm_ebpf_cgroup.header) {
71 - limit_try = NETDATA_EBPF_CGROUP_MAX_TRIES + 1;
81 + void *mapped = (netdata_ebpf_cgroup_shm_header_t *) ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup,
82 + sizeof(netdata_ebpf_cgroup_shm_header_t));
83 + if (unlikely(mapped == SEM_FAILED)) {
84 return;
85 }
86 + netdata_ebpf_cgroup_shm_header_t *header = mapped;
87
75 - size_t length = shm_ebpf_cgroup.header->body_length;
88 + size_t length = header->body_length;
89
77 - munmap(shm_ebpf_cgroup.header, sizeof(netdata_ebpf_cgroup_shm_header_t));
90 + munmap(header, sizeof(netdata_ebpf_cgroup_shm_header_t));
91
79 - shm_ebpf_cgroup.header = (netdata_ebpf_cgroup_shm_header_t *)ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup, length);
80 - if (!shm_ebpf_cgroup.header) {
81 - limit_try = NETDATA_EBPF_CGROUP_MAX_TRIES + 1;
92 + if (length <= ((sizeof(netdata_ebpf_cgroup_shm_header_t) + sizeof(netdata_ebpf_cgroup_shm_body_t)))) {
93 return;
94 }
84 - shm_ebpf_cgroup.body = (netdata_ebpf_cgroup_shm_body_t *) ((char *)shm_ebpf_cgroup.header +
85 - sizeof(netdata_ebpf_cgroup_shm_header_t));
95 +
96 + ebpf_mapped_memory = (void *)ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup, length);
97 + if (unlikely(ebpf_mapped_memory == MAP_FAILED)) {
98 + return;
99 + }
100 + shm_ebpf_cgroup.header = ebpf_mapped_memory;
101 + shm_ebpf_cgroup.body = ebpf_mapped_memory + sizeof(netdata_ebpf_cgroup_shm_header_t);
102
103 shm_sem_ebpf_cgroup = sem_open(NETDATA_NAMED_SEMAPHORE_EBPF_CGROUP_NAME, O_CREAT, 0660, 1);
104
105 if (shm_sem_ebpf_cgroup == SEM_FAILED) {
106 error("Cannot create semaphore, integration between eBPF and cgroup won't happen");
91 - munmap(shm_ebpf_cgroup.header, length);
107 + limit_try = NETDATA_EBPF_CGROUP_MAX_TRIES + 1;
108 + munmap(ebpf_mapped_memory, length);
109 shm_ebpf_cgroup.header = NULL;
110 + shm_ebpf_cgroup.body = NULL;
111 close(shm_fd_ebpf_cgroup);
112 shm_fd_ebpf_cgroup = -1;
113 shm_unlink(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME);
@@ -258,32 +276,38 @@ void ebpf_reset_updated_var()
276 void ebpf_parse_cgroup_shm_data()
277 {
278 static int previous = 0;
261 - if (shm_ebpf_cgroup.header) {
262 - sem_wait(shm_sem_ebpf_cgroup);
263 - int i, end = shm_ebpf_cgroup.header->cgroup_root_count;
279 + if (!shm_ebpf_cgroup.header || shm_sem_ebpf_cgroup == SEM_FAILED)
280 + return;
281
265 - pthread_mutex_lock(&mutex_cgroup_shm);
282 + sem_wait(shm_sem_ebpf_cgroup);
283 + int i, end = shm_ebpf_cgroup.header->cgroup_root_count;
284 + if (end <= 0) {
285 + sem_post(shm_sem_ebpf_cgroup);
286 + return;
287 + }
288
267 - ebpf_remove_cgroup_target_update_list();
289 + pthread_mutex_lock(&mutex_cgroup_shm);
290 + ebpf_remove_cgroup_target_update_list();
291
269 - ebpf_reset_updated_var();
292 + ebpf_reset_updated_var();
293
271 - for (i = 0; i < end; i++) {
272 - netdata_ebpf_cgroup_shm_body_t *ptr = &shm_ebpf_cgroup.body[i];
273 - if (ptr->enabled) {
274 - ebpf_cgroup_target_t *ect = ebpf_cgroup_find_or_create(ptr);
275 - ebpf_update_pid_link_list(ect, ptr->path);
276 - }
294 + for (i = 0; i < end; i++) {
295 + netdata_ebpf_cgroup_shm_body_t *ptr = &shm_ebpf_cgroup.body[i];
296 + if (ptr->enabled) {
297 + ebpf_cgroup_target_t *ect = ebpf_cgroup_find_or_create(ptr);
298 + ebpf_update_pid_link_list(ect, ptr->path);
299 }
278 - send_cgroup_chart = previous != shm_ebpf_cgroup.header->cgroup_root_count;
279 - previous = shm_ebpf_cgroup.header->cgroup_root_count;
300 + }
301 + send_cgroup_chart = previous != shm_ebpf_cgroup.header->cgroup_root_count;
302 + previous = shm_ebpf_cgroup.header->cgroup_root_count;
303 + sem_post(shm_sem_ebpf_cgroup);
304 + pthread_mutex_unlock(&mutex_cgroup_shm);
305 #ifdef NETDATA_DEV_MODE
281 - error("Updating cgroup %d (Previous: %d, Current: %d)", send_cgroup_chart, previous, shm_ebpf_cgroup.header->cgroup_root_count);
306 + info("Updating cgroup %d (Previous: %d, Current: %d)",
307 + send_cgroup_chart, previous, shm_ebpf_cgroup.header->cgroup_root_count);
308 #endif
283 - pthread_mutex_unlock(&mutex_cgroup_shm);
309
285 - sem_post(shm_sem_ebpf_cgroup);
286 - }
310 + sem_post(shm_sem_ebpf_cgroup);
311 }
312
313 // --------------------------------------------------------------------------------------------------------------------
@@ -315,3 +339,54 @@ void ebpf_create_charts_on_systemd(char *id, char *title, char *units, char *fam
339 fprintf(stdout, "DIMENSION %s '' %s 1 1\n", w->name, algorithm);
340 }
341 }
342 +
343 +// --------------------------------------------------------------------------------------------------------------------
344 +// Cgroup main thread
345 +
346 +/**
347 + * CGROUP exit
348 + *
349 + * Clean up the main thread.
350 + *
351 + * @param ptr thread data.
352 + */
353 +static void ebpf_cgroup_exit(void *ptr)
354 +{
355 + UNUSED(ptr);
356 +}
357 +
358 +/**
359 + * Cgroup integratin
360 + *
361 + * Thread responsible to call functions responsible to sync data between plugins.
362 + *
363 + * @param ptr It is a NULL value for this thread.
364 + *
365 + * @return It always returns NULL.
366 + */
367 +void *ebpf_cgroup_integration(void *ptr)
368 +{
369 + netdata_thread_cleanup_push(ebpf_cgroup_exit, ptr);
370 +
371 + usec_t step = USEC_PER_SEC;
372 + int counter = NETDATA_EBPF_CGROUP_UPDATE - 1;
373 + heartbeat_t hb;
374 + heartbeat_init(&hb);
375 + //Plugin will be killed when it receives a signal
376 + while (!ebpf_exit_plugin) {
377 + (void)heartbeat_next(&hb, step);
378 +
379 + // We are using a small heartbeat time to wake up thread,
380 + // but we should not update so frequently the shared memory data
381 + if (++counter >= NETDATA_EBPF_CGROUP_UPDATE) {
382 + counter = 0;
383 + if (!shm_ebpf_cgroup.header)
384 + ebpf_map_cgroup_shared_memory();
385 + else
386 + ebpf_parse_cgroup_shm_data();
387 + }
388 + }
389 +
390 + netdata_thread_cleanup_pop(1);
391 + return NULL;
392 +}
collectors/ebpf.plugin/ebpf_cgroup.h
+2
@@ -64,6 +64,8 @@ void ebpf_map_cgroup_shared_memory();
64 void ebpf_parse_cgroup_shm_data();
65 void ebpf_create_charts_on_systemd(char *id, char *title, char *units, char *family, char *charttype, int order,
66 char *algorithm, char *context, char *module, int update_every);
67 +void *ebpf_cgroup_integration(void *ptr);
68 +void ebpf_unmap_cgroup_shared_memory();
69 extern int send_cgroup_chart;
70
71 #endif /* NETDATA_EBPF_CGROUP_H */
collectors/ebpf.plugin/ebpf_dcstat.c
+5 -62
@@ -3,16 +3,11 @@
3 #include "ebpf.h"
4 #include "ebpf_dcstat.h"
5
6 -// ----------------------------------------------------------------------------
7 -// ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_dcstat_pid = NULL;
9 -
6 static char *dcstat_counter_dimension_name[NETDATA_DCSTAT_IDX_END] = { "ratio", "reference", "slow", "miss" };
7 static netdata_syscall_stat_t dcstat_counter_aggregated_data[NETDATA_DCSTAT_IDX_END];
8 static netdata_publish_syscall_t dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_END];
9
10 netdata_dcstat_pid_t *dcstat_vector = NULL;
15 -netdata_publish_dcstat_t **dcstat_pid = NULL;
11
12 static netdata_idx_t dcstat_hash_values[NETDATA_DCSTAT_IDX_END];
13 static netdata_idx_t *dcstat_values = NULL;
@@ -49,10 +44,6 @@ netdata_ebpf_targets_t dc_targets[] = { {.name = "lookup_fast", .mode = EBPF_LOA
44 {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
45
46 #ifdef LIBBPF_MAJOR_VERSION
52 -#include "includes/dc.skel.h" // BTF code
53 -
54 -static struct dc_bpf *bpf_obj = NULL;
55 -
47 /**
48 * Disable probe
49 *
@@ -298,23 +289,16 @@ void ebpf_dcstat_clean_names()
289 static void ebpf_dcstat_free(ebpf_module_t *em )
290 {
291 pthread_mutex_lock(&ebpf_exit_cleanup);
301 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
292 + em->enabled = NETDATA_THREAD_EBPF_STOPPING;
293 pthread_mutex_unlock(&ebpf_exit_cleanup);
294
295 freez(dcstat_vector);
296 freez(dcstat_values);
297
307 - ebpf_cleanup_publish_syscall(dcstat_counter_publish_aggregated);
308 -
298 ebpf_dcstat_clean_names();
299
311 -#ifdef LIBBPF_MAJOR_VERSION
312 - if (bpf_obj)
313 - dc_bpf__destroy(bpf_obj);
314 -#endif
315 -
300 pthread_mutex_lock(&ebpf_exit_cleanup);
317 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
301 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
302 pthread_mutex_unlock(&ebpf_exit_cleanup);
303 }
304
@@ -331,46 +315,6 @@ static void ebpf_dcstat_exit(void *ptr)
315 ebpf_dcstat_free(em);
316 }
317
334 -/*****************************************************************
335 - *
336 - * ARAL FUNCTIONS
337 - *
338 - *****************************************************************/
339 -
340 -/**
341 - * eBPF directory cache Aral init
342 - *
343 - * Initiallize array allocator that will be used when integration with apps is enabled.
344 - */
345 -static inline void ebpf_dcstat_aral_init()
346 -{
347 - ebpf_aral_dcstat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_DCSTAT_ARAL_NAME, sizeof(netdata_publish_dcstat_t));
348 -}
349 -
350 -/**
351 - * eBPF publish dcstat get
352 - *
353 - * Get a netdata_publish_dcstat_t entry to be used with a specific PID.
354 - *
355 - * @return it returns the address on success.
356 - */
357 -netdata_publish_dcstat_t *ebpf_publish_dcstat_get(void)
358 -{
359 - netdata_publish_dcstat_t *target = aral_mallocz(ebpf_aral_dcstat_pid);
360 - memset(target, 0, sizeof(netdata_publish_dcstat_t));
361 - return target;
362 -}
363 -
364 -/**
365 - * eBPF dcstat release
366 - *
367 - * @param stat Release a target after usage.
368 - */
369 -void ebpf_dcstat_release(netdata_publish_dcstat_t *stat)
370 -{
371 - aral_freez(ebpf_aral_dcstat_pid, stat);
372 -}
373 -
318 /*****************************************************************
319 *
320 * APPS
@@ -1150,11 +1094,11 @@ static int ebpf_dcstat_load_bpf(ebpf_module_t *em)
1094 }
1095 #ifdef LIBBPF_MAJOR_VERSION
1096 else {
1153 - bpf_obj = dc_bpf__open();
1154 - if (!bpf_obj)
1097 + dc_bpf_obj = dc_bpf__open();
1098 + if (!dc_bpf_obj)
1099 ret = -1;
1100 else
1157 - ret = ebpf_dc_load_and_attach(bpf_obj, em);
1101 + ret = ebpf_dc_load_and_attach(dc_bpf_obj, em);
1102 }
1103 #endif
1104
@@ -1188,7 +1132,6 @@ void *ebpf_dcstat_thread(void *ptr)
1132 ebpf_adjust_thread_load(em, default_btf);
1133 #endif
1134 if (ebpf_dcstat_load_bpf(em)) {
1191 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1135 goto enddcstat;
1136 }
1137
collectors/ebpf.plugin/ebpf_disk.c
+2 -6
@@ -429,7 +429,7 @@ static void ebpf_cleanup_disk_list()
429 static void ebpf_disk_free(ebpf_module_t *em)
430 {
431 pthread_mutex_lock(&ebpf_exit_cleanup);
432 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
432 + em->enabled = NETDATA_THREAD_EBPF_STOPPING;
433 pthread_mutex_unlock(&ebpf_exit_cleanup);
434
435 ebpf_disk_disable_tracepoints();
@@ -444,7 +444,7 @@ static void ebpf_disk_free(ebpf_module_t *em)
444 ebpf_cleanup_disk_list();
445
446 pthread_mutex_lock(&ebpf_exit_cleanup);
447 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
447 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
448 pthread_mutex_unlock(&ebpf_exit_cleanup);
449 }
450
@@ -761,25 +761,21 @@ void *ebpf_disk_thread(void *ptr)
761 em->maps = disk_maps;
762
763 if (ebpf_disk_enable_tracepoints()) {
764 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
764 goto enddisk;
765 }
766
767 avl_init_lock(&disk_tree, ebpf_compare_disks);
768 if (read_local_disks()) {
770 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
769 goto enddisk;
770 }
771
772 if (pthread_mutex_init(&plot_mutex, NULL)) {
775 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
773 error("Cannot initialize local mutex");
774 goto enddisk;
775 }
776
777 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
778 if (!em->probe_links) {
782 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
779 goto enddisk;
780 }
781
collectors/ebpf.plugin/ebpf_fd.c
+5 -62
@@ -3,10 +3,6 @@
3 #include "ebpf.h"
4 #include "ebpf_fd.h"
5
6 -// ----------------------------------------------------------------------------
7 -// ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_fd_pid = NULL;
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
@@ -40,17 +36,12 @@ static netdata_idx_t fd_hash_values[NETDATA_FD_COUNTER];
36 static netdata_idx_t *fd_values = NULL;
37
38 netdata_fd_stat_t *fd_vector = NULL;
43 -netdata_fd_stat_t **fd_pid = NULL;
39
40 netdata_ebpf_targets_t fd_targets[] = { {.name = "open", .mode = EBPF_LOAD_TRAMPOLINE},
41 {.name = "close", .mode = EBPF_LOAD_TRAMPOLINE},
42 {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
43
44 #ifdef LIBBPF_MAJOR_VERSION
50 -#include "includes/fd.skel.h" // BTF code
51 -
52 -static struct fd_bpf *bpf_obj = NULL;
53 -
45 /**
46 * Disable probe
47 *
@@ -368,20 +359,14 @@ static inline int ebpf_fd_load_and_attach(struct fd_bpf *obj, ebpf_module_t *em)
359 static void ebpf_fd_free(ebpf_module_t *em)
360 {
361 pthread_mutex_lock(&ebpf_exit_cleanup);
371 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
362 + em->enabled = NETDATA_THREAD_EBPF_STOPPING;
363 pthread_mutex_unlock(&ebpf_exit_cleanup);
364
374 - ebpf_cleanup_publish_syscall(fd_publish_aggregated);
365 freez(fd_values);
366 freez(fd_vector);
367
378 -#ifdef LIBBPF_MAJOR_VERSION
379 - if (bpf_obj)
380 - fd_bpf__destroy(bpf_obj);
381 -#endif
382 -
368 pthread_mutex_lock(&ebpf_exit_cleanup);
384 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
369 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
370 pthread_mutex_unlock(&ebpf_exit_cleanup);
371 }
372
@@ -398,46 +383,6 @@ static void ebpf_fd_exit(void *ptr)
383 ebpf_fd_free(em);
384 }
385
401 -/*****************************************************************
402 - *
403 - * ARAL FUNCTIONS
404 - *
405 - *****************************************************************/
406 -
407 -/**
408 - * eBPF file descriptor Aral init
409 - *
410 - * Initiallize array allocator that will be used when integration with apps is enabled.
411 - */
412 -static inline void ebpf_fd_aral_init()
413 -{
414 - ebpf_aral_fd_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_FD_ARAL_NAME, sizeof(netdata_fd_stat_t));
415 -}
416 -
417 -/**
418 - * eBPF publish file descriptor get
419 - *
420 - * Get a netdata_fd_stat_t entry to be used with a specific PID.
421 - *
422 - * @return it returns the address on success.
423 - */
424 -netdata_fd_stat_t *ebpf_fd_stat_get(void)
425 -{
426 - netdata_fd_stat_t *target = aral_mallocz(ebpf_aral_fd_pid);
427 - memset(target, 0, sizeof(netdata_fd_stat_t));
428 - return target;
429 -}
430 -
431 -/**
432 - * eBPF file descriptor release
433 - *
434 - * @param stat Release a target after usage.
435 - */
436 -void ebpf_fd_release(netdata_fd_stat_t *stat)
437 -{
438 - aral_freez(ebpf_aral_fd_pid, stat);
439 -}
440 -
386 /*****************************************************************
387 *
388 * MAIN LOOP
@@ -1142,17 +1087,16 @@ static int ebpf_fd_load_bpf(ebpf_module_t *em)
1087 if (em->load & EBPF_LOAD_LEGACY) {
1088 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
1089 if (!em->probe_links) {
1145 - em->enabled = CONFIG_BOOLEAN_NO;
1090 ret = -1;
1091 }
1092 }
1093 #ifdef LIBBPF_MAJOR_VERSION
1094 else {
1151 - bpf_obj = fd_bpf__open();
1152 - if (!bpf_obj)
1095 + fd_bpf_obj = fd_bpf__open();
1096 + if (!fd_bpf_obj)
1097 ret = -1;
1098 else
1155 - ret = ebpf_fd_load_and_attach(bpf_obj, em);
1099 + ret = ebpf_fd_load_and_attach(fd_bpf_obj, em);
1100 }
1101 #endif
1102
@@ -1182,7 +1126,6 @@ void *ebpf_fd_thread(void *ptr)
1126 ebpf_adjust_thread_load(em, default_btf);
1127 #endif
1128 if (ebpf_fd_load_bpf(em)) {
1185 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1129 goto endfd;
1130 }
1131
collectors/ebpf.plugin/ebpf_fd.h
-1
@@ -85,7 +85,6 @@ void *ebpf_fd_thread(void *ptr);
85 void ebpf_fd_create_apps_charts(struct ebpf_module *em, void *ptr);
86 void ebpf_fd_release(netdata_fd_stat_t *stat);
87 extern struct config fd_config;
88 -extern netdata_fd_stat_t **fd_pid;
88 extern netdata_ebpf_targets_t fd_targets[];
89
90 #endif /* NETDATA_EBPF_FD_H */
collectors/ebpf.plugin/ebpf_filesystem.c
+2 -5
@@ -329,18 +329,16 @@ void ebpf_filesystem_cleanup_ebpf_data()
329 static void ebpf_filesystem_free(ebpf_module_t *em)
330 {
331 pthread_mutex_lock(&ebpf_exit_cleanup);
332 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
332 + em->enabled = NETDATA_THREAD_EBPF_STOPPING;
333 pthread_mutex_unlock(&ebpf_exit_cleanup);
334
335 - ebpf_cleanup_publish_syscall(filesystem_publish_aggregated);
336 -
335 ebpf_filesystem_cleanup_ebpf_data();
336 if (dimensions)
337 ebpf_histogram_dimension_cleanup(dimensions, NETDATA_EBPF_HIST_MAX_BINS);
338 freez(filesystem_hash_values);
339
340 pthread_mutex_lock(&ebpf_exit_cleanup);
343 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
341 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
342 pthread_mutex_unlock(&ebpf_exit_cleanup);
343 }
344
@@ -570,7 +568,6 @@ void *ebpf_filesystem_thread(void *ptr)
568 if (em->optional)
569 info("Netdata cannot monitor the filesystems used on this host.");
570
573 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
571 goto endfilesystem;
572 }
573
collectors/ebpf.plugin/ebpf_hardirq.c
+10 -9
@@ -187,15 +187,11 @@ void ebpf_hardirq_release(hardirq_val_t *stat)
187 */
188 static void ebpf_hardirq_free(ebpf_module_t *em)
189 {
190 - pthread_mutex_lock(&ebpf_exit_cleanup);
191 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
192 - pthread_mutex_unlock(&ebpf_exit_cleanup);
193 -
190 for (int i = 0; hardirq_tracepoints[i].class != NULL; i++) {
191 ebpf_disable_tracepoint(&hardirq_tracepoints[i]);
192 }
193 pthread_mutex_lock(&ebpf_exit_cleanup);
198 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
194 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
195 pthread_mutex_unlock(&ebpf_exit_cleanup);
196 }
197
@@ -314,7 +310,9 @@ static int hardirq_parse_interrupts(char *irq_name, int irq)
310 */
311 static int hardirq_read_latency_map(int mapfd)
312 {
317 - hardirq_ebpf_static_val_t hardirq_ebpf_vals[ebpf_nprocs + 1];
313 + static hardirq_ebpf_static_val_t *hardirq_ebpf_vals = NULL;
314 + if (!hardirq_ebpf_vals)
315 + hardirq_ebpf_vals = callocz(ebpf_nprocs + 1, sizeof(hardirq_ebpf_static_val_t));
316
317 hardirq_ebpf_key_t key = {};
318 hardirq_ebpf_key_t next_key = {};
@@ -390,7 +388,9 @@ static int hardirq_read_latency_map(int mapfd)
388
389 static void hardirq_read_latency_static_map(int mapfd)
390 {
393 - hardirq_ebpf_static_val_t hardirq_ebpf_static_vals[ebpf_nprocs + 1];
391 + static hardirq_ebpf_static_val_t *hardirq_ebpf_static_vals = NULL;
392 + if (!hardirq_ebpf_static_vals)
393 + hardirq_ebpf_static_vals = callocz(ebpf_nprocs + 1, sizeof(hardirq_ebpf_static_val_t));
394
395 uint32_t i;
396 for (i = 0; i < HARDIRQ_EBPF_STATIC_END; i++) {
@@ -489,9 +489,12 @@ static inline void hardirq_write_static_dims()
489
490 /**
491 * Main loop for this collector.
492 + *
493 + * @param em the main thread structure.
494 */
495 static void hardirq_collector(ebpf_module_t *em)
496 {
497 + memset(&hardirq_pub, 0, sizeof(hardirq_pub));
498 avl_init_lock(&hardirq_pub, hardirq_val_cmp);
499 ebpf_hardirq_aral_init();
500
@@ -549,13 +552,11 @@ void *ebpf_hardirq_thread(void *ptr)
552 em->maps = hardirq_maps;
553
554 if (ebpf_enable_tracepoints(hardirq_tracepoints) == 0) {
552 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
555 goto endhardirq;
556 }
557
558 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
559 if (!em->probe_links) {
558 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
560 goto endhardirq;
561 }
562
collectors/ebpf.plugin/ebpf_mdflush.c
+2 -7
@@ -46,7 +46,7 @@ static void ebpf_mdflush_free(ebpf_module_t *em)
46 {
47 freez(mdflush_ebpf_vals);
48 pthread_mutex_lock(&ebpf_exit_cleanup);
49 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
49 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
50 pthread_mutex_unlock(&ebpf_exit_cleanup);
51 }
52
@@ -247,24 +247,19 @@ void *ebpf_mdflush_thread(void *ptr)
247
248 char *md_flush_request = ebpf_find_symbol("md_flush_request");
249 if (!md_flush_request) {
250 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
250 error("Cannot monitor MD devices, because md is not loaded.");
252 - }
253 - freez(md_flush_request);
254 -
255 - if (em->thread->enabled == NETDATA_THREAD_EBPF_STOPPED) {
251 goto endmdflush;
252 }
253
254 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
255 if (!em->probe_links) {
261 - em->enabled = NETDATA_THREAD_EBPF_STOPPED;
256 goto endmdflush;
257 }
258
259 mdflush_collector(em);
260
261 endmdflush:
262 + freez(md_flush_request);
263 ebpf_update_disabled_plugin_stats(em);
264
265 netdata_thread_cleanup_pop(1);
collectors/ebpf.plugin/ebpf_mount.c
+8 -24
@@ -18,8 +18,6 @@ struct config mount_config = { .first_section = NULL, .last_section = NULL, .mut
18 .index = {.avl_tree = { .root = NULL, .compar = appconfig_section_compare },
19 .rwlock = AVL_LOCK_INITIALIZER } };
20
21 -static netdata_idx_t *mount_values = NULL;
22 -
21 static netdata_idx_t mount_hash_values[NETDATA_MOUNT_END];
22
23 netdata_ebpf_targets_t mount_targets[] = { {.name = "mount", .mode = EBPF_LOAD_TRAMPOLINE},
@@ -27,10 +25,6 @@ netdata_ebpf_targets_t mount_targets[] = { {.name = "mount", .mode = EBPF_LOAD_T
25 {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
26
27 #ifdef LIBBPF_MAJOR_VERSION
30 -#include "includes/mount.skel.h" // BTF code
31 -
32 -static struct mount_bpf *bpf_obj = NULL;
33 -
28 /*****************************************************************
29 *
30 * BTF FUNCTIONS
@@ -228,18 +222,7 @@ static inline int ebpf_mount_load_and_attach(struct mount_bpf *obj, ebpf_module_
222 static void ebpf_mount_free(ebpf_module_t *em)
223 {
224 pthread_mutex_lock(&ebpf_exit_cleanup);
231 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
232 - pthread_mutex_unlock(&ebpf_exit_cleanup);
233 -
234 - freez(mount_values);
235 -
236 -#ifdef LIBBPF_MAJOR_VERSION
237 - if (bpf_obj)
238 - mount_bpf__destroy(bpf_obj);
239 -#endif
240 -
241 - pthread_mutex_lock(&ebpf_exit_cleanup);
242 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
225 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
226 pthread_mutex_unlock(&ebpf_exit_cleanup);
227 }
228
@@ -269,6 +252,10 @@ static void ebpf_mount_exit(void *ptr)
252 */
253 static void ebpf_mount_read_global_table()
254 {
255 + static netdata_idx_t *mount_values = NULL;
256 + if (!mount_values)
257 + mount_values = callocz((size_t)ebpf_nprocs + 1, sizeof(netdata_idx_t));
258 +
259 uint32_t idx;
260 netdata_idx_t *val = mount_hash_values;
261 netdata_idx_t *stored = mount_values;
@@ -311,7 +298,6 @@ static void ebpf_mount_send_data()
298 */
299 static void mount_collector(ebpf_module_t *em)
300 {
314 - mount_values = callocz((size_t)ebpf_nprocs, sizeof(netdata_idx_t));
301 memset(mount_hash_values, 0, sizeof(mount_hash_values));
302
303 heartbeat_t hb;
@@ -390,17 +376,16 @@ static int ebpf_mount_load_bpf(ebpf_module_t *em)
376 if (em->load & EBPF_LOAD_LEGACY) {
377 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
378 if (!em->probe_links) {
393 - em->enabled = CONFIG_BOOLEAN_NO;
379 ret = -1;
380 }
381 }
382 #ifdef LIBBPF_MAJOR_VERSION
383 else {
399 - bpf_obj = mount_bpf__open();
400 - if (!bpf_obj)
384 + mount_bpf_obj = mount_bpf__open();
385 + if (!mount_bpf_obj)
386 ret = -1;
387 else
403 - ret = ebpf_mount_load_and_attach(bpf_obj, em);
388 + ret = ebpf_mount_load_and_attach(mount_bpf_obj, em);
389 }
390 #endif
391
@@ -430,7 +415,6 @@ void *ebpf_mount_thread(void *ptr)
415 ebpf_adjust_thread_load(em, default_btf);
416 #endif
417 if (ebpf_mount_load_bpf(em)) {
433 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
418 goto endmount;
419 }
420
collectors/ebpf.plugin/ebpf_oomkill.c
+16 -17
@@ -47,7 +47,7 @@ static void oomkill_cleanup(void *ptr)
47 {
48 ebpf_module_t *em = (ebpf_module_t *)ptr;
49 pthread_mutex_lock(&ebpf_exit_cleanup);
50 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
50 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
51 pthread_mutex_unlock(&ebpf_exit_cleanup);
52 }
53
@@ -303,23 +303,24 @@ static void oomkill_collector(ebpf_module_t *em)
303 continue;
304
305 counter = 0;
306 - pthread_mutex_lock(&collect_data_mutex);
307 - pthread_mutex_lock(&lock);
306
307 uint32_t count = oomkill_read_data(keys);
310 - if (cgroups && count)
311 - ebpf_update_oomkill_cgroup(keys, count);
308 + if (!count)
309 + continue;
310
313 - // write everything from the ebpf map.
314 - if (cgroups)
311 + pthread_mutex_lock(&collect_data_mutex);
312 + pthread_mutex_lock(&lock);
313 + if (cgroups) {
314 + ebpf_update_oomkill_cgroup(keys, count);
315 + // write everything from the ebpf map.
316 ebpf_oomkill_send_cgroup_data(update_every);
317 + }
318
319 if (em->apps_charts & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) {
320 write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_OOMKILL_CHART);
321 oomkill_write_data(keys, count);
322 write_end_chart();
323 }
322 -
324 pthread_mutex_unlock(&lock);
325 pthread_mutex_unlock(&collect_data_mutex);
326 }
@@ -364,29 +365,27 @@ void *ebpf_oomkill_thread(void *ptr)
365 if (unlikely(!ebpf_all_pids || !em->apps_charts)) {
366 // When we are not running integration with apps, we won't fill necessary variables for this thread to run, so
367 // we need to disable it.
367 - if (em->thread->enabled)
368 + pthread_mutex_lock(&ebpf_exit_cleanup);
369 + if (em->enabled)
370 info("%s apps integration is completely disabled.", NETDATA_DEFAULT_OOM_DISABLED_MSG);
371 + pthread_mutex_unlock(&ebpf_exit_cleanup);
372
370 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
373 + goto endoomkill;
374 } else if (running_on_kernel < NETDATA_EBPF_KERNEL_4_14) {
372 - if (em->thread->enabled)
375 + pthread_mutex_lock(&ebpf_exit_cleanup);
376 + if (em->enabled)
377 info("%s kernel does not have necessary tracepoints.", NETDATA_DEFAULT_OOM_DISABLED_MSG);
378 + pthread_mutex_unlock(&ebpf_exit_cleanup);
379
375 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
376 - }
377 -
378 - if (em->thread->enabled == NETDATA_THREAD_EBPF_STOPPED) {
380 goto endoomkill;
381 }
382
383 if (ebpf_enable_tracepoints(oomkill_tracepoints) == 0) {
383 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
384 goto endoomkill;
385 }
386
387 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
388 if (!em->probe_links) {
389 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
389 goto endoomkill;
390 }
391
collectors/ebpf.plugin/ebpf_process.c
+14 -75
@@ -42,8 +42,6 @@ static netdata_idx_t *process_hash_values = NULL;
42 static netdata_syscall_stat_t process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_END];
43 static netdata_publish_syscall_t process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_END];
44
45 -ebpf_process_stat_t **global_process_stats = NULL;
46 -
45 int process_enabled = 0;
46 bool publish_internal_metrics = true;
47
@@ -607,58 +605,6 @@ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr)
605 em->apps_charts |= NETDATA_EBPF_APPS_FLAG_CHART_CREATED;
606 }
607
610 -/**
611 - * Create apps charts
612 - *
613 - * Call ebpf_create_chart to create the charts on apps submenu.
614 - *
615 - * @param root a pointer for the targets.
616 - */
617 -static void ebpf_create_apps_charts(struct ebpf_target *root)
618 -{
619 - if (unlikely(!ebpf_all_pids))
620 - return;
621 -
622 - struct ebpf_target *w;
623 - int newly_added = 0;
624 -
625 - for (w = root; w; w = w->next) {
626 - if (w->target)
627 - continue;
628 -
629 - if (unlikely(w->processes && (debug_enabled || w->debug_enabled))) {
630 - struct ebpf_pid_on_target *pid_on_target;
631 -
632 - fprintf(
633 - stderr, "ebpf.plugin: target '%s' has aggregated %u process%s:", w->name, w->processes,
634 - (w->processes == 1) ? "" : "es");
635 -
636 - for (pid_on_target = w->root_pid; pid_on_target; pid_on_target = pid_on_target->next) {
637 - fprintf(stderr, " %d", pid_on_target->pid);
638 - }
639 -
640 - fputc('\n', stderr);
641 - }
642 -
643 - if (!w->exposed && w->processes) {
644 - newly_added++;
645 - w->exposed = 1;
646 - if (debug_enabled || w->debug_enabled)
647 - debug_log_int("%s just added - regenerating charts.", w->name);
648 - }
649 - }
650 -
651 - if (!newly_added)
652 - return;
653 -
654 - int counter;
655 - for (counter = 0; ebpf_modules[counter].thread_name; counter++) {
656 - ebpf_module_t *current = &ebpf_modules[counter];
657 - if (current->enabled && current->apps_charts && current->apps_routine)
658 - current->apps_routine(current, root);
659 - }
660 -}
661 -
608 /*****************************************************************
609 *
610 * FUNCTIONS TO CLOSE THE THREAD
@@ -700,13 +646,13 @@ static void ebpf_process_exit(void *ptr)
646 {
647 ebpf_module_t *em = (ebpf_module_t *)ptr;
648
703 - ebpf_cleanup_publish_syscall(process_publish_aggregated);
649 freez(process_hash_values);
650
651 ebpf_process_disable_tracepoints();
652
653 pthread_mutex_lock(&ebpf_exit_cleanup);
709 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
654 + process_pid_fd = -1;
655 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
656 pthread_mutex_unlock(&ebpf_exit_cleanup);
657 }
658
@@ -1033,8 +979,7 @@ void ebpf_process_update_cgroup_algorithm()
979 int i;
980 for (i = 0; i < NETDATA_KEY_PUBLISH_PROCESS_END; i++) {
981 netdata_publish_syscall_t *ptr = &process_publish_aggregated[i];
1036 - freez(ptr->algorithm);
1037 - ptr->algorithm = strdupz(ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX]);
982 + ptr->algorithm = ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX];
983 }
984 }
985
@@ -1078,29 +1023,21 @@ static void process_collector(ebpf_module_t *em)
1023 heartbeat_init(&hb);
1024 int publish_global = em->global_charts;
1025 int cgroups = em->cgroup_charts;
1026 + pthread_mutex_lock(&ebpf_exit_cleanup);
1027 int thread_enabled = em->enabled;
1028 + process_pid_fd = process_maps[NETDATA_PROCESS_PID_TABLE].map_fd;
1029 + pthread_mutex_unlock(&ebpf_exit_cleanup);
1030 if (cgroups)
1031 ebpf_process_update_cgroup_algorithm();
1032
1085 - int update_apps_every = (int) EBPF_CFG_UPDATE_APPS_EVERY_DEFAULT;
1086 - int pid_fd = process_maps[NETDATA_PROCESS_PID_TABLE].map_fd;
1033 int update_every = em->update_every;
1034 int counter = update_every - 1;
1089 - int update_apps_list = update_apps_every - 1;
1035 while (!ebpf_exit_plugin) {
1036 usec_t dt = heartbeat_next(&hb, USEC_PER_SEC);
1037 (void)dt;
1038 if (ebpf_exit_plugin)
1039 break;
1040
1096 - pthread_mutex_lock(&collect_data_mutex);
1097 - if (++update_apps_list == update_apps_every) {
1098 - update_apps_list = 0;
1099 - cleanup_exited_pids();
1100 - collect_data_for_all_processes(pid_fd);
1101 - }
1102 - pthread_mutex_unlock(&collect_data_mutex);
1103 -
1041 if (++counter == update_every) {
1042 counter = 0;
1043
@@ -1109,7 +1046,6 @@ static void process_collector(ebpf_module_t *em)
1046 netdata_apps_integration_flags_t apps_enabled = em->apps_charts;
1047 pthread_mutex_lock(&collect_data_mutex);
1048
1112 - ebpf_create_apps_charts(apps_groups_root_target);
1049 if (ebpf_all_pids_count > 0) {
1050 if (cgroups && shm_ebpf_cgroup.header) {
1051 ebpf_update_process_cgroup();
@@ -1119,7 +1055,7 @@ static void process_collector(ebpf_module_t *em)
1055 pthread_mutex_lock(&lock);
1056 ebpf_send_statistic_data();
1057
1122 - if (thread_enabled) {
1058 + if (thread_enabled == NETDATA_THREAD_EBPF_RUNNING) {
1059 if (publish_global) {
1060 ebpf_process_send_data(em);
1061 }
@@ -1244,10 +1180,12 @@ void *ebpf_process_thread(void *ptr)
1180 ebpf_module_t *em = (ebpf_module_t *)ptr;
1181 em->maps = process_maps;
1182
1183 + pthread_mutex_lock(&ebpf_exit_cleanup);
1184 if (ebpf_process_enable_tracepoints()) {
1248 - em->enabled = em->global_charts = em->apps_charts = em->cgroup_charts = CONFIG_BOOLEAN_NO;
1185 + em->enabled = em->global_charts = em->apps_charts = em->cgroup_charts = NETDATA_THREAD_EBPF_STOPPING;
1186 }
1187 process_enabled = em->enabled;
1188 + pthread_mutex_unlock(&ebpf_exit_cleanup);
1189
1190 pthread_mutex_lock(&lock);
1191 ebpf_process_allocate_global_vectors(NETDATA_KEY_PUBLISH_PROCESS_END);
@@ -1257,7 +1195,6 @@ void *ebpf_process_thread(void *ptr)
1195 set_local_pointers();
1196 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
1197 if (!em->probe_links) {
1260 - em->enabled = CONFIG_BOOLEAN_NO;
1198 pthread_mutex_unlock(&lock);
1199 goto endprocess;
1200 }
@@ -1270,7 +1207,7 @@ void *ebpf_process_thread(void *ptr)
1207 process_aggregated_data, process_publish_aggregated, process_dimension_names, process_id_names,
1208 algorithms, NETDATA_KEY_PUBLISH_PROCESS_END);
1209
1273 - if (process_enabled) {
1210 + if (process_enabled == NETDATA_THREAD_EBPF_RUNNING) {
1211 ebpf_create_global_charts(em);
1212 }
1213
@@ -1289,8 +1226,10 @@ void *ebpf_process_thread(void *ptr)
1226 process_collector(em);
1227
1228 endprocess:
1292 - if (!em->enabled)
1229 + pthread_mutex_lock(&ebpf_exit_cleanup);
1230 + if (em->enabled == NETDATA_THREAD_EBPF_RUNNING)
1231 ebpf_update_disabled_plugin_stats(em);
1232 + pthread_mutex_unlock(&ebpf_exit_cleanup);
1233
1234 netdata_thread_cleanup_pop(1);
1235 return NULL;
collectors/ebpf.plugin/ebpf_shm.c
+4 -67
@@ -3,10 +3,6 @@
3 #include "ebpf.h"
4 #include "ebpf_shm.h"
5
6 -// ----------------------------------------------------------------------------
7 -// ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_shm_pid = NULL;
9 -
6 static char *shm_dimension_name[NETDATA_SHM_END] = { "get", "at", "dt", "ctl" };
7 static netdata_syscall_stat_t shm_aggregated_data[NETDATA_SHM_END];
8 static netdata_publish_syscall_t shm_publish_aggregated[NETDATA_SHM_END];
@@ -16,8 +12,6 @@ netdata_publish_shm_t *shm_vector = NULL;
12 static netdata_idx_t shm_hash_values[NETDATA_SHM_END];
13 static netdata_idx_t *shm_values = NULL;
14
19 -netdata_publish_shm_t **shm_pid = NULL;
20 -
15 struct config shm_config = { .first_section = NULL,
16 .last_section = NULL,
17 .mutex = NETDATA_MUTEX_INITIALIZER,
@@ -45,10 +39,6 @@ netdata_ebpf_targets_t shm_targets[] = { {.name = "shmget", .mode = EBPF_LOAD_TR
39 {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
40
41 #ifdef LIBBPF_MAJOR_VERSION
48 -#include "includes/shm.skel.h"
49 -
50 -static struct shm_bpf *bpf_obj = NULL;
51 -
42 /*****************************************************************
43 *
44 * BTF FUNCTIONS
@@ -291,22 +281,11 @@ static inline int ebpf_shm_load_and_attach(struct shm_bpf *obj, ebpf_module_t *e
281 */
282 static void ebpf_shm_free(ebpf_module_t *em)
283 {
294 - pthread_mutex_lock(&ebpf_exit_cleanup);
295 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
296 - pthread_mutex_unlock(&ebpf_exit_cleanup);
297 -
298 - ebpf_cleanup_publish_syscall(shm_publish_aggregated);
299 -
284 freez(shm_vector);
285 freez(shm_values);
286
303 -#ifdef LIBBPF_MAJOR_VERSION
304 - if (bpf_obj)
305 - shm_bpf__destroy(bpf_obj);
306 -#endif
307 -
287 pthread_mutex_lock(&ebpf_exit_cleanup);
309 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
288 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
289 pthread_mutex_unlock(&ebpf_exit_cleanup);
290 }
291
@@ -323,46 +302,6 @@ static void ebpf_shm_exit(void *ptr)
302 ebpf_shm_free(em);
303 }
304
326 -/*****************************************************************
327 - *
328 - * ARAL FUNCTIONS
329 - *
330 - *****************************************************************/
331 -
332 -/**
333 - * eBPF shared memory Aral init
334 - *
335 - * Initiallize array allocator that will be used when integration with apps is enabled.
336 - */
337 -static inline void ebpf_shm_aral_init()
338 -{
339 - ebpf_aral_shm_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SHM_ARAL_NAME, sizeof(netdata_publish_shm_t));
340 -}
341 -
342 -/**
343 - * eBPF shared memory get
344 - *
345 - * Get a netdata_publish_shm_t entry to be used with a specific PID.
346 - *
347 - * @return it returns the address on success.
348 - */
349 -netdata_publish_shm_t *ebpf_shm_stat_get(void)
350 -{
351 - netdata_publish_shm_t *target = aral_mallocz(ebpf_aral_shm_pid);
352 - memset(target, 0, sizeof(netdata_publish_shm_t));
353 - return target;
354 -}
355 -
356 -/**
357 - * eBPF shared memory release
358 - *
359 - * @param stat Release a target after usage.
360 - */
361 -void ebpf_shm_release(netdata_publish_shm_t *stat)
362 -{
363 - aral_freez(ebpf_aral_shm_pid, stat);
364 -}
365 -
305 /*****************************************************************
306 * COLLECTOR THREAD
307 *****************************************************************/
@@ -1051,17 +990,16 @@ static int ebpf_shm_load_bpf(ebpf_module_t *em)
990 if (em->load & EBPF_LOAD_LEGACY) {
991 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
992 if (!em->probe_links) {
1054 - em->enabled = CONFIG_BOOLEAN_NO;
993 ret = -1;
994 }
995 }
996 #ifdef LIBBPF_MAJOR_VERSION
997 else {
1060 - bpf_obj = shm_bpf__open();
1061 - if (!bpf_obj)
998 + shm_bpf_obj = shm_bpf__open();
999 + if (!shm_bpf_obj)
1000 ret = -1;
1001 else
1064 - ret = ebpf_shm_load_and_attach(bpf_obj, em);
1002 + ret = ebpf_shm_load_and_attach(shm_bpf_obj, em);
1003 }
1004 #endif
1005
@@ -1091,7 +1029,6 @@ void *ebpf_shm_thread(void *ptr)
1029 ebpf_adjust_thread_load(em, default_btf);
1030 #endif
1031 if (ebpf_shm_load_bpf(em)) {
1094 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1032 goto endshm;
1033 }
1034
collectors/ebpf.plugin/ebpf_shm.h
-2
@@ -53,8 +53,6 @@ enum shm_counters {
53 NETDATA_SHM_END
54 };
55
56 -extern netdata_publish_shm_t **shm_pid;
57 -
56 void *ebpf_shm_thread(void *ptr);
57 void ebpf_shm_create_apps_charts(struct ebpf_module *em, void *ptr);
58 void ebpf_shm_release(netdata_publish_shm_t *stat);
collectors/ebpf.plugin/ebpf_socket.c
+17 -92
@@ -7,7 +7,6 @@
7
8 // ----------------------------------------------------------------------------
9 // ARAL vectors used to speed up processing
10 -ARAL *ebpf_aral_socket_pid = NULL;
10
11 /*****************************************************************
12 *
@@ -62,7 +61,6 @@ static netdata_idx_t *socket_hash_values = NULL;
61 static netdata_syscall_stat_t socket_aggregated_data[NETDATA_MAX_SOCKET_VECTOR];
62 static netdata_publish_syscall_t socket_publish_aggregated[NETDATA_MAX_SOCKET_VECTOR];
63
65 -ebpf_socket_publish_apps_t **socket_bandwidth_curr = NULL;
64 static ebpf_bandwidth_t *bandwidth_vector = NULL;
65
66 pthread_mutex_t nv_mutex;
@@ -101,10 +99,6 @@ struct netdata_static_thread socket_threads = {
99 };
100
101 #ifdef LIBBPF_MAJOR_VERSION
104 -#include "includes/socket.skel.h" // BTF code
105 -
106 -static struct socket_bpf *bpf_obj = NULL;
107 -
102 /**
103 * Disable Probe
104 *
@@ -433,46 +427,6 @@ static inline int ebpf_socket_load_and_attach(struct socket_bpf *obj, ebpf_modul
427 }
428 #endif
429
436 -/*****************************************************************
437 - *
438 - * ARAL FUNCTIONS
439 - *
440 - *****************************************************************/
441 -
442 -/**
443 - * eBPF socket Aral init
444 - *
445 - * Initiallize array allocator that will be used when integration with apps is enabled.
446 - */
447 -static inline void ebpf_socket_aral_init()
448 -{
449 - ebpf_aral_socket_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SOCKET_ARAL_NAME, sizeof(ebpf_socket_publish_apps_t));
450 -}
451 -
452 -/**
453 - * eBPF socket get
454 - *
455 - * Get a ebpf_socket_publish_apps_t entry to be used with a specific PID.
456 - *
457 - * @return it returns the address on success.
458 - */
459 -ebpf_socket_publish_apps_t *ebpf_socket_stat_get(void)
460 -{
461 - ebpf_socket_publish_apps_t *target = aral_mallocz(ebpf_aral_socket_pid);
462 - memset(target, 0, sizeof(ebpf_socket_publish_apps_t));
463 - return target;
464 -}
465 -
466 -/**
467 - * eBPF socket release
468 - *
469 - * @param stat Release a target after usage.
470 - */
471 -void ebpf_socket_release(ebpf_socket_publish_apps_t *stat)
472 -{
473 - aral_freez(ebpf_aral_socket_pid, stat);
474 -}
475 -
430 /*****************************************************************
431 *
432 * FUNCTIONS TO CLOSE THE THREAD
@@ -498,7 +452,6 @@ static inline void clean_internal_socket_plot(netdata_socket_plot_t *ptr)
452 * Clean socket plot
453 *
454 * Clean the allocated data for inbound and outbound vectors.
501 - */
455 static void clean_allocated_socket_plot()
456 {
457 if (!network_viewer_opt.enabled)
@@ -520,12 +473,12 @@ static void clean_allocated_socket_plot()
473 }
474 clean_internal_socket_plot(&plot[outbound_vectors.last]);
475 }
476 + */
477
478 /**
479 * Clean network ports allocated during initialization.
480 *
481 * @param ptr a pointer to the link list.
528 - */
482 static void clean_network_ports(ebpf_network_viewer_port_list_t *ptr)
483 {
484 if (unlikely(!ptr))
@@ -538,6 +491,7 @@ static void clean_network_ports(ebpf_network_viewer_port_list_t *ptr)
491 ptr = next;
492 }
493 }
494 + */
495
496 /**
497 * Clean service names
@@ -545,7 +499,6 @@ static void clean_network_ports(ebpf_network_viewer_port_list_t *ptr)
499 * Clean the allocated link list that stores names.
500 *
501 * @param names the link list.
548 - */
502 static void clean_service_names(ebpf_network_viewer_dim_name_t *names)
503 {
504 if (unlikely(!names))
@@ -558,12 +511,12 @@ static void clean_service_names(ebpf_network_viewer_dim_name_t *names)
511 names = next;
512 }
513 }
514 + */
515
516 /**
517 * Clean hostnames
518 *
519 * @param hostnames the hostnames to clean
566 - */
520 static void clean_hostnames(ebpf_network_viewer_hostname_list_t *hostnames)
521 {
522 if (unlikely(!hostnames))
@@ -577,19 +530,7 @@ static void clean_hostnames(ebpf_network_viewer_hostname_list_t *hostnames)
530 hostnames = next;
531 }
532 }
580 -
581 -/**
582 - * Cleanup publish syscall
583 - *
584 - * @param nps list of structures to clean
533 */
586 -void ebpf_cleanup_publish_syscall(netdata_publish_syscall_t *nps)
587 -{
588 - while (nps) {
589 - freez(nps->algorithm);
590 - nps = nps->next;
591 - }
592 -}
534
535 /**
536 * Clean port Structure
@@ -640,15 +581,8 @@ static void clean_ip_structure(ebpf_network_viewer_ip_list_t **clean)
581 */
582 static void ebpf_socket_free(ebpf_module_t *em )
583 {
643 - pthread_mutex_lock(&ebpf_exit_cleanup);
644 - if (em->thread->enabled == NETDATA_THREAD_EBPF_RUNNING) {
645 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
646 - pthread_mutex_unlock(&ebpf_exit_cleanup);
647 - return;
648 - }
649 - pthread_mutex_unlock(&ebpf_exit_cleanup);
650 -
651 - ebpf_cleanup_publish_syscall(socket_publish_aggregated);
584 + /* We can have thousands of sockets to clean, so we are transferring
585 + * for OS the responsibility while we do not use ARAL here
586 freez(socket_hash_values);
587
588 freez(bandwidth_vector);
@@ -660,25 +594,17 @@ static void ebpf_socket_free(ebpf_module_t *em )
594
595 clean_port_structure(&listen_ports);
596
663 - ebpf_modules[EBPF_MODULE_SOCKET_IDX].enabled = 0;
664 -
597 clean_network_ports(network_viewer_opt.included_port);
598 clean_network_ports(network_viewer_opt.excluded_port);
599 clean_service_names(network_viewer_opt.names);
600 clean_hostnames(network_viewer_opt.included_hostnames);
601 clean_hostnames(network_viewer_opt.excluded_hostnames);
602 + */
603
604 pthread_mutex_destroy(&nv_mutex);
605
673 - freez(socket_threads.thread);
674 -
675 -#ifdef LIBBPF_MAJOR_VERSION
676 - if (bpf_obj)
677 - socket_bpf__destroy(bpf_obj);
678 -#endif
679 -
606 pthread_mutex_lock(&ebpf_exit_cleanup);
681 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
607 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
608 pthread_mutex_unlock(&ebpf_exit_cleanup);
609 }
610
@@ -692,8 +618,10 @@ static void ebpf_socket_free(ebpf_module_t *em )
618 static void ebpf_socket_exit(void *ptr)
619 {
620 ebpf_module_t *em = (ebpf_module_t *)ptr;
621 + pthread_mutex_lock(&nv_mutex);
622 if (socket_threads.thread)
623 netdata_thread_cancel(*socket_threads.thread);
624 + pthread_mutex_unlock(&nv_mutex);
625 ebpf_socket_free(em);
626 }
627
@@ -706,8 +634,7 @@ static void ebpf_socket_exit(void *ptr)
634 */
635 void ebpf_socket_cleanup(void *ptr)
636 {
709 - ebpf_module_t *em = (ebpf_module_t *)ptr;
710 - ebpf_socket_free(em);
637 + UNUSED(ptr);
638 }
639
640 /*****************************************************************
@@ -2200,10 +2127,11 @@ void *ebpf_socket_read_hash(void *ptr)
2127 heartbeat_init(&hb);
2128 int fd_ipv4 = socket_maps[NETDATA_SOCKET_TABLE_IPV4].map_fd;
2129 int fd_ipv6 = socket_maps[NETDATA_SOCKET_TABLE_IPV6].map_fd;
2203 - while (!ebpf_exit_plugin) {
2130 + // This thread is cancelled from another thread
2131 + for (;;) {
2132 (void)heartbeat_next(&hb, USEC_PER_SEC);
2133 if (ebpf_exit_plugin)
2206 - continue;
2134 + break;
2135
2136 pthread_mutex_lock(&nv_mutex);
2137 ebpf_read_socket_hash_table(fd_ipv4, AF_INET);
@@ -2838,8 +2766,7 @@ void ebpf_socket_update_cgroup_algorithm()
2766 int i;
2767 for (i = 0; i < NETDATA_MAX_SOCKET_VECTOR; i++) {
2768 netdata_publish_syscall_t *ptr = &socket_publish_aggregated[i];
2841 - freez(ptr->algorithm);
2842 - ptr->algorithm = strdupz(ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX]);
2769 + ptr->algorithm = ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX];
2770 }
2771 }
2772
@@ -3938,11 +3865,11 @@ static int ebpf_socket_load_bpf(ebpf_module_t *em)
3865 }
3866 #ifdef LIBBPF_MAJOR_VERSION
3867 else {
3941 - bpf_obj = socket_bpf__open();
3942 - if (!bpf_obj)
3868 + socket_bpf_obj = socket_bpf__open();
3869 + if (!socket_bpf_obj)
3870 ret = -1;
3871 else
3945 - ret = ebpf_socket_load_and_attach(bpf_obj, em);
3872 + ret = ebpf_socket_load_and_attach(socket_bpf_obj, em);
3873 }
3874 #endif
3875
@@ -3972,7 +3899,6 @@ void *ebpf_socket_thread(void *ptr)
3899 parse_table_size_options(&socket_config);
3900
3901 if (pthread_mutex_init(&nv_mutex, NULL)) {
3975 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
3902 error("Cannot initialize local mutex");
3903 goto endsocket;
3904 }
@@ -3995,7 +3921,6 @@ void *ebpf_socket_thread(void *ptr)
3921 ebpf_adjust_thread_load(em, default_btf);
3922 #endif
3923 if (ebpf_socket_load_bpf(em)) {
3998 - em->enabled = CONFIG_BOOLEAN_NO;
3924 pthread_mutex_unlock(&lock);
3925 goto endsocket;
3926 }
collectors/ebpf.plugin/ebpf_socket.h
-2
@@ -366,9 +366,7 @@ void update_listen_table(uint16_t value, uint16_t proto, netdata_passive_connect
366 void parse_network_viewer_section(struct config *cfg);
367 void ebpf_fill_ip_list(ebpf_network_viewer_ip_list_t **out, ebpf_network_viewer_ip_list_t *in, char *table);
368 void parse_service_name_section(struct config *cfg);
369 -void ebpf_socket_release(ebpf_socket_publish_apps_t *stat);
369
371 -extern ebpf_socket_publish_apps_t **socket_bandwidth_curr;
370 extern struct config socket_config;
371 extern netdata_ebpf_targets_t socket_targets[];
372
collectors/ebpf.plugin/ebpf_softirq.c
+2 -4
@@ -64,7 +64,7 @@ static softirq_ebpf_val_t *softirq_ebpf_vals = NULL;
64 static void ebpf_softirq_free(ebpf_module_t *em)
65 {
66 pthread_mutex_lock(&ebpf_exit_cleanup);
67 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
67 + em->enabled = NETDATA_THREAD_EBPF_STOPPING;
68 pthread_mutex_unlock(&ebpf_exit_cleanup);
69
70 for (int i = 0; softirq_tracepoints[i].class != NULL; i++) {
@@ -73,7 +73,7 @@ static void ebpf_softirq_free(ebpf_module_t *em)
73 freez(softirq_ebpf_vals);
74
75 pthread_mutex_lock(&ebpf_exit_cleanup);
76 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
76 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
77 pthread_mutex_unlock(&ebpf_exit_cleanup);
78 }
79
@@ -209,13 +209,11 @@ void *ebpf_softirq_thread(void *ptr)
209 em->maps = softirq_maps;
210
211 if (ebpf_enable_tracepoints(softirq_tracepoints) == 0) {
212 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
212 goto endsoftirq;
213 }
214
215 em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
216 if (!em->probe_links) {
218 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
217 goto endsoftirq;
218 }
219
collectors/ebpf.plugin/ebpf_swap.c
+2 -19
@@ -7,12 +7,10 @@ static char *swap_dimension_name[NETDATA_SWAP_END] = { "read", "write" };
7 static netdata_syscall_stat_t swap_aggregated_data[NETDATA_SWAP_END];
8 static netdata_publish_syscall_t swap_publish_aggregated[NETDATA_SWAP_END];
9
10 -netdata_publish_swap_t *swap_vector = NULL;
11 -
10 static netdata_idx_t swap_hash_values[NETDATA_SWAP_END];
11 static netdata_idx_t *swap_values = NULL;
12
15 -netdata_publish_swap_t **swap_pid = NULL;
13 +netdata_publish_swap_t *swap_vector = NULL;
14
15 struct config swap_config = { .first_section = NULL,
16 .last_section = NULL,
@@ -39,10 +37,6 @@ netdata_ebpf_targets_t swap_targets[] = { {.name = "swap_readpage", .mode = EBPF
37 {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
38
39 #ifdef LIBBPF_MAJOR_VERSION
42 -#include "includes/swap.skel.h" // BTF code
43 -
44 -static struct swap_bpf *bpf_obj = NULL;
45 -
40 /**
41 * Disable probe
42 *
@@ -224,21 +218,11 @@ static inline int ebpf_swap_load_and_attach(struct swap_bpf *obj, ebpf_module_t
218 */
219 static void ebpf_swap_free(ebpf_module_t *em)
220 {
227 - pthread_mutex_lock(&ebpf_exit_cleanup);
228 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
229 - pthread_mutex_unlock(&ebpf_exit_cleanup);
230 -
231 - ebpf_cleanup_publish_syscall(swap_publish_aggregated);
232 -
221 freez(swap_vector);
222 freez(swap_values);
223
236 -#ifdef LIBBPF_MAJOR_VERSION
237 - if (bpf_obj)
238 - swap_bpf__destroy(bpf_obj);
239 -#endif
224 pthread_mutex_lock(&ebpf_exit_cleanup);
241 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
225 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
226 pthread_mutex_unlock(&ebpf_exit_cleanup);
227 }
228
@@ -829,7 +813,6 @@ void *ebpf_swap_thread(void *ptr)
813 ebpf_adjust_thread_load(em, default_btf);
814 #endif
815 if (ebpf_swap_load_bpf(em)) {
832 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
816 goto endswap;
817 }
818
collectors/ebpf.plugin/ebpf_swap.h
-2
@@ -42,8 +42,6 @@ enum swap_counters {
42 NETDATA_SWAP_END
43 };
44
45 -extern netdata_publish_swap_t **swap_pid;
46 -
45 void *ebpf_swap_thread(void *ptr);
46 void ebpf_swap_create_apps_charts(struct ebpf_module *em, void *ptr);
47
collectors/ebpf.plugin/ebpf_sync.c
+1 -6
@@ -204,16 +204,12 @@ void ebpf_sync_cleanup_objects()
204 */
205 static void ebpf_sync_free(ebpf_module_t *em)
206 {
207 - pthread_mutex_lock(&ebpf_exit_cleanup);
208 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
209 - pthread_mutex_unlock(&ebpf_exit_cleanup);
210 -
207 #ifdef LIBBPF_MAJOR_VERSION
208 ebpf_sync_cleanup_objects();
209 #endif
210
211 pthread_mutex_lock(&ebpf_exit_cleanup);
216 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
212 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
213 pthread_mutex_unlock(&ebpf_exit_cleanup);
214 }
215
@@ -523,7 +519,6 @@ void *ebpf_sync_thread(void *ptr)
519 ebpf_adjust_thread_load(em, default_btf);
520 #endif
521 if (ebpf_sync_initialize_syscall(em)) {
526 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
522 goto endsync;
523 }
524
collectors/ebpf.plugin/ebpf_vfs.c
+4 -63
@@ -5,10 +5,6 @@
5 #include "ebpf.h"
6 #include "ebpf_vfs.h"
7
8 -// ----------------------------------------------------------------------------
9 -// ARAL vectors used to speed up processing
10 -ARAL *ebpf_aral_vfs_pid = NULL;
11 -
8 static char *vfs_dimension_names[NETDATA_KEY_PUBLISH_VFS_END] = { "delete", "read", "write",
9 "fsync", "open", "create" };
10 static char *vfs_id_names[NETDATA_KEY_PUBLISH_VFS_END] = { "vfs_unlink", "vfs_read", "vfs_write",
@@ -17,7 +13,6 @@ static char *vfs_id_names[NETDATA_KEY_PUBLISH_VFS_END] = { "vfs_unlink", "vfs_re
13 static netdata_idx_t *vfs_hash_values = NULL;
14 static netdata_syscall_stat_t vfs_aggregated_data[NETDATA_KEY_PUBLISH_VFS_END];
15 static netdata_publish_syscall_t vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_END];
20 -netdata_publish_vfs_t **vfs_pid = NULL;
16 netdata_publish_vfs_t *vfs_vector = NULL;
17
18 static ebpf_local_maps_t vfs_maps[] = {{.name = "tbl_vfs_pid", .internal_input = ND_EBPF_DEFAULT_PID_SIZE,
@@ -50,10 +45,6 @@ netdata_ebpf_targets_t vfs_targets[] = { {.name = "vfs_write", .mode = EBPF_LOAD
45 {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
46
47 #ifdef LIBBPF_MAJOR_VERSION
53 -#include "includes/vfs.skel.h" // BTF code
54 -
55 -static struct vfs_bpf *bpf_obj = NULL;
56 -
48 /**
49 * Disable probe
50 *
@@ -386,46 +377,6 @@ static inline int ebpf_vfs_load_and_attach(struct vfs_bpf *obj, ebpf_module_t *e
377 }
378 #endif
379
389 -/*****************************************************************
390 - *
391 - * ARAL FUNCTIONS
392 - *
393 - *****************************************************************/
394 -
395 -/**
396 - * eBPF VFS Aral init
397 - *
398 - * Initiallize array allocator that will be used when integration with apps is enabled.
399 - */
400 -static inline void ebpf_vfs_aral_init()
401 -{
402 - ebpf_aral_vfs_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_VFS_ARAL_NAME, sizeof(netdata_publish_vfs_t));
403 -}
404 -
405 -/**
406 - * eBPF publish VFS get
407 - *
408 - * Get a netdata_publish_vfs_t entry to be used with a specific PID.
409 - *
410 - * @return it returns the address on success.
411 - */
412 -netdata_publish_vfs_t *ebpf_vfs_get(void)
413 -{
414 - netdata_publish_vfs_t *target = aral_mallocz(ebpf_aral_vfs_pid);
415 - memset(target, 0, sizeof(netdata_publish_vfs_t));
416 - return target;
417 -}
418 -
419 -/**
420 - * eBPF VFS release
421 - *
422 - * @param stat Release a target after usage.
423 - */
424 -void ebpf_vfs_release(netdata_publish_vfs_t *stat)
425 -{
426 - aral_freez(ebpf_aral_vfs_pid, stat);
427 -}
428 -
380 /*****************************************************************
381 *
382 * FUNCTIONS TO CLOSE THE THREAD
@@ -441,20 +392,11 @@ void ebpf_vfs_release(netdata_publish_vfs_t *stat)
392 */
393 static void ebpf_vfs_free(ebpf_module_t *em)
394 {
444 - pthread_mutex_lock(&ebpf_exit_cleanup);
445 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPING;
446 - pthread_mutex_unlock(&ebpf_exit_cleanup);
447 -
395 freez(vfs_hash_values);
396 freez(vfs_vector);
397
451 -#ifdef LIBBPF_MAJOR_VERSION
452 - if (bpf_obj)
453 - vfs_bpf__destroy(bpf_obj);
454 -#endif
455 -
398 pthread_mutex_lock(&ebpf_exit_cleanup);
457 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
399 + em->enabled = NETDATA_THREAD_EBPF_STOPPED;
400 pthread_mutex_unlock(&ebpf_exit_cleanup);
401 }
402
@@ -1911,11 +1853,11 @@ static int ebpf_vfs_load_bpf(ebpf_module_t *em)
1853 }
1854 #ifdef LIBBPF_MAJOR_VERSION
1855 else {
1914 - bpf_obj = vfs_bpf__open();
1915 - if (!bpf_obj)
1856 + vfs_bpf_obj = vfs_bpf__open();
1857 + if (!vfs_bpf_obj)
1858 ret = -1;
1859 else
1918 - ret = ebpf_vfs_load_and_attach(bpf_obj, em);
1860 + ret = ebpf_vfs_load_and_attach(vfs_bpf_obj, em);
1861 }
1862 #endif
1863
@@ -1946,7 +1888,6 @@ void *ebpf_vfs_thread(void *ptr)
1888 ebpf_adjust_thread_load(em, default_btf);
1889 #endif
1890 if (ebpf_vfs_load_bpf(em)) {
1949 - em->thread->enabled = NETDATA_THREAD_EBPF_STOPPED;
1891 goto endvfs;
1892 }
1893
collectors/ebpf.plugin/ebpf_vfs.h
-2
@@ -167,8 +167,6 @@ enum netdata_vfs_calls_name {
167 NETDATA_VFS_END_LIST
168 };
169
170 -extern netdata_publish_vfs_t **vfs_pid;
171 -
170 void *ebpf_vfs_thread(void *ptr);
171 void ebpf_vfs_create_apps_charts(struct ebpf_module *em, void *ptr);
172 void ebpf_vfs_release(netdata_publish_vfs_t *stat);
libnetdata/ebpf/ebpf.c
+1 -1
@@ -441,7 +441,7 @@ void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em)
441 report->threads++;
442
443 // It is not necessary to report more information.
444 - if (!em->enabled)
444 + if (em->enabled != NETDATA_THREAD_EBPF_RUNNING)
445 return;
446
447 report->running++;
libnetdata/ebpf/ebpf.h
+8 -1
@@ -260,10 +260,17 @@ typedef enum netdata_apps_integration_flags {
260 #define NETDATA_EBPF_STAT_DIMENSION_MEMORY "memory"
261 #define NETDATA_EBPF_STAT_DIMENSION_ARAL "aral"
262
263 +enum ebpf_threads_status {
264 + NETDATA_THREAD_EBPF_RUNNING,
265 + NETDATA_THREAD_EBPF_STOPPING,
266 + NETDATA_THREAD_EBPF_STOPPED,
267 + NETDATA_THREAD_EBPF_NOT_RUNNING
268 +};
269 +
270 typedef struct ebpf_module {
271 const char *thread_name;
272 const char *config_name;
266 - int enabled;
273 + enum ebpf_threads_status enabled;
274 void *(*start_routine)(void *);
275 int update_every;
276 int global_charts;