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;