@cryptotaxi247 / netdata-1 / commits / b762b050a

Hash table charts (#15323)

thiagoftsm committed Jul 20, 2023 at 19:06 UTC b762b050afa8dc19726d5b0d395b452c0510b1eb
17 files changed +355 -172
collectors/ebpf.plugin/ebpf.c
+165 -2
@@ -60,7 +60,7 @@ ebpf_module_t ebpf_modules[] = {
60 NETDATA_V5_14,
61 .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
62 .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0 },
63 - { .thread_name = "socket", .config_name = "socket", .thread_description = NETDATA_EBPF_SOCKET_MODULE_DESC,
63 + { .thread_name = "socket", .config_name = "socket", .thread_description = NETDATA_EBPF_SOCKET_MODULE_DESC,
64 .enabled = 0, .start_routine = ebpf_socket_thread,
65 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
66 .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
@@ -1229,7 +1229,7 @@ void write_histogram_chart(char *family, char *name, const netdata_idx_t *hist,
1229 */
1230 int ebpf_statistic_create_aral_chart(char *name, ebpf_module_t *em)
1231 {
1232 - static int priority = 140100;
1232 + static int priority = NETATA_EBPF_ORDER_STAT_ARAL_BEGIN;
1233 char *mem = { NETDATA_EBPF_STAT_DIMENSION_MEMORY };
1234 char *aral = { NETDATA_EBPF_STAT_DIMENSION_ARAL };
1235
@@ -1325,6 +1325,49 @@ void ebpf_send_data_aral_chart(ARAL *memory, ebpf_module_t *em)
1325 write_end_chart();
1326 }
1327
1328 +/*****************************************************************
1329 + *
1330 + * FUNCTIONS TO READ GLOBAL HASH TABLES
1331 + *
1332 + *****************************************************************/
1333 +
1334 +/**
1335 + * Read Global Table Stats
1336 + *
1337 + * Read data from specified table (map_fd) using array allocated inside thread(values) and storing
1338 + * them in stats vector starting from the first position.
1339 + *
1340 + * For PID tables is recommended to use a function to parse the specific data.
1341 + *
1342 + * @param stats vector used to store data
1343 + * @param values helper to read data from hash tables.
1344 + * @param map_fd table that has data
1345 + * @param maps_per_core Is necessary to read data from all cores?
1346 + * @param begin initial value to query hash table
1347 + * @param end last value that will not be used.
1348 + */
1349 +void ebpf_read_global_table_stats(netdata_idx_t *stats,
1350 + netdata_idx_t *values,
1351 + int map_fd,
1352 + int maps_per_core,
1353 + uint32_t begin,
1354 + uint32_t end)
1355 +{
1356 + uint32_t idx, order;
1357 +
1358 + for (idx = begin, order = 0; idx < end; idx++, order++) {
1359 + if (!bpf_map_lookup_elem(map_fd, &idx, values)) {
1360 + int i;
1361 + int before = (maps_per_core) ? ebpf_nprocs: 1;
1362 + netdata_idx_t total = 0;
1363 + for (i = 0; i < before; i++)
1364 + total += values[i];
1365 +
1366 + stats[order] = total;
1367 + }
1368 + }
1369 +}
1370 +
1371 /*****************************************************************
1372 *
1373 * FUNCTIONS TO DEFINE OPTIONS
@@ -2453,6 +2496,47 @@ static char *memlock_stat = {"memory_locked"};
2496 static char *hash_table_stat = {"hash_table"};
2497 static char *hash_table_core[NETDATA_EBPF_LOAD_STAT_END] = {"per_core", "unique"};
2498
2499 +/**
2500 + * Send Hash Table PID data
2501 + *
2502 + * Send all information associated with a specific pid table.
2503 + *
2504 + * @param chart chart id
2505 + * @param idx index position in hash_table_stats
2506 + */
2507 +static inline void ebpf_send_hash_table_pid_data(char *chart, uint32_t idx)
2508 +{
2509 + int i;
2510 + write_begin_chart(NETDATA_MONITORING_FAMILY, chart);
2511 + for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
2512 + ebpf_module_t *wem = &ebpf_modules[i];
2513 + if (wem->apps_routine)
2514 + write_chart_dimension((char *)wem->thread_name,
2515 + (wem->enabled < NETDATA_THREAD_EBPF_STOPPING) ?
2516 + wem->hash_table_stats[idx]:
2517 + 0);
2518 + }
2519 + write_end_chart();
2520 +}
2521 +
2522 +/**
2523 + * Send Global Hash Table data
2524 + *
2525 + * Send all information associated with a specific pid table.
2526 + *
2527 + */
2528 +static inline void ebpf_send_global_hash_table_data()
2529 +{
2530 + int i;
2531 + write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_HASH_TABLES_GLOBAL_ELEMENTS);
2532 + for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
2533 + ebpf_module_t *wem = &ebpf_modules[i];
2534 + write_chart_dimension((char *)wem->thread_name,
2535 + (wem->enabled < NETDATA_THREAD_EBPF_STOPPING) ? NETDATA_CONTROLLER_END: 0);
2536 + }
2537 + write_end_chart();
2538 +}
2539 +
2540 /**
2541 * Send Statistic Data
2542 *
@@ -2500,6 +2584,11 @@ void ebpf_send_statistic_data()
2584 write_chart_dimension(hash_table_core[NETDATA_EBPF_THREAD_PER_CORE], (long long)plugin_statistics.hash_percpu);
2585 write_chart_dimension(hash_table_core[NETDATA_EBPF_THREAD_UNIQUE], (long long)plugin_statistics.hash_unique);
2586 write_end_chart();
2587 +
2588 + ebpf_send_global_hash_table_data();
2589 +
2590 + ebpf_send_hash_table_pid_data(NETDATA_EBPF_HASH_TABLES_INSERT_PID_ELEMENTS, NETDATA_EBPF_GLOBAL_TABLE_PID_TABLE_ADD);
2591 + ebpf_send_hash_table_pid_data(NETDATA_EBPF_HASH_TABLES_REMOVE_PID_ELEMENTS, NETDATA_EBPF_GLOBAL_TABLE_PID_TABLE_DEL);
2592 }
2593
2594 /**
@@ -2681,6 +2770,66 @@ static inline void ebpf_create_statistic_hash_per_core(int update_every)
2770 ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
2771 }
2772
2773 +/**
2774 + * Hash table global elements
2775 + *
2776 + * Write to standard output current values inside global tables.
2777 + *
2778 + * @param update_every time used to update charts
2779 + */
2780 +static void ebpf_create_statistic_hash_global_elements(int update_every)
2781 +{
2782 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
2783 + NETDATA_EBPF_HASH_TABLES_GLOBAL_ELEMENTS,
2784 + "Controllers inside global table",
2785 + "rows",
2786 + NETDATA_EBPF_FAMILY,
2787 + NETDATA_EBPF_CHART_TYPE_LINE,
2788 + NULL,
2789 + NETDATA_EBPF_ORDER_STAT_HASH_GLOBAL_TABLE_TOTAL,
2790 + update_every,
2791 + NETDATA_EBPF_MODULE_NAME_PROCESS);
2792 +
2793 + int i;
2794 + for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
2795 + ebpf_write_global_dimension((char *)ebpf_modules[i].thread_name,
2796 + (char *)ebpf_modules[i].thread_name,
2797 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
2798 + }
2799 +}
2800 +
2801 +/**
2802 + * Hash table global elements
2803 + *
2804 + * Write to standard output current values inside global tables.
2805 + *
2806 + * @param update_every time used to update charts
2807 + * @param id chart id
2808 + * @param title chart title
2809 + * @param order ordder chart will be shown on dashboard.
2810 + */
2811 +static void ebpf_create_statistic_hash_pid_table(int update_every, char *id, char *title, int order)
2812 +{
2813 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
2814 + id,
2815 + title,
2816 + "rows",
2817 + NETDATA_EBPF_FAMILY,
2818 + NETDATA_EBPF_CHART_TYPE_LINE,
2819 + NULL,
2820 + order,
2821 + update_every,
2822 + NETDATA_EBPF_MODULE_NAME_PROCESS);
2823 +
2824 + int i;
2825 + for (i = 0; i < EBPF_MODULE_FUNCTION_IDX; i++) {
2826 + ebpf_module_t *wem = &ebpf_modules[i];
2827 + if (wem->apps_routine)
2828 + ebpf_write_global_dimension((char *)wem->thread_name,
2829 + (char *)wem->thread_name,
2830 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX]);
2831 + }
2832 +}
2833
2834 /**
2835 * Create Statistics Charts
@@ -2718,6 +2867,20 @@ static void ebpf_create_statistic_charts(int update_every)
2867 ebpf_create_statistic_hash_tables(update_every);
2868
2869 ebpf_create_statistic_hash_per_core(update_every);
2870 +
2871 + ebpf_create_statistic_hash_global_elements(update_every);
2872 +
2873 + ebpf_create_statistic_hash_pid_table(update_every,
2874 + NETDATA_EBPF_HASH_TABLES_INSERT_PID_ELEMENTS,
2875 + "Elements inserted into PID table",
2876 + NETDATA_EBPF_ORDER_STAT_HASH_PID_TABLE_ADDED);
2877 +
2878 + ebpf_create_statistic_hash_pid_table(update_every,
2879 + NETDATA_EBPF_HASH_TABLES_REMOVE_PID_ELEMENTS,
2880 + "Elements removed from PID table",
2881 + NETDATA_EBPF_ORDER_STAT_HASH_PID_TABLE_REMOVED);
2882 +
2883 + fflush(stdout);
2884 }
2885
2886 /*****************************************************************
collectors/ebpf.plugin/ebpf.h
+6 -2
@@ -69,8 +69,6 @@ typedef struct netdata_syscall_stat {
69 struct netdata_syscall_stat *next; // Link list
70 } netdata_syscall_stat_t;
71
72 -typedef uint64_t netdata_idx_t;
73 -
72 typedef struct netdata_publish_syscall {
73 char *dimension;
74 char *name;
@@ -169,6 +167,9 @@ typedef struct ebpf_tracepoint {
167 #define NETDATA_EBPF_KERNEL_MEMORY "ebpf_kernel_memory"
168 #define NETDATA_EBPF_HASH_TABLES_LOADED "ebpf_hash_tables_count"
169 #define NETDATA_EBPF_HASH_TABLES_PER_CORE "ebpf_hash_tables_per_core"
170 +#define NETDATA_EBPF_HASH_TABLES_GLOBAL_ELEMENTS "ebpf_hash_tables_global_elements"
171 +#define NETDATA_EBPF_HASH_TABLES_INSERT_PID_ELEMENTS "ebpf_hash_tables_insert_pid_elements"
172 +#define NETDATA_EBPF_HASH_TABLES_REMOVE_PID_ELEMENTS "ebpf_hash_tables_remove_pid_elements"
173
174 // Log file
175 #define NETDATA_DEVELOPER_LOG_FILE "developer.log"
@@ -319,6 +320,9 @@ void ebpf_update_disabled_plugin_stats(ebpf_module_t *em);
320 ARAL *ebpf_allocate_pid_aral(char *name, size_t size);
321 void ebpf_unload_legacy_code(struct bpf_object *objects, struct bpf_link **probe_links);
322
323 +void ebpf_read_global_table_stats(netdata_idx_t *stats, netdata_idx_t *values, int map_fd,
324 + int maps_per_core, uint32_t begin, uint32_t end);
325 +
326 extern ebpf_filesystem_partitions_t localfs[];
327 extern ebpf_sync_syscalls_t local_syscalls[];
328 extern int ebpf_exit_plugin;
collectors/ebpf.plugin/ebpf_cachestat.c
+18 -18
@@ -854,26 +854,24 @@ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr)
854 *
855 * Read the table with number of calls for all functions
856 *
857 + * @param stats vector used to read data from control table.
858 * @param maps_per_core do I need to read all cores?
859 */
859 -static void ebpf_cachestat_read_global_table(int maps_per_core)
860 +static void ebpf_cachestat_read_global_tables(netdata_idx_t *stats, int maps_per_core)
861 {
861 - uint32_t idx;
862 - netdata_idx_t *val = cachestat_hash_values;
863 - netdata_idx_t *stored = cachestat_values;
864 - int fd = cachestat_maps[NETDATA_CACHESTAT_GLOBAL_STATS].map_fd;
865 -
866 - for (idx = NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU; idx < NETDATA_CACHESTAT_END; idx++) {
867 - if (!bpf_map_lookup_elem(fd, &idx, stored)) {
868 - int i;
869 - int end = (maps_per_core) ? ebpf_nprocs: 1;
870 - netdata_idx_t total = 0;
871 - for (i = 0; i < end; i++)
872 - total += stored[i];
873 -
874 - val[idx] = total;
875 - }
876 - }
862 + ebpf_read_global_table_stats(cachestat_hash_values,
863 + cachestat_values,
864 + cachestat_maps[NETDATA_CACHESTAT_GLOBAL_STATS].map_fd,
865 + maps_per_core,
866 + NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU,
867 + NETDATA_CACHESTAT_END);
868 +
869 + ebpf_read_global_table_stats(stats,
870 + cachestat_values,
871 + cachestat_maps[NETDATA_CACHESTAT_CTRL].map_fd,
872 + maps_per_core,
873 + NETDATA_CONTROLLER_PID_TABLE_ADD,
874 + NETDATA_CONTROLLER_END);
875 }
876
877 /**
@@ -1288,6 +1286,8 @@ static void cachestat_collector(ebpf_module_t *em)
1286 //This will be cancelled by its parent
1287 uint32_t running_time = 0;
1288 uint32_t lifetime = em->lifetime;
1289 + netdata_idx_t *stats = em->hash_table_stats;
1290 + memset(stats, 0, sizeof(em->hash_table_stats));
1291 while (!ebpf_exit_plugin && running_time < lifetime) {
1292 (void)heartbeat_next(&hb, USEC_PER_SEC);
1293
@@ -1296,7 +1296,7 @@ static void cachestat_collector(ebpf_module_t *em)
1296
1297 counter = 0;
1298 netdata_apps_integration_flags_t apps = em->apps_charts;
1299 - ebpf_cachestat_read_global_table(maps_per_core);
1299 + ebpf_cachestat_read_global_tables(stats, maps_per_core);
1300 pthread_mutex_lock(&collect_data_mutex);
1301 if (apps)
1302 ebpf_read_cachestat_apps_table(maps_per_core);
collectors/ebpf.plugin/ebpf_dcstat.c
+18 -18
@@ -690,26 +690,24 @@ static void ebpf_update_dc_cgroup(int maps_per_core)
690 *
691 * Read the table with number of calls for all functions
692 *
693 + * @param stats vector used to read data from control table.
694 * @param maps_per_core do I need to read all cores?
695 */
695 -static void ebpf_dc_read_global_table(int maps_per_core)
696 +static void ebpf_dc_read_global_tables(netdata_idx_t *stats, int maps_per_core)
697 {
697 - uint32_t idx;
698 - netdata_idx_t *val = dcstat_hash_values;
699 - netdata_idx_t *stored = dcstat_values;
700 - int fd = dcstat_maps[NETDATA_DCSTAT_GLOBAL_STATS].map_fd;
701 -
702 - for (idx = NETDATA_KEY_DC_REFERENCE; idx < NETDATA_DIRECTORY_CACHE_END; idx++) {
703 - if (!bpf_map_lookup_elem(fd, &idx, stored)) {
704 - int i;
705 - int end = (maps_per_core) ? ebpf_nprocs: 1;
706 - netdata_idx_t total = 0;
707 - for (i = 0; i < end; i++)
708 - total += stored[i];
709 -
710 - val[idx] = total;
711 - }
712 - }
698 + ebpf_read_global_table_stats(dcstat_hash_values,
699 + dcstat_values,
700 + dcstat_maps[NETDATA_DCSTAT_GLOBAL_STATS].map_fd,
701 + maps_per_core,
702 + NETDATA_KEY_DC_REFERENCE,
703 + NETDATA_DIRECTORY_CACHE_END);
704 +
705 + ebpf_read_global_table_stats(stats,
706 + dcstat_values,
707 + dcstat_maps[NETDATA_DCSTAT_CTRL].map_fd,
708 + maps_per_core,
709 + NETDATA_CONTROLLER_PID_TABLE_ADD,
710 + NETDATA_CONTROLLER_END);
711 }
712
713 /**
@@ -1169,6 +1167,8 @@ static void dcstat_collector(ebpf_module_t *em)
1167 int maps_per_core = em->maps_per_core;
1168 uint32_t running_time = 0;
1169 uint32_t lifetime = em->lifetime;
1170 + netdata_idx_t *stats = em->hash_table_stats;
1171 + memset(stats, 0, sizeof(em->hash_table_stats));
1172 while (!ebpf_exit_plugin && running_time < lifetime) {
1173 (void)heartbeat_next(&hb, USEC_PER_SEC);
1174
@@ -1177,7 +1177,7 @@ static void dcstat_collector(ebpf_module_t *em)
1177
1178 counter = 0;
1179 netdata_apps_integration_flags_t apps = em->apps_charts;
1180 - ebpf_dc_read_global_table(maps_per_core);
1180 + ebpf_dc_read_global_tables(stats, maps_per_core);
1181 pthread_mutex_lock(&collect_data_mutex);
1182 if (apps)
1183 read_dc_apps_table(maps_per_core);
collectors/ebpf.plugin/ebpf_fd.c
+19 -19
@@ -360,7 +360,7 @@ static inline int ebpf_fd_load_and_attach(struct fd_bpf *obj, ebpf_module_t *em)
360 if (!ret) {
361 ebpf_fd_set_hash_tables(obj);
362
363 - ebpf_update_controller(fd_maps[NETDATA_CACHESTAT_CTRL].map_fd, em);
363 + ebpf_update_controller(fd_maps[NETDATA_FD_CONTROLLER].map_fd, em);
364 }
365
366 return ret;
@@ -624,26 +624,24 @@ static void ebpf_fd_send_data(ebpf_module_t *em)
624 *
625 * Read the table with number of calls for all functions
626 *
627 + * @param stats vector used to read data from control table.
628 * @param maps_per_core do I need to read all cores?
629 */
629 -static void ebpf_fd_read_global_table(int maps_per_core)
630 +static void ebpf_fd_read_global_tables(netdata_idx_t *stats, int maps_per_core)
631 {
631 - uint32_t idx;
632 - netdata_idx_t *val = fd_hash_values;
633 - netdata_idx_t *stored = fd_values;
634 - int fd = fd_maps[NETDATA_FD_GLOBAL_STATS].map_fd;
635 -
636 - for (idx = NETDATA_KEY_CALLS_DO_SYS_OPEN; idx < NETDATA_FD_COUNTER; idx++) {
637 - if (!bpf_map_lookup_elem(fd, &idx, stored)) {
638 - int i;
639 - int end = (maps_per_core) ? ebpf_nprocs: 1;
640 - netdata_idx_t total = 0;
641 - for (i = 0; i < end; i++)
642 - total += stored[i];
643 -
644 - val[idx] = total;
645 - }
646 - }
632 + ebpf_read_global_table_stats(fd_hash_values,
633 + fd_values,
634 + fd_maps[NETDATA_FD_GLOBAL_STATS].map_fd,
635 + maps_per_core,
636 + NETDATA_KEY_CALLS_DO_SYS_OPEN,
637 + NETDATA_FD_COUNTER);
638 +
639 + ebpf_read_global_table_stats(stats,
640 + fd_values,
641 + fd_maps[NETDATA_FD_CONTROLLER].map_fd,
642 + maps_per_core,
643 + NETDATA_CONTROLLER_PID_TABLE_ADD,
644 + NETDATA_CONTROLLER_END);
645 }
646
647 /**
@@ -1136,6 +1134,8 @@ static void fd_collector(ebpf_module_t *em)
1134 int maps_per_core = em->maps_per_core;
1135 uint32_t running_time = 0;
1136 uint32_t lifetime = em->lifetime;
1137 + netdata_idx_t *stats = em->hash_table_stats;
1138 + memset(stats, 0, sizeof(em->hash_table_stats));
1139 while (!ebpf_exit_plugin && running_time < lifetime) {
1140 (void)heartbeat_next(&hb, USEC_PER_SEC);
1141
@@ -1144,7 +1144,7 @@ static void fd_collector(ebpf_module_t *em)
1144
1145 counter = 0;
1146 netdata_apps_integration_flags_t apps = em->apps_charts;
1147 - ebpf_fd_read_global_table(maps_per_core);
1147 + ebpf_fd_read_global_tables(stats, maps_per_core);
1148 pthread_mutex_lock(&collect_data_mutex);
1149 if (apps)
1150 read_fd_apps_table(maps_per_core);
collectors/ebpf.plugin/ebpf_oomkill.c
+4
@@ -419,6 +419,7 @@ static void oomkill_collector(ebpf_module_t *em)
419 int counter = update_every - 1;
420 uint32_t running_time = 0;
421 uint32_t lifetime = em->lifetime;
422 + netdata_idx_t *stats = em->hash_table_stats;
423 while (!ebpf_exit_plugin && running_time < lifetime) {
424 (void)heartbeat_next(&hb, USEC_PER_SEC);
425 if (ebpf_exit_plugin || ++counter != update_every)
@@ -432,6 +433,9 @@ static void oomkill_collector(ebpf_module_t *em)
433 continue;
434 }
435
436 + stats[NETDATA_CONTROLLER_PID_TABLE_ADD] += (uint64_t) count;
437 + stats[NETDATA_CONTROLLER_PID_TABLE_DEL] += (uint64_t) count;
438 +
439 pthread_mutex_lock(&collect_data_mutex);
440 pthread_mutex_lock(&lock);
441 if (cgroups) {
collectors/ebpf.plugin/ebpf_process.c
+17 -20
@@ -267,26 +267,22 @@ void ebpf_process_send_apps_data(struct ebpf_target *root, ebpf_module_t *em)
267 *
268 * @param maps_per_core do I need to read all cores?
269 */
270 -static void ebpf_read_process_hash_global_tables(int maps_per_core)
270 +static void ebpf_read_process_hash_global_tables(netdata_idx_t *stats, int maps_per_core)
271 {
272 - uint64_t idx;
272 netdata_idx_t res[NETDATA_KEY_END_VECTOR];
274 -
275 - netdata_idx_t *val = process_hash_values;
276 - int fd = process_maps[NETDATA_PROCESS_GLOBAL_TABLE].map_fd;
277 - for (idx = 0; idx < NETDATA_KEY_END_VECTOR; idx++) {
278 - if (!bpf_map_lookup_elem(fd, &idx, val)) {
279 - uint64_t total = 0;
280 - int i;
281 - int end = (maps_per_core) ? ebpf_nprocs : 1;
282 - for (i = 0; i < end; i++)
283 - total += val[i];
284 -
285 - res[idx] = total;
286 - } else {
287 - res[idx] = 0;
288 - }
289 - }
273 + ebpf_read_global_table_stats(res,
274 + process_hash_values,
275 + process_maps[NETDATA_PROCESS_GLOBAL_TABLE].map_fd,
276 + maps_per_core,
277 + 0,
278 + NETDATA_KEY_END_VECTOR);
279 +
280 + ebpf_read_global_table_stats(stats,
281 + process_hash_values,
282 + process_maps[NETDATA_PROCESS_CTRL_TABLE].map_fd,
283 + maps_per_core,
284 + NETDATA_CONTROLLER_PID_TABLE_ADD,
285 + NETDATA_CONTROLLER_END);
286
287 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_EXIT].call = res[NETDATA_KEY_CALLS_DO_EXIT];
288 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK].call = res[NETDATA_KEY_CALLS_RELEASE_TASK];
@@ -747,7 +743,6 @@ static void ebpf_process_exit(void *ptr)
743 ebpf_statistic_obsolete_aral_chart(em, process_disable_priority);
744 #endif
745
750 -
746 fflush(stdout);
747 pthread_mutex_unlock(&lock);
748 }
@@ -1121,6 +1116,8 @@ static void process_collector(ebpf_module_t *em)
1116 int maps_per_core = em->maps_per_core;
1117 uint32_t running_time = 0;
1118 uint32_t lifetime = em->lifetime;
1119 + netdata_idx_t *stats = em->hash_table_stats;
1120 + memset(stats, 0, sizeof(em->hash_table_stats));
1121 while (!ebpf_exit_plugin && running_time < lifetime) {
1122 usec_t dt = heartbeat_next(&hb, USEC_PER_SEC);
1123 (void)dt;
@@ -1130,7 +1127,7 @@ static void process_collector(ebpf_module_t *em)
1127 if (++counter == update_every) {
1128 counter = 0;
1129
1133 - ebpf_read_process_hash_global_tables(maps_per_core);
1130 + ebpf_read_process_hash_global_tables(stats, maps_per_core);
1131
1132 netdata_apps_integration_flags_t apps_enabled = em->apps_charts;
1133 pthread_mutex_lock(&collect_data_mutex);
collectors/ebpf.plugin/ebpf_process.h
+5 -1
@@ -48,7 +48,11 @@ enum netdata_ebpf_stats_order {
48 NETDATA_EBPF_ORDER_STAT_LOAD_METHOD,
49 NETDATA_EBPF_ORDER_STAT_KERNEL_MEMORY,
50 NETDATA_EBPF_ORDER_STAT_HASH_TABLES,
51 - NETDATA_EBPF_ORDER_STAT_HASH_CORE
51 + NETDATA_EBPF_ORDER_STAT_HASH_CORE,
52 + NETDATA_EBPF_ORDER_STAT_HASH_GLOBAL_TABLE_TOTAL,
53 + NETDATA_EBPF_ORDER_STAT_HASH_PID_TABLE_ADDED,
54 + NETDATA_EBPF_ORDER_STAT_HASH_PID_TABLE_REMOVED,
55 + NETATA_EBPF_ORDER_STAT_ARAL_BEGIN
56 };
57
58 enum netdata_ebpf_load_mode_stats{
collectors/ebpf.plugin/ebpf_shm.c
+18 -22
@@ -646,30 +646,24 @@ static void shm_send_global()
646 *
647 * Read the table with number of calls for all functions
648 *
649 + * @param stats vector used to read data from control table.
650 * @param maps_per_core do I need to read all cores?
651 */
651 -static void ebpf_shm_read_global_table(int maps_per_core)
652 +static void ebpf_shm_read_global_table(netdata_idx_t *stats, int maps_per_core)
653 {
653 - netdata_idx_t *stored = shm_values;
654 - netdata_idx_t *val = shm_hash_values;
655 - int fd = shm_maps[NETDATA_SHM_GLOBAL_TABLE].map_fd;
656 - size_t length = sizeof(netdata_idx_t);
657 - if (maps_per_core)
658 - length *= ebpf_nprocs;
659 -
660 - uint32_t i, end = NETDATA_SHM_END;
661 - for (i = NETDATA_KEY_SHMGET_CALL; i < end; i++) {
662 - if (!bpf_map_lookup_elem(fd, &i, stored)) {
663 - int j;
664 - int last = (maps_per_core) ? ebpf_nprocs : 1;
665 - netdata_idx_t total = 0;
666 - for (j = 0; j < last; j++)
667 - total += stored[j];
668 -
669 - val[i] = total;
670 - memset(stored, 0 , length);
671 - }
672 - }
654 + ebpf_read_global_table_stats(shm_hash_values,
655 + shm_values,
656 + shm_maps[NETDATA_SHM_GLOBAL_TABLE].map_fd,
657 + maps_per_core,
658 + NETDATA_KEY_SHMGET_CALL,
659 + NETDATA_SHM_END);
660 +
661 + ebpf_read_global_table_stats(stats,
662 + shm_values,
663 + shm_maps[NETDATA_SHM_CONTROLLER].map_fd,
664 + maps_per_core,
665 + NETDATA_CONTROLLER_PID_TABLE_ADD,
666 + NETDATA_CONTROLLER_END);
667 }
668
669 /**
@@ -1039,6 +1033,8 @@ static void shm_collector(ebpf_module_t *em)
1033 int maps_per_core = em->maps_per_core;
1034 uint32_t running_time = 0;
1035 uint32_t lifetime = em->lifetime;
1036 + netdata_idx_t *stats = em->hash_table_stats;
1037 + memset(stats, 0, sizeof(em->hash_table_stats));
1038 while (!ebpf_exit_plugin && running_time < lifetime) {
1039 (void)heartbeat_next(&hb, USEC_PER_SEC);
1040 if (ebpf_exit_plugin || ++counter != update_every)
@@ -1046,7 +1042,7 @@ static void shm_collector(ebpf_module_t *em)
1042
1043 counter = 0;
1044 netdata_apps_integration_flags_t apps = em->apps_charts;
1049 - ebpf_shm_read_global_table(maps_per_core);
1045 + ebpf_shm_read_global_table(stats, maps_per_core);
1046 pthread_mutex_lock(&collect_data_mutex);
1047 if (apps) {
1048 read_shm_apps_table(maps_per_core);
collectors/ebpf.plugin/ebpf_socket.c
+18 -24
@@ -2205,33 +2205,25 @@ void *ebpf_socket_read_hash(void *ptr)
2205 /**
2206 * Read the hash table and store data to allocated vectors.
2207 *
2208 + * @param stats vector used to read data from control table.
2209 * @param maps_per_core do I need to read all cores?
2210 */
2210 -static void read_hash_global_tables(int maps_per_core)
2211 +static void ebpf_socket_read_hash_global_tables(netdata_idx_t *stats, int maps_per_core)
2212 {
2212 - uint64_t idx;
2213 netdata_idx_t res[NETDATA_SOCKET_COUNTER];
2214 -
2215 - netdata_idx_t *val = socket_hash_values;
2216 - size_t length = sizeof(netdata_idx_t);
2217 - if (maps_per_core)
2218 - length *= ebpf_nprocs;
2219 -
2220 - int fd = socket_maps[NETDATA_SOCKET_GLOBAL].map_fd;
2221 - for (idx = 0; idx < NETDATA_SOCKET_COUNTER; idx++) {
2222 - if (!bpf_map_lookup_elem(fd, &idx, val)) {
2223 - uint64_t total = 0;
2224 - int i;
2225 - int end = (maps_per_core) ? ebpf_nprocs : 1;
2226 - for (i = 0; i < end; i++)
2227 - total += val[i];
2228 -
2229 - res[idx] = total;
2230 - memset(socket_hash_values, 0, length);
2231 - } else {
2232 - res[idx] = 0;
2233 - }
2234 - }
2214 + ebpf_read_global_table_stats(res,
2215 + socket_hash_values,
2216 + socket_maps[NETDATA_SOCKET_GLOBAL].map_fd,
2217 + maps_per_core,
2218 + NETDATA_KEY_CALLS_TCP_SENDMSG,
2219 + NETDATA_SOCKET_COUNTER);
2220 +
2221 + ebpf_read_global_table_stats(stats,
2222 + socket_hash_values,
2223 + socket_maps[NETDATA_SOCKET_TABLE_CTRL].map_fd,
2224 + maps_per_core,
2225 + NETDATA_CONTROLLER_PID_TABLE_ADD,
2226 + NETDATA_CONTROLLER_END);
2227
2228 socket_aggregated_data[NETDATA_IDX_TCP_SENDMSG].call = res[NETDATA_KEY_CALLS_TCP_SENDMSG];
2229 socket_aggregated_data[NETDATA_IDX_TCP_CLEANUP_RBUF].call = res[NETDATA_KEY_CALLS_TCP_CLEANUP_RBUF];
@@ -2930,6 +2922,8 @@ static void socket_collector(ebpf_module_t *em)
2922 int counter = update_every - 1;
2923 uint32_t running_time = 0;
2924 uint32_t lifetime = em->lifetime;
2925 + netdata_idx_t *stats = em->hash_table_stats;
2926 + memset(stats, 0, sizeof(em->hash_table_stats));
2927 while (!ebpf_exit_plugin && running_time < lifetime) {
2928 (void)heartbeat_next(&hb, USEC_PER_SEC);
2929 if (ebpf_exit_plugin || ++counter != update_every)
@@ -2939,7 +2933,7 @@ static void socket_collector(ebpf_module_t *em)
2933 netdata_apps_integration_flags_t socket_apps_enabled = em->apps_charts;
2934 if (socket_global_enabled) {
2935 read_listen_table();
2942 - read_hash_global_tables(maps_per_core);
2936 + ebpf_socket_read_hash_global_tables(stats, maps_per_core);
2937 }
2938
2939 pthread_mutex_lock(&collect_data_mutex);
collectors/ebpf.plugin/ebpf_swap.c
+19 -19
@@ -519,26 +519,24 @@ static void swap_send_global()
519 *
520 * Read the table with number of calls to all functions
521 *
522 + * @param stats vector used to read data from control table.
523 * @param maps_per_core do I need to read all cores?
524 */
524 -static void ebpf_swap_read_global_table(int maps_per_core)
525 -{
526 - netdata_idx_t *stored = swap_values;
527 - netdata_idx_t *val = swap_hash_values;
528 - int fd = swap_maps[NETDATA_SWAP_GLOBAL_TABLE].map_fd;
529 -
530 - uint32_t i, end = NETDATA_SWAP_END;
531 - for (i = NETDATA_KEY_SWAP_READPAGE_CALL; i < end; i++) {
532 - if (!bpf_map_lookup_elem(fd, &i, stored)) {
533 - int j;
534 - int last = (maps_per_core) ? ebpf_nprocs : 1;
535 - netdata_idx_t total = 0;
536 - for (j = 0; j < last; j++)
537 - total += stored[j];
538 -
539 - val[i] = total;
540 - }
541 - }
525 +static void ebpf_swap_read_global_table(netdata_idx_t *stats, int maps_per_core)
526 +{
527 + ebpf_read_global_table_stats(swap_hash_values,
528 + swap_values,
529 + swap_maps[NETDATA_SWAP_GLOBAL_TABLE].map_fd,
530 + maps_per_core,
531 + NETDATA_KEY_SWAP_READPAGE_CALL,
532 + NETDATA_SWAP_END);
533 +
534 + ebpf_read_global_table_stats(stats,
535 + swap_values,
536 + swap_maps[NETDATA_SWAP_CONTROLLER].map_fd,
537 + maps_per_core,
538 + NETDATA_CONTROLLER_PID_TABLE_ADD,
539 + NETDATA_CONTROLLER_END);
540 }
541
542 /**
@@ -804,6 +802,8 @@ static void swap_collector(ebpf_module_t *em)
802 int maps_per_core = em->maps_per_core;
803 uint32_t running_time = 0;
804 uint32_t lifetime = em->lifetime;
805 + netdata_idx_t *stats = em->hash_table_stats;
806 + memset(stats, 0, sizeof(em->hash_table_stats));
807 while (!ebpf_exit_plugin && running_time < lifetime) {
808 (void)heartbeat_next(&hb, USEC_PER_SEC);
809 if (ebpf_exit_plugin || ++counter != update_every)
@@ -811,7 +811,7 @@ static void swap_collector(ebpf_module_t *em)
811
812 counter = 0;
813 netdata_apps_integration_flags_t apps = em->apps_charts;
814 - ebpf_swap_read_global_table(maps_per_core);
814 + ebpf_swap_read_global_table(stats, maps_per_core);
815 pthread_mutex_lock(&collect_data_mutex);
816 if (apps)
817 read_swap_apps_table(maps_per_core);
collectors/ebpf.plugin/ebpf_vfs.c
+18 -21
@@ -964,30 +964,25 @@ static void ebpf_vfs_send_data(ebpf_module_t *em)
964 /**
965 * Read the hash table and store data to allocated vectors.
966 *
967 + * @param stats vector used to read data from control table.
968 * @param maps_per_core do I need to read all cores?
969 */
969 -static void ebpf_vfs_read_global_table(int maps_per_core)
970 +static void ebpf_vfs_read_global_table(netdata_idx_t *stats, int maps_per_core)
971 {
971 - uint64_t idx;
972 netdata_idx_t res[NETDATA_VFS_COUNTER];
973 -
974 - netdata_idx_t *val = vfs_hash_values;
975 - size_t length = sizeof(netdata_idx_t);
976 - if (maps_per_core)
977 - length *= ebpf_nprocs;
978 -
979 - int fd = vfs_maps[NETDATA_VFS_ALL].map_fd;
980 - for (idx = 0; idx < NETDATA_VFS_COUNTER; idx++) {
981 - uint64_t total = 0;
982 - if (!bpf_map_lookup_elem(fd, &idx, val)) {
983 - int i;
984 - int end = (maps_per_core) ? ebpf_nprocs : 1;
985 - for (i = 0; i < end; i++)
986 - total += val[i];
987 - }
988 - res[idx] = total;
989 - memset(val, 0, length);
990 - }
973 + ebpf_read_global_table_stats(res,
974 + vfs_hash_values,
975 + vfs_maps[NETDATA_VFS_ALL].map_fd,
976 + maps_per_core,
977 + NETDATA_KEY_CALLS_VFS_WRITE,
978 + NETDATA_VFS_COUNTER);
979 +
980 + ebpf_read_global_table_stats(stats,
981 + vfs_hash_values,
982 + vfs_maps[NETDATA_VFS_CTRL].map_fd,
983 + maps_per_core,
984 + NETDATA_CONTROLLER_PID_TABLE_ADD,
985 + NETDATA_CONTROLLER_END);
986
987 vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_UNLINK].ncall = res[NETDATA_KEY_CALLS_VFS_UNLINK];
988 vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ].ncall = res[NETDATA_KEY_CALLS_VFS_READ] +
@@ -1963,6 +1958,8 @@ static void vfs_collector(ebpf_module_t *em)
1958 int maps_per_core = em->maps_per_core;
1959 uint32_t running_time = 0;
1960 uint32_t lifetime = em->lifetime;
1961 + netdata_idx_t *stats = em->hash_table_stats;
1962 + memset(stats, 0, sizeof(em->hash_table_stats));
1963 while (!ebpf_exit_plugin && running_time < lifetime) {
1964 (void)heartbeat_next(&hb, USEC_PER_SEC);
1965 if (ebpf_exit_plugin || ++counter != update_every)
@@ -1970,7 +1967,7 @@ static void vfs_collector(ebpf_module_t *em)
1967
1968 counter = 0;
1969 netdata_apps_integration_flags_t apps = em->apps_charts;
1973 - ebpf_vfs_read_global_table(maps_per_core);
1970 + ebpf_vfs_read_global_table(stats, maps_per_core);
1971 pthread_mutex_lock(&collect_data_mutex);
1972 if (apps)
1973 ebpf_vfs_read_apps(maps_per_core);
libnetdata/ebpf/ebpf.h
+24
@@ -181,6 +181,17 @@ enum netdata_controller {
181 NETDATA_CONTROLLER_APPS_ENABLED,
182 NETDATA_CONTROLLER_APPS_LEVEL,
183
184 + // These index show the number of elements
185 + // stored inside hash tables.
186 + //
187 + // We have indexes to count increase and
188 + // decrease events, because __sync_fetch_and_sub
189 + // generates compilation errors.
190 + NETDATA_CONTROLLER_PID_TABLE_ADD,
191 + NETDATA_CONTROLLER_PID_TABLE_DEL,
192 + NETDATA_CONTROLLER_TEMP_TABLE_ADD,
193 + NETDATA_CONTROLLER_TEMP_TABLE_DEL,
194 +
195 NETDATA_CONTROLLER_END
196 };
197
@@ -278,6 +289,17 @@ enum ebpf_threads_status {
289 NETDATA_THREAD_EBPF_NOT_RUNNING // thread was never started
290 };
291
292 +enum ebpf_global_table_values {
293 + NETDATA_EBPF_GLOBAL_TABLE_PID_TABLE_ADD, // Count elements added inside PID table
294 + NETDATA_EBPF_GLOBAL_TABLE_PID_TABLE_DEL, // Count elements removed from PID table
295 + NETDATA_EBPF_GLOBAL_TABLE_TEMP_TABLE_ADD, // Count elements added inside TEMP table
296 + NETDATA_EBPF_GLOBAL_TABLE_TEMP_TABLE_DEL, // Count elements removed from TEMP table
297 +
298 + NETDATA_EBPF_GLOBAL_TABLE_STATUS_END
299 +};
300 +
301 +typedef uint64_t netdata_idx_t;
302 +
303 typedef struct ebpf_module {
304 const char *thread_name;
305 const char *config_name;
@@ -313,6 +335,8 @@ typedef struct ebpf_module {
335 // period to run
336 uint32_t running_time; // internal usage, this is used to reset a value when a new request happens.
337 uint32_t lifetime;
338 +
339 + netdata_idx_t hash_table_stats[NETDATA_EBPF_GLOBAL_TABLE_STATUS_END];
340 } ebpf_module_t;
341
342 #define EBPF_DEFAULT_LIFETIME 300
packaging/ebpf-co-re.checksums
+1 -1
@@ -1 +1 @@
1 -2bcbe98689efe6ee364cb3e9161ef549198d7f181845add923c6561bc8fb74d1 netdata-ebpf-co-re-glibc-v1.2.0.tar.xz
1 +2abbbaf30a73e1ed365d42324a5128470568b008528c3ff8cd98d5eb86152f03 netdata-ebpf-co-re-glibc-v1.2.1.tar.xz
packaging/ebpf-co-re.version
+1 -1
@@ -1 +1 @@
1 -v1.2.0
1 +v1.2.1
packaging/ebpf.checksums
+3 -3
@@ -1,3 +1,3 @@
1 -a7386ffca8cbe9aa24c01b0b97b2e3553c11d696752037551277f9b1f5feb100 ./netdata-kernel-collector-glibc-v1.2.0.tar.xz
2 -2b37ce6129dc61fd79e5519c150196099d363b4e57dafc55b210f64f9b40a3ec ./netdata-kernel-collector-musl-v1.2.0.tar.xz
3 -ad22f11cb545557c09955f3728ba76d9734345c0ab84927086bb0e99a9f88f80 ./netdata-kernel-collector-static-v1.2.0.tar.xz
1 +cb0cd6ef4bdb8a39c42b152d328d4822217c59e1d616d3003bc67bc53a058275 ./netdata-kernel-collector-glibc-v1.2.1.tar.xz
2 +0633ff39e8654a21ab664a289f58daca5792cfaf2ed62dcaacf7cd267eeedd40 ./netdata-kernel-collector-musl-v1.2.1.tar.xz
3 +6ce60c5ac8f45cc6a01b7ac9ea150728963d0aca1ee6dfd568b0f8b2ba67b88b ./netdata-kernel-collector-static-v1.2.1.tar.xz
packaging/ebpf.version
+1 -1
@@ -1 +1 @@
1 -v1.2.0
1 +v1.2.1