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': {