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;