@cryptotaxi247 / netdata-1 / commits / 589eb8d06

eBPF (reduce CPU and memory usage) (#18365)

thiagoftsm committed Aug 19, 2024 at 07:58 UTC 589eb8d06511a6b50fb65c81aadb665060c5d285
11 files changed +204 -74
src/collectors/ebpf.plugin/ebpf.c
+1
@@ -3037,6 +3037,7 @@ static void ebpf_set_global_variables()
3037 isrh = get_redhat_release();
3038 pid_max = os_get_system_pid_max();
3039 running_on_kernel = ebpf_get_kernel_version();
3040 + memset(pids_fd, -1, sizeof(pids_fd));
3041 }
3042
3043 /**
src/collectors/ebpf.plugin/ebpf_apps.c
+44 -19
@@ -320,6 +320,8 @@ struct ebpf_target
320
321 size_t apps_groups_targets_count = 0; // # of apps_groups.conf targets
322
323 +int pids_fd[EBPF_PIDS_END_IDX];
324 +
325 // ----------------------------------------------------------------------------
326 // internal counters
327
@@ -470,8 +472,8 @@ static inline int read_proc_pid_stat(ebpf_pid_data_t *p)
472
473 struct stat statbuf;
474 if (stat(filename, &statbuf)) {
475 + // PID ended before we stat the file
476 p->has_proc_file = 0;
474 - p->thread_collecting &= ~(1<<EBPF_OPTION_ALL_CHARTS);
477 return 0;
478 }
479
@@ -540,7 +542,7 @@ static inline int ebpf_collect_data_for_pid(pid_t pid)
542 return 0;
543 }
544
543 - ebpf_pid_data_t *p = ebpf_get_pid_data((uint32_t)pid, 0, NULL, EBPF_OPTION_ALL_CHARTS);
545 + ebpf_pid_data_t *p = ebpf_get_pid_data((uint32_t)pid, 0, NULL, EBPF_PIDS_PROC_FILE);
546 read_proc_pid_stat(p);
547
548 // check its parent pid
@@ -744,7 +746,9 @@ void ebpf_del_pid_entry(pid_t pid)
746 if (p->prev)
747 p->prev->next = p->next;
748
747 - memset(p, 0, sizeof(ebpf_pid_data_t));
749 +
750 + if ((p->thread_collecting & EBPF_PIDS_PROC_FILE) || p->has_proc_file)
751 + ebpf_all_pids_count--;
752
753 rw_spinlock_write_lock(&ebpf_judy_pid.index.rw_spinlock);
754 netdata_ebpf_judy_pid_stats_t *pid_ptr = ebpf_get_pid_from_judy_unsafe(&ebpf_judy_pid.index.JudyLArray, p->pid);
@@ -764,7 +768,7 @@ void ebpf_del_pid_entry(pid_t pid)
768 }
769 rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
770
767 - ebpf_all_pids_count--;
771 + memset(p, 0, sizeof(ebpf_pid_data_t));
772 }
773
774 /**
@@ -773,12 +777,10 @@ void ebpf_del_pid_entry(pid_t pid)
777 static void ebpf_cleanup_exited_pids()
778 {
779 ebpf_pid_data_t *p = NULL;
776 - for (p = ebpf_pids_link_list; p;) {
780 + for (p = ebpf_pids_link_list; p; p = p->next) {
781 if (!p->has_proc_file) {
778 - ebpf_release_pid_data(p, 0, p->pid, EBPF_OPTION_ALL_CHARTS);
782 + ebpf_reset_specific_pid_data(p);
783 }
780 -
781 - p = p->next;
784 }
785 }
786
@@ -857,6 +859,7 @@ void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core)
859 {
860 int i, end = (maps_per_core) ? ebpf_nprocs : 1;
861 ebpf_process_stat_t *total = &out[0];
862 + uint64_t ct = total->ct;
863 for (i = 1; i < end; i++) {
864 ebpf_process_stat_t *w = &out[i];
865 total->exit_call += w->exit_call;
@@ -864,7 +867,11 @@ void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core)
867 total->create_thread += w->create_thread;
868 total->create_process += w->create_process;
869 total->release_call += w->release_call;
870 +
871 + if (w->ct > ct)
872 + ct = w->ct;
873 }
874 + total->ct = ct;
875 }
876
877 /**
@@ -878,7 +885,7 @@ void ebpf_process_sum_values_for_pids(ebpf_process_stat_t *process, struct ebpf_
885 memset(process, 0, sizeof(ebpf_process_stat_t));
886 for (; root; root = root->next) {
887 int32_t pid = root->pid;
881 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_PROCESS_IDX);
888 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_PROCESS_IDX);
889 ebpf_publish_process_t *in = local_pid->process;
890 if (!in)
891 continue;
@@ -906,6 +913,7 @@ void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core, uin
913 if (tbl_pid_stats_fd == -1)
914 return;
915
916 + pids_fd[EBPF_PIDS_PROCESS_IDX] = tbl_pid_stats_fd;
917 size_t length = sizeof(ebpf_process_stat_t);
918 if (maps_per_core)
919 length *= ebpf_nprocs;
@@ -920,17 +928,28 @@ void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core, uin
928
929 ebpf_process_apps_accumulator(process_stat_vector, maps_per_core);
930
923 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, 0, NULL, EBPF_MODULE_PROCESS_IDX);
931 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, 0, NULL, EBPF_PIDS_PROCESS_IDX);
932 ebpf_publish_process_t *w = local_pid->process;
933 if (!w)
934 local_pid->process = w = ebpf_process_allocate_publish();
935
928 - w->create_thread = process_stat_vector[0].create_thread;
929 - w->exit_call = process_stat_vector[0].exit_call;
930 - w->create_thread = process_stat_vector[0].create_thread;
931 - w->create_process = process_stat_vector[0].create_process;
932 - w->release_call = process_stat_vector[0].release_call;
933 - w->task_err = process_stat_vector[0].task_err;
936 + if (!w->ct || w->ct != process_stat_vector[0].ct) {
937 + w->ct = process_stat_vector[0].ct;
938 + w->create_thread = process_stat_vector[0].create_thread;
939 + w->exit_call = process_stat_vector[0].exit_call;
940 + w->create_thread = process_stat_vector[0].create_thread;
941 + w->create_process = process_stat_vector[0].create_process;
942 + w->release_call = process_stat_vector[0].release_call;
943 + w->task_err = process_stat_vector[0].task_err;
944 + } else {
945 + if (kill(key, 0)) { // No PID found
946 + ebpf_reset_specific_pid_data(local_pid);
947 + } else { // There is PID, but there is not data anymore
948 + ebpf_release_pid_data(local_pid, tbl_pid_stats_fd, key, EBPF_PIDS_PROCESS_IDX);
949 + ebpf_process_release_publish(w);
950 + local_pid->process = NULL;
951 + }
952 + }
953
954 end_process_loop:
955 memset(process_stat_vector, 0, length);
@@ -953,12 +972,18 @@ end_process_loop:
972 */
973 void ebpf_parse_proc_files()
974 {
956 - ebpf_pid_data_t *pids = ebpf_pids_link_list;
957 - while (pids) {
975 + ebpf_pid_data_t *pids;
976 + for (pids = ebpf_pids_link_list; pids;) {
977 + if (kill(pids->pid, 0)) { // No PID found
978 + ebpf_pid_data_t *next = pids->next;
979 + ebpf_reset_specific_pid_data(pids);
980 + pids = next;
981 + continue;
982 + }
983 +
984 pids->not_updated = EBPF_CLEANUP_FACTOR;
985 pids->merged = 0;
986 pids->children_count = 0;
961 -
987 pids = pids->next;
988 }
989
src/collectors/ebpf.plugin/ebpf_apps.h
+77 -13
@@ -44,6 +44,22 @@
44
45 #define EBPF_CLEANUP_FACTOR 2
46
47 +enum ebpf_pids_index {
48 + EBPF_PIDS_PROCESS_IDX,
49 + EBPF_PIDS_SOCKET_IDX,
50 + EBPF_PIDS_CACHESTAT_IDX,
51 + EBPF_PIDS_DCSTAT_IDX,
52 + EBPF_PIDS_SWAP_IDX,
53 + EBPF_PIDS_VFS_IDX,
54 + EBPF_PIDS_FD_IDX,
55 + EBPF_PIDS_SHM_IDX,
56 +
57 + EBPF_PIDS_PROC_FILE,
58 + EBPF_PIDS_END_IDX
59 +};
60 +
61 +extern int pids_fd[EBPF_PIDS_END_IDX];
62 +
63 enum ebpf_main_index {
64 EBPF_MODULE_PROCESS_IDX,
65 EBPF_MODULE_SOCKET_IDX,
@@ -154,6 +170,7 @@ extern struct ebpf_target *users_root_target;
170 extern struct ebpf_target *groups_root_target;
171 extern uint64_t collect_pids;
172
173 +// ebpf_pid_data
174 typedef struct __attribute__((packed)) ebpf_pid_data {
175 uint32_t pid;
176 uint32_t ppid;
@@ -256,7 +273,7 @@ static inline void *ebpf_swap_allocate_publish_swap()
273 return callocz(1, sizeof(netdata_publish_swap_t));
274 }
275
259 -static inline void ebpf_release_publish_swap(netdata_publish_swap_t *ptr)
276 +static inline void ebpf_swap_release_publish(netdata_publish_swap_t *ptr)
277 {
278 ebpf_hash_table_pids_count--;
279 freez(ptr);
@@ -287,14 +304,12 @@ static inline void ebpf_process_release_publish(ebpf_publish_process_t *ptr)
304 }
305
306 static inline ebpf_pid_data_t *ebpf_get_pid_data(uint32_t pid, uint32_t tgid, char *name, uint32_t idx) {
290 - // To add pids to target here will do host very slow
291 -
307 ebpf_pid_data_t *ptr = &ebpf_pids[pid];
308 + ptr->thread_collecting |= 1<<idx;
309 // The caller is getting data to work.
294 - if (!name && idx != EBPF_OPTION_ALL_CHARTS)
310 + if (!name && idx != EBPF_PIDS_PROC_FILE)
311 return ptr;
312
297 - ptr->thread_collecting |= 1<<idx;
313 if (ptr->pid == pid) {
314 return ptr;
315 }
@@ -305,17 +320,15 @@ static inline ebpf_pid_data_t *ebpf_get_pid_data(uint32_t pid, uint32_t tgid, ch
320 if (name)
321 strncpyz(ptr->comm, name, EBPF_MAX_COMPARE_NAME);
322
308 - if (idx == EBPF_OPTION_ALL_CHARTS) {
309 - // We are going to use only with pids listed in /proc, other PIDs are associated to it
310 - if (likely(ebpf_pids_link_list))
311 - ebpf_pids_link_list->prev = ptr;
323 + if (likely(ebpf_pids_link_list))
324 + ebpf_pids_link_list->prev = ptr;
325
313 - ptr->next = ebpf_pids_link_list;
314 - ebpf_pids_link_list = ptr;
326 + ptr->next = ebpf_pids_link_list;
327 + ebpf_pids_link_list = ptr;
328 + if (idx == EBPF_PIDS_PROC_FILE) {
329 + ebpf_all_pids_count++;
330 }
331
317 - ebpf_all_pids_count++;
318 -
332 return ptr;
333 }
334
@@ -330,6 +343,57 @@ static inline void ebpf_release_pid_data(ebpf_pid_data_t *eps, int fd, uint32_t
343 }
344 }
345
346 +static inline void ebpf_reset_specific_pid_data(ebpf_pid_data_t *ptr)
347 +{
348 + int idx;
349 + uint32_t pid = ptr->pid;
350 + for (idx = EBPF_PIDS_PROCESS_IDX; idx < EBPF_PIDS_PROC_FILE; idx++) {
351 + if (!(ptr->thread_collecting & (1<<idx))) {
352 + continue;
353 + }
354 + // Check if we still have the map loaded
355 + int fd = pids_fd[idx];
356 + if (fd <= STDERR_FILENO)
357 + continue;
358 +
359 + bpf_map_delete_elem(fd, &pid);
360 + ebpf_hash_table_pids_count--;
361 + void *clean;
362 + switch (idx) {
363 + case EBPF_PIDS_PROCESS_IDX:
364 + clean = ptr->process;
365 + break;
366 + case EBPF_PIDS_SOCKET_IDX:
367 + clean = ptr->socket;
368 + break;
369 + case EBPF_PIDS_CACHESTAT_IDX:
370 + clean = ptr->cachestat;
371 + break;
372 + case EBPF_PIDS_DCSTAT_IDX:
373 + clean = ptr->dc;
374 + break;
375 + case EBPF_PIDS_SWAP_IDX:
376 + clean = ptr->swap;
377 + break;
378 + case EBPF_PIDS_VFS_IDX:
379 + clean = ptr->vfs;
380 + break;
381 + case EBPF_PIDS_FD_IDX:
382 + clean = ptr->fd;
383 + break;
384 + case EBPF_PIDS_SHM_IDX:
385 + clean = ptr->shm;
386 + break;
387 + default:
388 + clean = NULL;
389 + }
390 + freez(clean);
391 + }
392 +
393 + ebpf_del_pid_entry(pid);
394 +}
395 +
396 +
397 typedef struct ebpf_pid_stat {
398 uint32_t pid;
399 uint64_t thread_collecting;
src/collectors/ebpf.plugin/ebpf_cachestat.c
+13 -7
@@ -525,6 +525,7 @@ void ebpf_obsolete_cachestat_apps_charts(struct ebpf_module *em)
525 */
526 static void ebpf_cachestat_exit(void *pptr)
527 {
528 + pids_fd[EBPF_PIDS_CACHESTAT_IDX] = -1;
529 ebpf_module_t *em = CLEANUP_FUNCTION_GET_PTR(pptr);
530 if(!em) return;
531
@@ -733,7 +734,7 @@ static void ebpf_read_cachestat_apps_table(int maps_per_core, uint32_t max_perio
734
735 cachestat_apps_accumulator(cv, maps_per_core);
736
736 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_MODULE_CACHESTAT_IDX);
737 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_PIDS_CACHESTAT_IDX);
738 netdata_publish_cachestat_t *publish = local_pid->cachestat;
739 if (!publish)
740 local_pid->cachestat = publish = ebpf_cachestat_allocate_publish();
@@ -741,10 +742,14 @@ static void ebpf_read_cachestat_apps_table(int maps_per_core, uint32_t max_perio
742 if (!publish->ct || publish->ct != cv->ct){
743 cachestat_save_pid_values(publish, cv);
744 local_pid->not_updated = 0;
744 - } else if (++local_pid->not_updated >= max_period) {
745 - ebpf_release_pid_data(local_pid, fd, key, EBPF_MODULE_CACHESTAT_IDX);
746 - ebpf_cachestat_release_publish(publish);
747 - local_pid->cachestat = NULL;
745 + } else {
746 + if (kill(key, 0)) { // No PID found
747 + ebpf_reset_specific_pid_data(local_pid);
748 + } else { // There is PID, but there is not data anymore
749 + ebpf_release_pid_data(local_pid, fd, key, EBPF_PIDS_CACHESTAT_IDX);
750 + ebpf_cachestat_release_publish(publish);
751 + local_pid->cachestat = NULL;
752 + }
753 }
754
755 end_cachestat_loop:
@@ -771,7 +776,7 @@ static void ebpf_update_cachestat_cgroup()
776 int pid = pids->pid;
777 netdata_publish_cachestat_t *out = &pids->cachestat;
778
774 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_CACHESTAT_IDX);
779 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_CACHESTAT_IDX);
780 netdata_publish_cachestat_t *in = local_pid->cachestat;
781 if (!in)
782 continue;
@@ -798,7 +803,7 @@ void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct ebpf_p
803 netdata_cachestat_t *dst = &publish->current;
804 for (; root; root = root->next) {
805 int32_t pid = root->pid;
801 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_CACHESTAT_IDX);
806 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_CACHESTAT_IDX);
807 netdata_publish_cachestat_t *w = local_pid->cachestat;
808 if (!w)
809 continue;
@@ -851,6 +856,7 @@ void *ebpf_read_cachestat_thread(void *ptr)
856 uint32_t lifetime = em->lifetime;
857 uint32_t running_time = 0;
858 usec_t period = update_every * USEC_PER_SEC;
859 + pids_fd[EBPF_PIDS_CACHESTAT_IDX] = cachestat_maps[NETDATA_CACHESTAT_PID_STATS].map_fd;
860 while (!ebpf_plugin_stop() && running_time < lifetime) {
861 (void)heartbeat_next(&hb, period);
862 if (ebpf_plugin_stop() || ++counter != update_every)
src/collectors/ebpf.plugin/ebpf_dcstat.c
+13 -7
@@ -453,6 +453,7 @@ static void ebpf_obsolete_dc_global(ebpf_module_t *em)
453 */
454 static void ebpf_dcstat_exit(void *pptr)
455 {
456 + pids_fd[EBPF_PIDS_DCSTAT_IDX] = -1;
457 ebpf_module_t *em = CLEANUP_FUNCTION_GET_PTR(pptr);
458 if(!em) return;
459
@@ -559,7 +560,7 @@ static void ebpf_read_dc_apps_table(int maps_per_core, uint32_t max_period)
560
561 ebpf_dcstat_apps_accumulator(cv, maps_per_core);
562
562 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_MODULE_DCSTAT_IDX);
563 + ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_PIDS_DCSTAT_IDX);
564 netdata_publish_dcstat_t *publish = pid_stat->dc;
565 if (!publish)
566 pid_stat->dc = publish = ebpf_dcallocate_publish();
@@ -571,10 +572,14 @@ static void ebpf_read_dc_apps_table(int maps_per_core, uint32_t max_period)
572 publish->curr.cache_access = cv[0].cache_access;
573
574 pid_stat->not_updated = 0;
574 - } else if (++pid_stat->not_updated >= max_period) {
575 - ebpf_release_pid_data(pid_stat, fd, key, EBPF_MODULE_DCSTAT_IDX);
576 - ebpf_dc_release_publish(publish);
577 - pid_stat->dc = NULL;
575 + } else {
576 + if (kill(key, 0)) { // No PID found
577 + ebpf_reset_specific_pid_data(pid_stat);
578 + } else { // There is PID, but there is not data anymore
579 + ebpf_release_pid_data(pid_stat, fd, key, EBPF_PIDS_DCSTAT_IDX);
580 + ebpf_dc_release_publish(publish);
581 + pid_stat->dc = NULL;
582 + }
583 }
584
585 end_dc_loop:
@@ -597,7 +602,7 @@ void ebpf_dcstat_sum_pids(netdata_publish_dcstat_t *publish, struct ebpf_pid_on_
602 memset(&publish->curr, 0, sizeof(netdata_publish_dcstat_pid_t));
603 for (; root; root = root->next) {
604 int32_t pid = root->pid;
600 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_DCSTAT_IDX);
605 + ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_DCSTAT_IDX);
606 netdata_publish_dcstat_t *w = pid_stat->dc;
607 if (!w)
608 continue;
@@ -656,6 +661,7 @@ void *ebpf_read_dcstat_thread(void *ptr)
661 uint32_t running_time = 0;
662 usec_t period = update_every * USEC_PER_SEC;
663 uint32_t max_period = EBPF_CLEANUP_FACTOR;
664 + pids_fd[EBPF_PIDS_DCSTAT_IDX] = dcstat_maps[NETDATA_DCSTAT_PID_STATS].map_fd;
665 while (!ebpf_plugin_stop() && running_time < lifetime) {
666 (void)heartbeat_next(&hb, period);
667 if (ebpf_plugin_stop() || ++counter != update_every)
@@ -785,7 +791,7 @@ static void ebpf_update_dc_cgroup()
791 for (pids = ect->pids; pids; pids = pids->next) {
792 int pid = pids->pid;
793 netdata_dcstat_pid_t *out = &pids->dc;
788 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_DCSTAT_IDX);
794 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_DCSTAT_IDX);
795 netdata_publish_dcstat_t *in = local_pid->dc;
796 if (!in)
797 continue;
src/collectors/ebpf.plugin/ebpf_fd.c
+13 -7
@@ -548,6 +548,7 @@ static void ebpf_obsolete_fd_global(ebpf_module_t *em)
548 */
549 static void ebpf_fd_exit(void *pptr)
550 {
551 + pids_fd[EBPF_PIDS_FD_IDX] = -1;
552 ebpf_module_t *em = CLEANUP_FUNCTION_GET_PTR(pptr);
553 if(!em) return;
554
@@ -700,7 +701,7 @@ static void ebpf_read_fd_apps_table(int maps_per_core, uint32_t max_period)
701
702 fd_apps_accumulator(fv, maps_per_core);
703
703 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(key, fv->tgid, fv->name, EBPF_MODULE_FD_IDX);
704 + ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(key, fv->tgid, fv->name, EBPF_PIDS_FD_IDX);
705 netdata_publish_fd_stat_t *publish_fd = pid_stat->fd;
706 if (!publish_fd)
707 pid_stat->fd = publish_fd = ebpf_fd_allocate_publish();
@@ -713,10 +714,14 @@ static void ebpf_read_fd_apps_table(int maps_per_core, uint32_t max_period)
714 publish_fd->close_err = fv->close_err;
715
716 pid_stat->not_updated = 0;
716 - } else if (++pid_stat->not_updated >= max_period) {
717 - ebpf_release_pid_data(pid_stat, fd, key, EBPF_MODULE_FD_IDX);
718 - ebpf_fd_release_publish(publish_fd);
719 - pid_stat->fd = NULL;
717 + } else {
718 + if (kill(key, 0)) { // No PID found
719 + ebpf_reset_specific_pid_data(pid_stat);
720 + } else { // There is PID, but there is not data anymore
721 + ebpf_release_pid_data(pid_stat, fd, key, EBPF_PIDS_FD_IDX);
722 + ebpf_fd_release_publish(publish_fd);
723 + pid_stat->fd = NULL;
724 + }
725 }
726
727 end_fd_loop:
@@ -740,7 +745,7 @@ static void ebpf_fd_sum_pids(netdata_fd_stat_t *fd, struct ebpf_pid_on_target *r
745
746 for (; root; root = root->next) {
747 int32_t pid = root->pid;
743 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_FD_IDX);
748 + ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_FD_IDX);
749 netdata_publish_fd_stat_t *w = pid_stat->fd;
750 if (!w)
751 continue;
@@ -795,6 +800,7 @@ void *ebpf_read_fd_thread(void *ptr)
800 uint32_t running_time = 0;
801 int period = USEC_PER_SEC;
802 uint32_t max_period = EBPF_CLEANUP_FACTOR;
803 + pids_fd[EBPF_PIDS_FD_IDX] = fd_maps[NETDATA_FD_PID_STATS].map_fd;
804 while (!ebpf_plugin_stop() && running_time < lifetime) {
805 (void)heartbeat_next(&hb, period);
806 if (ebpf_plugin_stop() || ++counter != update_every)
@@ -837,7 +843,7 @@ static void ebpf_update_fd_cgroup()
843 for (pids = ect->pids; pids; pids = pids->next) {
844 int pid = pids->pid;
845 netdata_publish_fd_stat_t *out = &pids->fd;
840 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_FD_IDX);
846 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_FD_IDX);
847 netdata_publish_fd_stat_t *in = local_pid->fd;
848 if (!in)
849 continue;
src/collectors/ebpf.plugin/ebpf_process.c
+2 -1
@@ -230,7 +230,7 @@ static void ebpf_update_process_cgroup()
230 for (pids = ect->pids; pids; pids = pids->next) {
231 int pid = pids->pid;
232 ebpf_publish_process_t *out = &pids->ps;
233 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_PROCESS_IDX);
233 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_PROCESS_IDX);
234 ebpf_publish_process_t *in = local_pid->process;
235 if (!in)
236 continue;
@@ -691,6 +691,7 @@ static void ebpf_process_disable_tracepoints()
691 */
692 static void ebpf_process_exit(void *pptr)
693 {
694 + pids_fd[EBPF_PIDS_PROCESS_IDX] = -1;
695 ebpf_module_t *em = CLEANUP_FUNCTION_GET_PTR(pptr);
696 if(!em) return;
697
src/collectors/ebpf.plugin/ebpf_shm.c
+13 -7
@@ -552,7 +552,7 @@ static void ebpf_update_shm_cgroup()
552 for (pids = ect->pids; pids; pids = pids->next) {
553 int pid = pids->pid;
554 netdata_publish_shm_t *out = &pids->shm;
555 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_SHM_IDX);
555 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_SHM_IDX);
556 netdata_publish_shm_t *in = local_pid->shm;
557 if (!in)
558 continue;
@@ -587,7 +587,7 @@ static void ebpf_read_shm_apps_table(int maps_per_core, uint32_t max_period)
587
588 shm_apps_accumulator(cv, maps_per_core);
589
590 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_MODULE_SHM_IDX);
590 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_PIDS_SHM_IDX);
591 netdata_publish_shm_t *publish = local_pid->shm;
592 if (!publish)
593 local_pid->shm = publish = ebpf_shm_allocate_publish();
@@ -595,10 +595,14 @@ static void ebpf_read_shm_apps_table(int maps_per_core, uint32_t max_period)
595 if (!publish->ct || publish->ct != cv->ct) {
596 memcpy(publish, &cv[0], sizeof(netdata_publish_shm_t));
597 local_pid->not_updated = 0;
598 - } else if (++local_pid->not_updated >= max_period){
599 - ebpf_release_pid_data(local_pid, fd, key, EBPF_MODULE_SHM_IDX);
600 - ebpf_shm_release_publish(publish);
601 - local_pid->shm = NULL;
598 + } else {
599 + if (kill(key, 0)) { // No PID found
600 + ebpf_reset_specific_pid_data(local_pid);
601 + } else { // There is PID, but there is not data anymore
602 + ebpf_release_pid_data(local_pid, fd, key, EBPF_PIDS_SHM_IDX);
603 + ebpf_shm_release_publish(publish);
604 + local_pid->shm = NULL;
605 + }
606 }
607
608 end_shm_loop:
@@ -668,7 +672,7 @@ static void ebpf_shm_sum_pids(netdata_publish_shm_t *shm, struct ebpf_pid_on_tar
672 memset(shm, 0, sizeof(netdata_publish_shm_t));
673 for (; root; root = root->next) {
674 int32_t pid = root->pid;
671 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_SHM_IDX);
675 + ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_SHM_IDX);
676 netdata_publish_shm_t *w = pid_stat->shm;
677 if (!w)
678 continue;
@@ -1076,6 +1080,7 @@ void *ebpf_read_shm_thread(void *ptr)
1080 uint32_t running_time = 0;
1081 usec_t period = update_every * USEC_PER_SEC;
1082 uint32_t max_period = EBPF_CLEANUP_FACTOR;
1083 + pids_fd[EBPF_PIDS_SHM_IDX] = shm_maps[NETDATA_PID_SHM_TABLE].map_fd;
1084 while (!ebpf_plugin_stop() && running_time < lifetime) {
1085 (void)heartbeat_next(&hb, period);
1086 if (ebpf_plugin_stop() || ++counter != update_every)
@@ -1334,6 +1339,7 @@ static int ebpf_shm_load_bpf(ebpf_module_t *em)
1339 */
1340 void *ebpf_shm_thread(void *ptr)
1341 {
1342 + pids_fd[EBPF_PIDS_SHM_IDX] = -1;
1343 ebpf_module_t *em = (ebpf_module_t *)ptr;
1344
1345 CLEANUP_FUNCTION_REGISTER(ebpf_shm_exit) cleanup_ptr = em;
src/collectors/ebpf.plugin/ebpf_socket.c
+1
@@ -2850,6 +2850,7 @@ static int ebpf_socket_load_bpf(ebpf_module_t *em)
2850 */
2851 void *ebpf_socket_thread(void *ptr)
2852 {
2853 + pids_fd[EBPF_PIDS_SOCKET_IDX] = -1;
2854 ebpf_module_t *em = (ebpf_module_t *)ptr;
2855
2856 CLEANUP_FUNCTION_REGISTER(ebpf_socket_exit) cleanup_ptr = em;
src/collectors/ebpf.plugin/ebpf_swap.c
+14 -7
@@ -391,6 +391,7 @@ static void ebpf_obsolete_swap_global(ebpf_module_t *em)
391 */
392 static void ebpf_swap_exit(void *ptr)
393 {
394 + pids_fd[EBPF_PIDS_SWAP_IDX] = -1;
395 ebpf_module_t *em = (ebpf_module_t *)ptr;
396
397 pthread_mutex_lock(&lock);
@@ -483,7 +484,7 @@ static void ebpf_update_swap_cgroup()
484 for (pids = ect->pids; pids; pids = pids->next) {
485 int pid = pids->pid;
486 netdata_publish_swap_t *out = &pids->swap;
486 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_SWAP_IDX);
487 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_SWAP_IDX);
488 netdata_publish_swap_t *in = local_pid->swap;
489 if (!in)
490 continue;
@@ -508,7 +509,7 @@ static void ebpf_swap_sum_pids(netdata_publish_swap_t *swap, struct ebpf_pid_on_
509
510 for (; root; root = root->next) {
511 int32_t pid = root->pid;
511 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_SWAP_IDX);
512 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_SWAP_IDX);
513 netdata_publish_swap_t *w = local_pid->swap;
514 if (!w)
515 continue;
@@ -560,17 +561,22 @@ static void ebpf_read_swap_apps_table(int maps_per_core, uint32_t max_period)
561
562 swap_apps_accumulator(cv, maps_per_core);
563
563 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_MODULE_SWAP_IDX);
564 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, EBPF_PIDS_SWAP_IDX);
565 netdata_publish_swap_t *publish = local_pid->swap;
566 if (!publish)
567 local_pid->swap = publish = ebpf_swap_allocate_publish_swap();
568 +
569 if (!publish->ct || publish->ct != cv->ct) {
570 memcpy(publish, cv, sizeof(netdata_publish_swap_t));
571 local_pid->not_updated = 0;
570 - } else if (++local_pid->not_updated >= max_period && !local_pid->has_proc_file) {
571 - ebpf_release_pid_data(local_pid, fd, key, EBPF_MODULE_SWAP_IDX);
572 - ebpf_release_publish_swap(publish);
573 - local_pid->swap = NULL;
572 + } else {
573 + if (kill(key, 0)) { // No PID found
574 + ebpf_reset_specific_pid_data(local_pid);
575 + } else { // There is PID, but there is not data anymore
576 + ebpf_release_pid_data(local_pid, fd, key, EBPF_PIDS_SWAP_IDX);
577 + ebpf_swap_release_publish(publish);
578 + local_pid->swap = NULL;
579 + }
580 }
581
582 // We are cleaning to avoid passing data read from one process to other.
@@ -608,6 +614,7 @@ void *ebpf_read_swap_thread(void *ptr)
614 uint32_t running_time = 0;
615 usec_t period = update_every * USEC_PER_SEC;
616 uint32_t max_period = EBPF_CLEANUP_FACTOR;
617 + pids_fd[EBPF_PIDS_SWAP_IDX] = swap_maps[NETDATA_PID_SWAP_TABLE].map_fd;
618
619 while (!ebpf_plugin_stop() && running_time < lifetime) {
620 (void)heartbeat_next(&hb, period);
src/collectors/ebpf.plugin/ebpf_vfs.c
+13 -6
@@ -1114,7 +1114,7 @@ static void ebpf_vfs_sum_pids(netdata_publish_vfs_t *vfs, struct ebpf_pid_on_tar
1114
1115 for (; root; root = root->next) {
1116 int32_t pid = root->pid;
1117 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_VFS_IDX);
1117 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_VFS_IDX);
1118 netdata_publish_vfs_t *w = local_pid->vfs;
1119 if (!w)
1120 continue;
@@ -1261,17 +1261,22 @@ static void ebpf_vfs_read_apps(int maps_per_core, uint32_t max_period)
1261
1262 vfs_apps_accumulator(vv, maps_per_core);
1263
1264 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, vv->tgid, vv->name, EBPF_MODULE_VFS_IDX);
1264 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, vv->tgid, vv->name, EBPF_PIDS_VFS_IDX);
1265 netdata_publish_vfs_t *publish = local_pid->vfs;
1266 if (!publish)
1267 local_pid->vfs = publish = ebpf_vfs_allocate_publish();
1268 +
1269 if (!publish->ct || publish->ct != vv->ct) {
1270 vfs_aggregate_set_vfs(publish, vv);
1271 local_pid->not_updated = 0;
1272 } else if (++local_pid->not_updated >= max_period){
1272 - ebpf_release_pid_data(local_pid, fd, key, EBPF_MODULE_VFS_IDX);
1273 - ebpf_vfs_release_publish(publish);
1274 - local_pid->vfs = NULL;
1273 + if (kill(key, 0)) { // No PID found
1274 + ebpf_reset_specific_pid_data(local_pid);
1275 + } else { // There is PID, but there is not data anymore
1276 + ebpf_release_pid_data(local_pid, fd, key, EBPF_PIDS_VFS_IDX);
1277 + ebpf_vfs_release_publish(publish);
1278 + local_pid->vfs = NULL;
1279 + }
1280 }
1281
1282 end_vfs_loop:
@@ -1299,7 +1304,7 @@ static void read_update_vfs_cgroup()
1304 netdata_publish_vfs_t *out = &pids->vfs;
1305 memset(out, 0, sizeof(netdata_publish_vfs_t));
1306
1302 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_VFS_IDX);
1307 + ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_PIDS_VFS_IDX);
1308 netdata_publish_vfs_t *in = local_pid->vfs;
1309 if (!in)
1310 continue;
@@ -2076,6 +2081,7 @@ void *ebpf_read_vfs_thread(void *ptr)
2081 uint32_t running_time = 0;
2082 usec_t period = update_every * USEC_PER_SEC;
2083 uint32_t max_period = EBPF_CLEANUP_FACTOR;
2084 + pids_fd[EBPF_PIDS_VFS_IDX] = vfs_maps[NETDATA_VFS_PID].map_fd;
2085 while (!ebpf_plugin_stop() && running_time < lifetime) {
2086 (void)heartbeat_next(&hb, period);
2087 if (ebpf_plugin_stop() || ++counter != update_every)
@@ -2624,6 +2630,7 @@ static int ebpf_vfs_load_bpf(ebpf_module_t *em)
2630 */
2631 void *ebpf_vfs_thread(void *ptr)
2632 {
2633 + pids_fd[EBPF_PIDS_VFS_IDX] = -1;
2634 ebpf_module_t *em = (ebpf_module_t *)ptr;
2635
2636 CLEANUP_FUNCTION_REGISTER(ebpf_vfs_exit) cleanup_ptr = em;