@cryptotaxi247 / netdata-1 / commits / b3f59597c

eBPF new charts (user ring) (#14623)

thiagoftsm committed Mar 8, 2023 at 14:49 UTC b3f59597c47f108df1303eeb2702b487c08a188e
28 files changed +393 -20
collectors/ebpf.plugin/ebpf.c
+75 -1
@@ -446,7 +446,8 @@ ebpf_network_viewer_options_t network_viewer_opt;
446
447 // Statistic
448 ebpf_plugin_stats_t plugin_statistics = {.core = 0, .legacy = 0, .running = 0, .threads = 0, .tracepoints = 0,
449 - .probes = 0, .retprobes = 0, .trampolines = 0};
449 + .probes = 0, .retprobes = 0, .trampolines = 0, .memlock_kern = 0,
450 + .hash_tables = 0};
451
452 #ifdef LIBBPF_MAJOR_VERSION
453 struct btf *default_btf = NULL;
@@ -939,6 +940,79 @@ void write_histogram_chart(char *family, char *name, const netdata_idx_t *hist,
940 fflush(stdout);
941 }
942
943 +/**
944 + * ARAL Charts
945 + *
946 + * Add chart to monitor ARAL usage
947 + * Caller must call this function with mutex locked.
948 + *
949 + * @param name the name used to create aral
950 + * @param em a pointer to the structure with the default values.
951 + */
952 +void ebpf_statistic_create_aral_chart(char *name, ebpf_module_t *em)
953 +{
954 + static int priority = 140100;
955 + char *mem = { NETDATA_EBPF_STAT_DIMENSION_MEMORY };
956 + char *aral = { NETDATA_EBPF_STAT_DIMENSION_ARAL };
957 +
958 + snprintfz(em->memory_usage, NETDATA_EBPF_CHART_MEM_LENGTH -1, "aral_%s_size", name);
959 + snprintfz(em->memory_allocations, NETDATA_EBPF_CHART_MEM_LENGTH -1, "aral_%s_alloc", name);
960 +
961 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
962 + em->memory_usage,
963 + "Bytes allocated for ARAL.",
964 + "bytes",
965 + NETDATA_EBPF_FAMILY,
966 + NETDATA_EBPF_CHART_TYPE_STACKED,
967 + "netdata.ebpf_aral_stat_size",
968 + priority++,
969 + em->update_every,
970 + NETDATA_EBPF_MODULE_NAME_PROCESS);
971 +
972 + ebpf_write_global_dimension(mem,
973 + mem,
974 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
975 +
976 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
977 + em->memory_allocations,
978 + "Calls to allocate memory.",
979 + "calls",
980 + NETDATA_EBPF_FAMILY,
981 + NETDATA_EBPF_CHART_TYPE_STACKED,
982 + "netdata.ebpf_aral_stat_alloc",
983 + priority++,
984 + em->update_every,
985 + NETDATA_EBPF_MODULE_NAME_PROCESS);
986 +
987 + ebpf_write_global_dimension(aral,
988 + aral,
989 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
990 +}
991 +
992 +/**
993 + * Send data from aral chart
994 + *
995 + * Send data for eBPF plugin
996 + *
997 + * @param memory a pointer to the allocated address
998 + * @param em a pointer to the structure with the default values.
999 + */
1000 +void ebpf_send_data_aral_chart(ARAL *memory, ebpf_module_t *em)
1001 +{
1002 + char *mem = { NETDATA_EBPF_STAT_DIMENSION_MEMORY };
1003 + char *aral = { NETDATA_EBPF_STAT_DIMENSION_ARAL };
1004 +
1005 + struct aral_statistics *stats = aral_statistics(memory);
1006 +
1007 + write_begin_chart(NETDATA_MONITORING_FAMILY, em->memory_usage);
1008 + write_chart_dimension(mem, (long long)stats->structures.allocated_bytes);
1009 + write_end_chart();
1010 +
1011 + write_begin_chart(NETDATA_MONITORING_FAMILY, em->memory_allocations);
1012 + write_chart_dimension(aral, (long long)stats->structures.allocations);
1013 + write_end_chart();
1014 +}
1015 +
1016 /*****************************************************************
1017 *
1018 * FUNCTIONS TO DEFINE OPTIONS
collectors/ebpf.plugin/ebpf.h
+2
@@ -143,6 +143,8 @@ enum ebpf_threads_status {
143 // Statistics charts
144 #define NETDATA_EBPF_THREADS "ebpf_threads"
145 #define NETDATA_EBPF_LOAD_METHOD "ebpf_load_methods"
146 +#define NETDATA_EBPF_KERNEL_MEMORY "ebpf_kernel_memory"
147 +#define NETDATA_EBPF_HASH_TABLES_LOADED "ebpf_hash_tables_count"
148
149 // Log file
150 #define NETDATA_DEVELOPER_LOG_FILE "developer.log"
collectors/ebpf.plugin/ebpf_apps.c
+4 -4
@@ -6,8 +6,8 @@
6
7 // ----------------------------------------------------------------------------
8 // ARAL vectors used to speed up processing
9 -ARAL *ebpf_aral_apps_pid_stat;
10 -ARAL *ebpf_aral_process_stat;
9 +ARAL *ebpf_aral_apps_pid_stat = NULL;
10 +ARAL *ebpf_aral_process_stat = NULL;
11
12 /**
13 * eBPF ARAL Init
@@ -22,9 +22,9 @@ void ebpf_aral_init(void)
22 max_elements = NETDATA_EBPF_ALLOC_MIN_ELEMENTS;
23 }
24
25 - ebpf_aral_apps_pid_stat = ebpf_allocate_pid_aral("ebpf-pid_stat", sizeof(struct ebpf_pid_stat));
25 + ebpf_aral_apps_pid_stat = ebpf_allocate_pid_aral("ebpf_pid_stat", sizeof(struct ebpf_pid_stat));
26
27 - ebpf_aral_process_stat = ebpf_allocate_pid_aral("ebpf-proc_stat", sizeof(ebpf_process_stat_t));
27 + ebpf_aral_process_stat = ebpf_allocate_pid_aral(NETDATA_EBPF_PROC_ARAL_NAME, sizeof(ebpf_process_stat_t));
28
29 #ifdef NETDATA_DEV_MODE
30 info("Plugin is using ARAL with values %d", NETDATA_EBPF_ALLOC_MAX_PID);
collectors/ebpf.plugin/ebpf_apps.h
+5 -2
@@ -228,11 +228,14 @@ extern netdata_publish_dcstat_t **dcstat_pid;
228
229 extern void ebpf_aral_init(void);
230
231 -extern struct ebpf_pid_stat *ebpf_target_get(void);
232 -
231 extern ebpf_process_stat_t *ebpf_process_stat_get(void);
232 extern void ebpf_process_stat_release(ebpf_process_stat_t *stat);
233
234 #include "libnetdata/threads/threads.h"
235
236 +// ARAL variables
237 +extern ARAL *ebpf_aral_apps_pid_stat;
238 +extern ARAL *ebpf_aral_process_stat;
239 +#define NETDATA_EBPF_PROC_ARAL_NAME "ebpf_proc_stat"
240 +
241 #endif /* NETDATA_EBPF_APPS_H */
collectors/ebpf.plugin/ebpf_cachestat.c
+13 -2
@@ -5,7 +5,7 @@
5
6 // ----------------------------------------------------------------------------
7 // ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_cachestat_pid;
8 +ARAL *ebpf_aral_cachestat_pid = NULL;
9
10 netdata_publish_cachestat_t **cachestat_pid;
11
@@ -381,7 +381,7 @@ static void ebpf_cachestat_exit(void *ptr)
381 */
382 static inline void ebpf_cachestat_aral_init()
383 {
384 - ebpf_aral_cachestat_pid = ebpf_allocate_pid_aral("ebpf-cachestat", sizeof(netdata_publish_cachestat_t));
384 + ebpf_aral_cachestat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_CACHESTAT_ARAL_NAME, sizeof(netdata_publish_cachestat_t));
385 }
386
387 /**
@@ -1136,6 +1136,11 @@ static void cachestat_collector(ebpf_module_t *em)
1136 if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED)
1137 ebpf_cache_send_apps_data(apps_groups_root_target);
1138
1139 +#ifdef NETDATA_DEV_MODE
1140 + if (ebpf_aral_cachestat_pid)
1141 + ebpf_send_data_aral_chart(ebpf_aral_cachestat_pid, em);
1142 +#endif
1143 +
1144 if (cgroups)
1145 ebpf_cachestat_send_cgroup_data(update_every);
1146
@@ -1334,7 +1339,13 @@ void *ebpf_cachestat_thread(void *ptr)
1339
1340 pthread_mutex_lock(&lock);
1341 ebpf_update_stats(&plugin_statistics, em);
1342 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
1343 ebpf_create_memory_charts(em);
1344 +#ifdef NETDATA_DEV_MODE
1345 + if (ebpf_aral_cachestat_pid)
1346 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_CACHESTAT_ARAL_NAME, em);
1347 +#endif
1348 +
1349 pthread_mutex_unlock(&lock);
1350
1351 cachestat_collector(em);
collectors/ebpf.plugin/ebpf_cachestat.h
+3
@@ -33,6 +33,9 @@
33 #define NETDATA_SYSTEMD_CACHESTAT_HIT_FILE_CONTEXT "services.cachestat_hits"
34 #define NETDATA_SYSTEMD_CACHESTAT_MISS_FILES_CONTEXT "services.cachestat_misses"
35
36 +// ARAL Name
37 +#define NETDATA_EBPF_CACHESTAT_ARAL_NAME "ebpf_cachestat"
38 +
39 // variables
40 enum cachestat_counters {
41 NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU,
collectors/ebpf.plugin/ebpf_dcstat.c
+13 -2
@@ -5,7 +5,7 @@
5
6 // ----------------------------------------------------------------------------
7 // ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_dcstat_pid;
8 +ARAL *ebpf_aral_dcstat_pid = NULL;
9
10 static char *dcstat_counter_dimension_name[NETDATA_DCSTAT_IDX_END] = { "ratio", "reference", "slow", "miss" };
11 static netdata_syscall_stat_t dcstat_counter_aggregated_data[NETDATA_DCSTAT_IDX_END];
@@ -344,7 +344,7 @@ static void ebpf_dcstat_exit(void *ptr)
344 */
345 static inline void ebpf_dcstat_aral_init()
346 {
347 - ebpf_aral_dcstat_pid = ebpf_allocate_pid_aral("ebpf-dcstat", sizeof(netdata_publish_dcstat_t));
347 + ebpf_aral_dcstat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_DCSTAT_ARAL_NAME, sizeof(netdata_publish_dcstat_t));
348 }
349
350 /**
@@ -1053,6 +1053,11 @@ static void dcstat_collector(ebpf_module_t *em)
1053 if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED)
1054 ebpf_dcache_send_apps_data(apps_groups_root_target);
1055
1056 +#ifdef NETDATA_DEV_MODE
1057 + if (ebpf_aral_dcstat_pid)
1058 + ebpf_send_data_aral_chart(ebpf_aral_dcstat_pid, em);
1059 +#endif
1060 +
1061 if (cgroups)
1062 ebpf_dc_send_cgroup_data(update_every);
1063
@@ -1201,6 +1206,12 @@ void *ebpf_dcstat_thread(void *ptr)
1206 pthread_mutex_lock(&lock);
1207 ebpf_create_filesystem_charts(em->update_every);
1208 ebpf_update_stats(&plugin_statistics, em);
1209 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
1210 +#ifdef NETDATA_DEV_MODE
1211 + if (ebpf_aral_dcstat_pid)
1212 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_DCSTAT_ARAL_NAME, em);
1213 +#endif
1214 +
1215 pthread_mutex_unlock(&lock);
1216
1217 dcstat_collector(em);
collectors/ebpf.plugin/ebpf_dcstat.h
+3
@@ -28,6 +28,9 @@
28 #define NETDATA_SYSTEMD_DC_NOT_CACHE_CONTEXT "services.dc_not_cache"
29 #define NETDATA_SYSTEMD_DC_NOT_FOUND_CONTEXT "services.dc_not_found"
30
31 +// ARAL name
32 +#define NETDATA_EBPF_DCSTAT_ARAL_NAME "ebpf_dcstat"
33 +
34 enum directory_cache_indexes {
35 NETDATA_DCSTAT_IDX_RATIO,
36 NETDATA_DCSTAT_IDX_REFERENCE,
collectors/ebpf.plugin/ebpf_disk.c
+1
@@ -792,6 +792,7 @@ void *ebpf_disk_thread(void *ptr)
792
793 pthread_mutex_lock(&lock);
794 ebpf_update_stats(&plugin_statistics, em);
795 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, disk_maps);
796 pthread_mutex_unlock(&lock);
797
798 disk_collector(em);
collectors/ebpf.plugin/ebpf_fd.c
+13 -2
@@ -5,7 +5,7 @@
5
6 // ----------------------------------------------------------------------------
7 // ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_fd_pid;
8 +ARAL *ebpf_aral_fd_pid = NULL;
9
10 static char *fd_dimension_names[NETDATA_FD_SYSCALL_END] = { "open", "close" };
11 static char *fd_id_names[NETDATA_FD_SYSCALL_END] = { "do_sys_open", "__close_fd" };
@@ -411,7 +411,7 @@ static void ebpf_fd_exit(void *ptr)
411 */
412 static inline void ebpf_fd_aral_init()
413 {
414 - ebpf_aral_fd_pid = ebpf_allocate_pid_aral("ebpf-fd", sizeof(netdata_fd_stat_t));
414 + ebpf_aral_fd_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_FD_ARAL_NAME, sizeof(netdata_fd_stat_t));
415 }
416
417 /**
@@ -983,6 +983,11 @@ static void fd_collector(ebpf_module_t *em)
983 if (apps)
984 read_apps_table();
985
986 +#ifdef NETDATA_DEV_MODE
987 + if (ebpf_aral_fd_pid)
988 + ebpf_send_data_aral_chart(ebpf_aral_fd_pid, em);
989 +#endif
990 +
991 if (cgroups)
992 ebpf_update_fd_cgroup();
993
@@ -1193,6 +1198,12 @@ void *ebpf_fd_thread(void *ptr)
1198 pthread_mutex_lock(&lock);
1199 ebpf_create_fd_global_charts(em);
1200 ebpf_update_stats(&plugin_statistics, em);
1201 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
1202 +#ifdef NETDATA_DEV_MODE
1203 + if (ebpf_aral_fd_pid)
1204 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_FD_ARAL_NAME, em);
1205 +#endif
1206 +
1207 pthread_mutex_unlock(&lock);
1208
1209 fd_collector(em);
collectors/ebpf.plugin/ebpf_fd.h
+3
@@ -33,6 +33,9 @@
33 #define NETDATA_SYSTEMD_FD_CLOSE_CONTEXT "services.fd_close"
34 #define NETDATA_SYSTEMD_FD_CLOSE_ERR_CONTEXT "services.fd_close_error"
35
36 +// ARAL name
37 +#define NETDATA_EBPF_FD_ARAL_NAME "ebpf_fd"
38 +
39 typedef struct netdata_fd_stat {
40 uint32_t open_call; // Open syscalls (open and openat)
41 uint32_t close_call; // Close syscall (close)
collectors/ebpf.plugin/ebpf_filesystem.c
+3
@@ -182,6 +182,9 @@ int ebpf_filesystem_initialize_ebpf_data(ebpf_module_t *em)
182 return -1;
183 }
184 efp->flags |= NETDATA_FILESYSTEM_FLAG_HAS_PARTITION;
185 + pthread_mutex_lock(&lock);
186 + ebpf_update_kernel_memory(&plugin_statistics, &fs_maps[i], EBPF_ACTION_STAT_ADD);
187 + pthread_mutex_unlock(&lock);
188
189 // Nedeed for filesystems like btrfs
190 if ((efp->flags & NETDATA_FILESYSTEM_FILL_ADDRESS_TABLE) && (efp->addresses.function)) {
collectors/ebpf.plugin/ebpf_hardirq.c
+1
@@ -391,6 +391,7 @@ static void hardirq_collector(ebpf_module_t *em)
391 hardirq_create_charts(em->update_every);
392 hardirq_create_static_dims();
393 ebpf_update_stats(&plugin_statistics, em);
394 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
395 pthread_mutex_unlock(&lock);
396
397 // loop and read from published data until ebpf plugin is closed.
collectors/ebpf.plugin/ebpf_mdflush.c
+1
@@ -208,6 +208,7 @@ static void mdflush_collector(ebpf_module_t *em)
208 pthread_mutex_lock(&lock);
209 mdflush_create_charts(update_every);
210 ebpf_update_stats(&plugin_statistics, em);
211 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
212 pthread_mutex_unlock(&lock);
213
214 // loop and read from published data until ebpf plugin is closed.
collectors/ebpf.plugin/ebpf_mount.c
+1
@@ -442,6 +442,7 @@ void *ebpf_mount_thread(void *ptr)
442 pthread_mutex_lock(&lock);
443 ebpf_create_mount_charts(em->update_every);
444 ebpf_update_stats(&plugin_statistics, em);
445 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
446 pthread_mutex_unlock(&lock);
447
448 mount_collector(em);
collectors/ebpf.plugin/ebpf_oomkill.c
+1
@@ -392,6 +392,7 @@ void *ebpf_oomkill_thread(void *ptr)
392
393 pthread_mutex_lock(&lock);
394 ebpf_update_stats(&plugin_statistics, em);
395 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
396 pthread_mutex_unlock(&lock);
397
398 oomkill_collector(em);
collectors/ebpf.plugin/ebpf_process.c
+76
@@ -55,6 +55,8 @@ struct config process_config = { .first_section = NULL,
55
56 static char *threads_stat[NETDATA_EBPF_THREAD_STAT_END] = {"total", "running"};
57 static char *load_event_stat[NETDATA_EBPF_LOAD_STAT_END] = {"legacy", "co-re"};
58 +static char *memlock_stat = {"memory_locked"};
59 +static char *hash_table_stat = {"hash_table"};
60
61 /*****************************************************************
62 *
@@ -456,6 +458,56 @@ static inline void ebpf_create_statistic_load_chart(ebpf_module_t *em)
458 ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
459 }
460
461 +/**
462 + * Create chart for Kernel Memory
463 + *
464 + * Write to standard output current values for allocated memory.
465 + *
466 + * @param em a pointer to the structure with the default values.
467 + */
468 +static inline void ebpf_create_statistic_kernel_memory(ebpf_module_t *em)
469 +{
470 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
471 + NETDATA_EBPF_KERNEL_MEMORY,
472 + "Memory allocated for hash tables.",
473 + "bytes",
474 + NETDATA_EBPF_FAMILY,
475 + NETDATA_EBPF_CHART_TYPE_LINE,
476 + NULL,
477 + 140002,
478 + em->update_every,
479 + NETDATA_EBPF_MODULE_NAME_PROCESS);
480 +
481 + ebpf_write_global_dimension(memlock_stat,
482 + memlock_stat,
483 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
484 +}
485 +
486 +/**
487 + * Create chart Hash Table
488 + *
489 + * Write to standard output number of hash tables used with this software.
490 + *
491 + * @param em a pointer to the structure with the default values.
492 + */
493 +static inline void ebpf_create_statistic_hash_tables(ebpf_module_t *em)
494 +{
495 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
496 + NETDATA_EBPF_HASH_TABLES_LOADED,
497 + "Number of hash tables loaded.",
498 + "hash tables",
499 + NETDATA_EBPF_FAMILY,
500 + NETDATA_EBPF_CHART_TYPE_LINE,
501 + NULL,
502 + 140003,
503 + em->update_every,
504 + NETDATA_EBPF_MODULE_NAME_PROCESS);
505 +
506 + ebpf_write_global_dimension(hash_table_stat,
507 + hash_table_stat,
508 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
509 +}
510 +
511 /**
512 * Update Internal Metric variable
513 *
@@ -487,6 +539,10 @@ static void ebpf_create_statistic_charts(ebpf_module_t *em)
539 ebpf_create_statistic_thread_chart(em);
540
541 ebpf_create_statistic_load_chart(em);
542 +
543 + ebpf_create_statistic_kernel_memory(em);
544 +
545 + ebpf_create_statistic_hash_tables(em);
546 }
547
548 /**
@@ -1001,6 +1057,14 @@ void ebpf_send_statistic_data()
1057 write_chart_dimension(load_event_stat[NETDATA_EBPF_LOAD_STAT_LEGACY], (long long)plugin_statistics.legacy);
1058 write_chart_dimension(load_event_stat[NETDATA_EBPF_LOAD_STAT_CORE], (long long)plugin_statistics.core);
1059 write_end_chart();
1060 +
1061 + write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_KERNEL_MEMORY);
1062 + write_chart_dimension(memlock_stat, (long long)plugin_statistics.memlock_kern);
1063 + write_end_chart();
1064 +
1065 + write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_HASH_TABLES_LOADED);
1066 + write_chart_dimension(hash_table_stat, (long long)plugin_statistics.hash_tables);
1067 + write_end_chart();
1068 }
1069
1070 /**
@@ -1064,6 +1128,11 @@ static void process_collector(ebpf_module_t *em)
1128 ebpf_process_send_apps_data(apps_groups_root_target, em);
1129 }
1130
1131 +#ifdef NETDATA_DEV_MODE
1132 + if (ebpf_aral_process_stat)
1133 + ebpf_send_data_aral_chart(ebpf_aral_process_stat, em);
1134 +#endif
1135 +
1136 if (cgroups && shm_ebpf_cgroup.header) {
1137 ebpf_process_send_cgroup_data(em);
1138 }
@@ -1206,6 +1275,13 @@ void *ebpf_process_thread(void *ptr)
1275 }
1276
1277 ebpf_update_stats(&plugin_statistics, em);
1278 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
1279 +
1280 +#ifdef NETDATA_DEV_MODE
1281 + if (ebpf_aral_process_stat)
1282 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_PROC_ARAL_NAME, em);
1283 +#endif
1284 +
1285 ebpf_create_statistic_charts(em);
1286
1287 pthread_mutex_unlock(&lock);
collectors/ebpf.plugin/ebpf_shm.c
+13 -2
@@ -5,7 +5,7 @@
5
6 // ----------------------------------------------------------------------------
7 // ARAL vectors used to speed up processing
8 -ARAL *ebpf_aral_shm_pid;
8 +ARAL *ebpf_aral_shm_pid = NULL;
9
10 static char *shm_dimension_name[NETDATA_SHM_END] = { "get", "at", "dt", "ctl" };
11 static netdata_syscall_stat_t shm_aggregated_data[NETDATA_SHM_END];
@@ -336,7 +336,7 @@ static void ebpf_shm_exit(void *ptr)
336 */
337 static inline void ebpf_shm_aral_init()
338 {
339 - ebpf_aral_shm_pid = ebpf_allocate_pid_aral("ebpf-shm", sizeof(netdata_publish_shm_t));
339 + ebpf_aral_shm_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SHM_ARAL_NAME, sizeof(netdata_publish_shm_t));
340 }
341
342 /**
@@ -917,6 +917,11 @@ static void shm_collector(ebpf_module_t *em)
917 ebpf_shm_send_apps_data(apps_groups_root_target);
918 }
919
920 +#ifdef NETDATA_DEV_MODE
921 + if (ebpf_aral_shm_pid)
922 + ebpf_send_data_aral_chart(ebpf_aral_shm_pid, em);
923 +#endif
924 +
925 if (cgroups) {
926 ebpf_shm_send_cgroup_data(update_every);
927 }
@@ -1110,6 +1115,12 @@ void *ebpf_shm_thread(void *ptr)
1115 pthread_mutex_lock(&lock);
1116 ebpf_create_shm_charts(em->update_every);
1117 ebpf_update_stats(&plugin_statistics, em);
1118 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
1119 +#ifdef NETDATA_DEV_MODE
1120 + if (ebpf_aral_shm_pid)
1121 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_SHM_ARAL_NAME, em);
1122 +#endif
1123 +
1124 pthread_mutex_unlock(&lock);
1125
1126 shm_collector(em);
collectors/ebpf.plugin/ebpf_shm.h
+3
@@ -27,6 +27,9 @@
27 #define NETDATA_SYSTEMD_SHM_DT_CONTEXT "services.shmdt"
28 #define NETDATA_SYSTEMD_SHM_CTL_CONTEXT "services.shmctl"
29
30 +// ARAL name
31 +#define NETDATA_EBPF_SHM_ARAL_NAME "ebpf_shm"
32 +
33 typedef struct netdata_publish_shm {
34 uint64_t get;
35 uint64_t at;
collectors/ebpf.plugin/ebpf_socket.c
+13 -2
@@ -7,7 +7,7 @@
7
8 // ----------------------------------------------------------------------------
9 // ARAL vectors used to speed up processing
10 -ARAL *ebpf_aral_socket_pid;
10 +ARAL *ebpf_aral_socket_pid = NULL;
11
12 /*****************************************************************
13 *
@@ -446,7 +446,7 @@ static inline int ebpf_socket_load_and_attach(struct socket_bpf *obj, ebpf_modul
446 */
447 static inline void ebpf_socket_aral_init()
448 {
449 - ebpf_aral_socket_pid = ebpf_allocate_pid_aral("ebpf-socket", sizeof(ebpf_socket_publish_apps_t));
449 + ebpf_aral_socket_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SOCKET_ARAL_NAME, sizeof(ebpf_socket_publish_apps_t));
450 }
451
452 /**
@@ -2948,6 +2948,11 @@ static void socket_collector(ebpf_module_t *em)
2948 if (socket_apps_enabled & NETDATA_EBPF_APPS_FLAG_CHART_CREATED)
2949 ebpf_socket_send_apps_data(em, apps_groups_root_target);
2950
2951 +#ifdef NETDATA_DEV_MODE
2952 + if (ebpf_aral_socket_pid)
2953 + ebpf_send_data_aral_chart(ebpf_aral_socket_pid, em);
2954 +#endif
2955 +
2956 if (cgroups)
2957 ebpf_socket_send_cgroup_data(update_every);
2958
@@ -4009,6 +4014,12 @@ void *ebpf_socket_thread(void *ptr)
4014 ebpf_create_global_charts(em);
4015
4016 ebpf_update_stats(&plugin_statistics, em);
4017 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
4018 +
4019 +#ifdef NETDATA_DEV_MODE
4020 + if (ebpf_aral_socket_pid)
4021 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_SOCKET_ARAL_NAME, em);
4022 +#endif
4023
4024 pthread_mutex_unlock(&lock);
4025
collectors/ebpf.plugin/ebpf_socket.h
+3
@@ -160,6 +160,9 @@ typedef enum ebpf_socket_idx {
160 #define NETDATA_SERVICES_SOCKET_UDP_RECV_CONTEXT "services.net_udp_recv"
161 #define NETDATA_SERVICES_SOCKET_UDP_SEND_CONTEXT "services.net_udp_send"
162
163 +// ARAL name
164 +#define NETDATA_EBPF_SOCKET_ARAL_NAME "ebpf_socket"
165 +
166 typedef struct ebpf_socket_publish_apps {
167 // Data read
168 uint64_t bytes_sent; // Bytes sent
collectors/ebpf.plugin/ebpf_softirq.c
+1
@@ -164,6 +164,7 @@ static void softirq_collector(ebpf_module_t *em)
164 softirq_create_charts(em->update_every);
165 softirq_create_dims();
166 ebpf_update_stats(&plugin_statistics, em);
167 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
168 pthread_mutex_unlock(&lock);
169
170 // loop and read from published data until ebpf plugin is closed.
collectors/ebpf.plugin/ebpf_swap.c
+1
@@ -842,6 +842,7 @@ void *ebpf_swap_thread(void *ptr)
842 pthread_mutex_lock(&lock);
843 ebpf_create_swap_charts(em->update_every);
844 ebpf_update_stats(&plugin_statistics, em);
845 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
846 pthread_mutex_unlock(&lock);
847
848 swap_collector(em);
collectors/ebpf.plugin/ebpf_vfs.c
+13 -2
@@ -7,7 +7,7 @@
7
8 // ----------------------------------------------------------------------------
9 // ARAL vectors used to speed up processing
10 -ARAL *ebpf_aral_vfs_pid;
10 +ARAL *ebpf_aral_vfs_pid = NULL;
11
12 static char *vfs_dimension_names[NETDATA_KEY_PUBLISH_VFS_END] = { "delete", "read", "write",
13 "fsync", "open", "create" };
@@ -399,7 +399,7 @@ static inline int ebpf_vfs_load_and_attach(struct vfs_bpf *obj, ebpf_module_t *e
399 */
400 static inline void ebpf_vfs_aral_init()
401 {
402 - ebpf_aral_vfs_pid = ebpf_allocate_pid_aral("ebpf-vfs", sizeof(netdata_publish_vfs_t));
402 + ebpf_aral_vfs_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_VFS_ARAL_NAME, sizeof(netdata_publish_vfs_t));
403 }
404
405 /**
@@ -1528,6 +1528,11 @@ static void vfs_collector(ebpf_module_t *em)
1528 if (apps)
1529 ebpf_vfs_read_apps();
1530
1531 +#ifdef NETDATA_DEV_MODE
1532 + if (ebpf_aral_vfs_pid)
1533 + ebpf_send_data_aral_chart(ebpf_aral_vfs_pid, em);
1534 +#endif
1535 +
1536 if (cgroups)
1537 read_update_vfs_cgroup();
1538
@@ -1956,6 +1961,12 @@ void *ebpf_vfs_thread(void *ptr)
1961 pthread_mutex_lock(&lock);
1962 ebpf_create_global_charts(em);
1963 ebpf_update_stats(&plugin_statistics, em);
1964 + ebpf_update_kernel_memory_with_vector(&plugin_statistics, em->maps);
1965 +#ifdef NETDATA_DEV_MODE
1966 + if (ebpf_aral_vfs_pid)
1967 + ebpf_statistic_create_aral_chart(NETDATA_EBPF_VFS_ARAL_NAME, em);
1968 +#endif
1969 +
1970 pthread_mutex_unlock(&lock);
1971
1972 vfs_collector(em);
collectors/ebpf.plugin/ebpf_vfs.h
+3
@@ -69,6 +69,9 @@
69 #define NETDATA_SYSTEMD_VFS_FSYNC_CONTEXT "services.vfs_fsync"
70 #define NETDATA_SYSTEMD_VFS_FSYNC_ERROR_CONTEXT "services.vfs_fsync_error"
71
72 +// ARAL name
73 +#define NETDATA_EBPF_VFS_ARAL_NAME "ebpf_vfs"
74 +
75 typedef struct netdata_publish_vfs {
76 uint64_t pid_tgid;
77 uint32_t pid;
libnetdata/ebpf/ebpf.c
+85
@@ -454,6 +454,91 @@ void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em)
454 ebpf_stats_targets(report, em->targets);
455 }
456
457 +/**
458 + * Update Kernel memory with memory
459 + *
460 + * This algorithm is an adaptation of https://elixir.bootlin.com/linux/v6.1.14/source/tools/bpf/bpftool/common.c#L402
461 + * to get 'memlock' data and update report.
462 + *
463 + * @param report the output structure
464 + * @param map pointer to a map.
465 + * @param action What action will be done with this map.
466 + */
467 +void ebpf_update_kernel_memory(ebpf_plugin_stats_t *report, ebpf_local_maps_t *map, ebpf_stats_action_t action)
468 +{
469 + char filename[FILENAME_MAX+1];
470 + snprintfz(filename, FILENAME_MAX, "/proc/self/fdinfo/%d", map->map_fd);
471 + procfile *ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
472 + if(unlikely(!ff)) {
473 + error("Cannot open %s", filename);
474 + return;
475 + }
476 +
477 + ff = procfile_readall(ff);
478 + if(unlikely(!ff))
479 + return;
480 +
481 + unsigned long j, lines = procfile_lines(ff);
482 + char *memlock = { "memlock" };
483 + for (j = 0; j < lines ; j++) {
484 + char *cmp = procfile_lineword(ff, j,0);
485 + if (!strncmp(memlock, cmp, 7)) {
486 + uint64_t memsize = (uint64_t) str2l(procfile_lineword(ff, j,1));
487 + switch (action) {
488 + case EBPF_ACTION_STAT_ADD: {
489 + report->memlock_kern += memsize;
490 + report->hash_tables += 1;
491 +#ifdef NETDATA_DEV_MODE
492 + info("Hash table %u: %s (FD = %d) is consuming %lu bytes totalizing %lu bytes",
493 + report->hash_tables, map->name, map->map_fd, memsize, report->memlock_kern);
494 +#endif
495 + break;
496 + }
497 + case EBPF_ACTION_STAT_REMOVE: {
498 + report->memlock_kern -= memsize;
499 + report->hash_tables -= 1;
500 +#ifdef NETDATA_DEV_MODE
501 + info("Hash table %s (FD = %d) was removed releasing %lu bytes, now we have %u tables loaded totalizing %lu bytes.",
502 + map->name, map->map_fd, memsize, report->hash_tables, report->memlock_kern);
503 +#endif
504 + break;
505 + }
506 + default: {
507 + break;
508 + }
509 + }
510 + break;
511 + }
512 + }
513 +
514 + procfile_close(ff);
515 +}
516 +
517 +/**
518 + * Update Kernel memory with memory
519 + *
520 + * This algorithm is an adaptation of https://elixir.bootlin.com/linux/v6.1.14/source/tools/bpf/bpftool/common.c#L402
521 + * to get 'memlock' data and update report.
522 + *
523 + * @param report the output structure
524 + * @param map pointer to a map. Last map must fish with name = NULL
525 + */
526 +void ebpf_update_kernel_memory_with_vector(ebpf_plugin_stats_t *report, ebpf_local_maps_t *maps)
527 +{
528 + if (!maps)
529 + return;
530 +
531 + ebpf_local_maps_t *map;
532 + int i = 0;
533 + for (map = &maps[i]; maps[i].name; i++, map = &maps[i]) {
534 + int fd = map->map_fd;
535 + if (fd == ND_EBPF_MAP_FD_NOT_INITIALIZED)
536 + continue;
537 +
538 + ebpf_update_kernel_memory(report, map, EBPF_ACTION_STAT_ADD);
539 + }
540 +}
541 +
542 //----------------------------------------------------------------------------------------------------------------------
543
544 void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em)
libnetdata/ebpf/ebpf.h
+23
@@ -10,6 +10,7 @@
10 #include <linux/btf.h>
11 #endif
12 #include <stdlib.h> // Necessary for stdtoul
13 +#include "libnetdata/aral/aral.h"
14
15 #define NETDATA_DEBUGFS "/sys/kernel/debug/tracing/"
16 #define NETDATA_KALLSYMS "/proc/kallsyms"
@@ -238,14 +239,27 @@ typedef struct ebpf_plugin_stats {
239 uint32_t retprobes; // Number of kretprobes loaded
240 uint32_t tracepoints; // Number of tracepoints used
241 uint32_t trampolines; // Number of trampolines used
242 +
243 + uint64_t memlock_kern; // The same information reported by bpftool, but it is not accurated
244 + // https://lore.kernel.org/linux-mm/20230112155326.26902-5-laoar.shao@gmail.com/T/
245 + uint32_t hash_tables; // Number of hash tables used on the system.
246 } ebpf_plugin_stats_t;
247
248 +typedef enum ebpf_stats_action {
249 + EBPF_ACTION_STAT_ADD,
250 + EBPF_ACTION_STAT_REMOVE,
251 +} ebpf_stats_action_t;
252 +
253 typedef enum netdata_apps_integration_flags {
254 NETDATA_EBPF_APPS_FLAG_NO,
255 NETDATA_EBPF_APPS_FLAG_YES,
256 NETDATA_EBPF_APPS_FLAG_CHART_CREATED
257 } netdata_apps_integration_flags_t;
258
259 +#define NETDATA_EBPF_CHART_MEM_LENGTH 48
260 +#define NETDATA_EBPF_STAT_DIMENSION_MEMORY "memory"
261 +#define NETDATA_EBPF_STAT_DIMENSION_ARAL "aral"
262 +
263 typedef struct ebpf_module {
264 const char *thread_name;
265 const char *config_name;
@@ -271,6 +285,10 @@ typedef struct ebpf_module {
285 struct bpf_link **probe_links;
286 struct bpf_object *objects;
287 struct netdata_static_thread *thread;
288 +
289 + // charts
290 + char memory_usage[NETDATA_EBPF_CHART_MEM_LENGTH];
291 + char memory_allocations[NETDATA_EBPF_CHART_MEM_LENGTH];
292 } ebpf_module_t;
293
294 int ebpf_get_kernel_version();
@@ -368,4 +386,9 @@ struct btf *ebpf_load_btf_file(char *path, char *filename);
386 int ebpf_is_function_inside_btf(struct btf *file, char *function);
387 #endif
388
389 +void ebpf_update_kernel_memory_with_vector(ebpf_plugin_stats_t *report, ebpf_local_maps_t *maps);
390 +void ebpf_update_kernel_memory(ebpf_plugin_stats_t *report, ebpf_local_maps_t *map, ebpf_stats_action_t action);
391 +void ebpf_statistic_create_aral_chart(char *name, ebpf_module_t *em);
392 +void ebpf_send_data_aral_chart(ARAL *memory, ebpf_module_t *em);
393 +
394 #endif /* NETDATA_EBPF_H */
web/gui/dashboard_info.js
+17 -1
@@ -4921,7 +4921,23 @@ netdataDashboard.context = {
4921 info: 'Show number of threads loaded using legacy code (independent binary) or <code>CO-RE (Compile Once Run Everywhere)</code>.'
4922 },
4923
4924 - // ------------------------------------------------------------------------
4924 + 'netdata.ebpf_kernel_memory': {
4925 + info: 'Show amount of memory allocated inside kernel ring for hash tables. This chart shows the same information displayed by command `bpftool map show`.'
4926 + },
4927 +
4928 + 'netdata.ebpf_hash_tables_count': {
4929 + info: 'Show total number of hash tables loaded by eBPF.plugin`.'
4930 + },
4931 +
4932 + 'netdata.ebpf_aral_stat_size': {
4933 + info: 'Show total memory allocated for the specific ARAL.'
4934 + },
4935 +
4936 + 'netdata.ebpf_aral_stat_alloc': {
4937 + info: 'Show total memory of calls to get a specific region of memory inside an ARAL region.'
4938 + },
4939 +
4940 +// ------------------------------------------------------------------------
4941 // RETROSHARE
4942
4943 'retroshare.bandwidth': {