@cryptotaxi247 / netdata-1 / commits / 12e830a51

ebpf.plugin: rework memory (#19844)

thiagoftsm committed Mar 28, 2025 at 13:56 UTC 12e830a51d0a4863c23b05de2f81f5d3e0b36ed8
23 files changed +747 -624
src/collectors/collectors-ipc/ebpf-ipc.c
+124 -7
@@ -2,10 +2,110 @@
2
3 #include "ebpf-ipc.h"
4
5 -netdata_ebpf_pid_stats_t *integration_shm;
5 +netdata_ebpf_pid_stats_t *integration_shm = NULL;
6 int shm_fd_ebpf_integration = -1;
7 sem_t *shm_mutex_ebpf_integration = SEM_FAILED;
8
9 +static Pvoid_t ebpf_ipc_JudyL = NULL;
10 +ebpf_user_mem_stat_t ebpf_stat_values;
11 +
12 +bool using_vector = false;
13 +
14 +static uint32_t *ebpf_shm_find_index_unsafe(uint32_t pid)
15 +{
16 + uint32_t *ret = NULL;
17 + Pvoid_t *Pvalue = JudyLGet(ebpf_ipc_JudyL, (Word_t)pid, PJE0);
18 + if (Pvalue)
19 + ret = *Pvalue;
20 + return ret;
21 +}
22 +
23 +static bool ebpf_find_pid_shm_del_unsafe(uint32_t pid, enum ebpf_pids_index idx)
24 +{
25 + uint32_t *lpid = ebpf_shm_find_index_unsafe(pid);
26 + if (!lpid || !ebpf_stat_values.current)
27 + return false;
28 +
29 + netdata_ebpf_pid_stats_t *ptr = &integration_shm[*lpid];
30 + ptr->threads &= ~(idx << 1);
31 + if (ptr->threads) {
32 + return true;
33 + }
34 +
35 + (void)JudyLDel(&ebpf_ipc_JudyL, (Word_t)pid, PJE0);
36 +
37 + ebpf_stat_values.current--;
38 + if (!ebpf_stat_values.current)
39 + return false;
40 +
41 + netdata_ebpf_pid_stats_t *newValue = &integration_shm[ebpf_stat_values.current];
42 + uint32_t *move = ebpf_shm_find_index_unsafe(newValue->pid);
43 + if (move) {
44 + *move = *lpid;
45 + memcpy(ptr, newValue, sizeof(*ptr));
46 + }
47 +
48 + return false;
49 +}
50 +
51 +static uint32_t ebpf_find_or_create_index_pid(uint32_t pid)
52 +{
53 + uint32_t *idx = ebpf_shm_find_index_unsafe(pid);
54 + if (!idx) {
55 + Pvoid_t *Pvalue = JudyLIns(&ebpf_ipc_JudyL, (Word_t)pid, PJE0);
56 + internal_fatal(!Pvalue || Pvalue == PJERR, "EBPF: pid judy index");
57 + if (likely(!*Pvalue)) {
58 + *Pvalue = idx = callocz(1, sizeof(*idx));
59 + *idx = ebpf_stat_values.current++;
60 + } else
61 + idx = *Pvalue;
62 + }
63 + return *idx;
64 +}
65 +
66 +bool netdata_ebpf_reset_shm_pointer_unsafe(int fd, uint32_t pid, enum ebpf_pids_index idx)
67 +{
68 + if (idx != NETDATA_EBPF_PIDS_SOCKET_IDX)
69 + bpf_map_delete_elem(fd, &pid);
70 +
71 + if (using_vector && integration_shm) {
72 + netdata_ebpf_pid_stats_t *ptr = &integration_shm[pid];
73 + ptr->threads &= ~(idx << 1);
74 + if (!ptr->threads) {
75 + ebpf_stat_values.current--;
76 + memset(ptr, 0, sizeof(*ptr));
77 + return false;
78 + }
79 + } else {
80 + return ebpf_find_pid_shm_del_unsafe(pid, idx);
81 + }
82 +
83 + return true;
84 +}
85 +
86 +netdata_ebpf_pid_stats_t *netdata_ebpf_get_shm_pointer_unsafe(uint32_t pid, enum ebpf_pids_index idx)
87 +{
88 + if (!integration_shm || (ebpf_stat_values.current + 1) == ebpf_stat_values.total)
89 + return NULL;
90 +
91 + if (!using_vector) {
92 + pid = ebpf_find_or_create_index_pid(pid);
93 + }
94 +
95 + if (pid >= ebpf_stat_values.total)
96 + return NULL;
97 +
98 + netdata_ebpf_pid_stats_t *ptr = &integration_shm[pid];
99 + if (using_vector && !ptr->threads) {
100 + ebpf_stat_values.current++;
101 + }
102 +
103 + ptr->pid = pid;
104 + ptr->threads |= idx << 1;
105 +
106 + return ptr;
107 +}
108 +
109 void netdata_integration_cleanup_shm()
110 {
111 if (shm_mutex_ebpf_integration != SEM_FAILED) {
@@ -13,8 +113,8 @@ void netdata_integration_cleanup_shm()
113 }
114
115 if (integration_shm) {
16 - size_t length = os_get_system_pid_max() * sizeof(netdata_ebpf_pid_stats_t);
17 - munmap(integration_shm, length);
116 + size_t length = ebpf_stat_values.total * sizeof(netdata_ebpf_pid_stats_t);
117 + nd_munmap(integration_shm, length);
118 }
119
120 if (shm_fd_ebpf_integration > 0) {
@@ -22,23 +122,35 @@ void netdata_integration_cleanup_shm()
122 }
123 }
124
125 +static void netdata_ebpf_select_access_mode(size_t pids)
126 +{
127 + size_t local_max = os_get_system_pid_max();
128 + using_vector = (pids == local_max);
129 +}
130 +
131 int netdata_integration_initialize_shm(size_t pids)
132 {
133 + if (!pids)
134 + return -1;
135 +
136 + netdata_ebpf_select_access_mode(pids);
137 +
138 shm_fd_ebpf_integration = shm_open(NETDATA_EBPF_INTEGRATION_NAME, O_CREAT | O_RDWR, 0660);
139 if (shm_fd_ebpf_integration < 0) {
140 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot initialize shared memory. Integration won't happen.");
141 return -1;
142 }
143
144 + ebpf_stat_values.current = 0;
145 + ebpf_stat_values.total = pids;
146 size_t length = pids * sizeof(netdata_ebpf_pid_stats_t);
147 if (ftruncate(shm_fd_ebpf_integration, (off_t)length)) {
148 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot set size for shared memory.");
149 goto end_shm;
150 }
151
39 - integration_shm = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd_ebpf_integration, 0);
40 - if (unlikely(MAP_FAILED == integration_shm)) {
41 - integration_shm = NULL;
152 + integration_shm = nd_mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd_ebpf_integration, 0);
153 + if (!integration_shm) {
154 nd_log(
155 NDLS_COLLECTORS,
156 NDLP_ERR,
@@ -53,9 +165,14 @@ int netdata_integration_initialize_shm(size_t pids)
165 }
166
167 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot create semaphore, integration between won't happen");
56 - munmap(integration_shm, length);
168 + nd_munmap(integration_shm, length);
169 integration_shm = NULL;
170
171 end_shm:
172 return -1;
173 }
174 +
175 +void netdata_integration_current_ipc_data(ebpf_user_mem_stat_t *values)
176 +{
177 + memcpy(values, &ebpf_stat_values, sizeof(*values));
178 +}
src/collectors/collectors-ipc/ebpf-ipc.h
+148 -8
@@ -20,6 +20,18 @@ extern "C" {
20 #include <stdio.h>
21 #include <stdint.h>
22
23 +#include <bpf/bpf.h>
24 +#include <bpf/libbpf.h>
25 +#ifdef LIBBPF_DEPRECATED
26 +#include <bpf/btf.h>
27 +#include <linux/btf.h>
28 +#endif
29 +
30 +typedef struct ebpf_user_mem_stat {
31 + uint32_t total;
32 + uint32_t current;
33 +} ebpf_user_mem_stat_t;
34 +
35 // ----------------------------------------------------------------------------
36 // Enumeration used to identify threads with eBPF PIDs
37 enum ebpf_pids_index {
@@ -57,6 +69,33 @@ typedef struct ebpf_process_stat {
69 uint32_t task_err;
70 } ebpf_process_stat_t;
71
72 +typedef struct ebpf_publish_process {
73 + uint64_t ct;
74 +
75 + //Counter
76 + uint32_t exit_call;
77 + uint32_t release_call;
78 + uint32_t create_process;
79 + uint32_t create_thread;
80 +
81 + //Counter
82 + uint32_t task_err;
83 +} ebpf_publish_process_t;
84 +
85 +typedef struct ebpf_socket_publish_apps {
86 + // Data read
87 + uint64_t bytes_sent; // Bytes sent
88 + uint64_t bytes_received; // Bytes received
89 + uint64_t call_tcp_sent; // Number of times tcp_sendmsg was called
90 + uint64_t call_tcp_received; // Number of times tcp_cleanup_rbuf was called
91 + uint64_t retransmit; // Number of times tcp_retransmit was called
92 + uint64_t call_udp_sent; // Number of times udp_sendmsg was called
93 + uint64_t call_udp_received; // Number of times udp_recvmsg was called
94 + uint64_t call_close; // Number of times tcp_close was called
95 + uint64_t call_tcp_v4_connection; // Number of times tcp_v4_connect was called
96 + uint64_t call_tcp_v6_connection; // Number of times tcp_v6_connect was called
97 +} ebpf_socket_publish_apps_t;
98 +
99 typedef struct netdata_socket {
100 char name[TASK_COMM_LEN];
101
@@ -100,6 +139,41 @@ typedef struct netdata_cachestat_pid {
139 uint32_t mark_buffer_dirty;
140 } netdata_cachestat_pid_t;
141
142 +typedef struct netdata_cachestat {
143 + uint32_t add_to_page_cache_lru;
144 + uint32_t mark_page_accessed;
145 + uint32_t account_page_dirtied;
146 + uint32_t mark_buffer_dirty;
147 +} netdata_cachestat_t;
148 +
149 +typedef struct netdata_publish_cachestat {
150 + uint64_t ct;
151 +
152 + long long ratio;
153 + long long dirty;
154 + long long hit;
155 + long long miss;
156 +
157 + netdata_cachestat_t current;
158 + netdata_cachestat_t prev;
159 +} netdata_publish_cachestat_t;
160 +
161 +typedef struct netdata_publish_dcstat_pid {
162 + uint64_t cache_access;
163 + uint32_t file_system;
164 + uint32_t not_found;
165 +} netdata_publish_dcstat_pid_t;
166 +
167 +typedef struct netdata_publish_dcstat {
168 + uint64_t ct;
169 +
170 + long long ratio;
171 + long long cache_access;
172 +
173 + netdata_publish_dcstat_pid_t curr;
174 + netdata_publish_dcstat_pid_t prev;
175 +} netdata_publish_dcstat_t;
176 +
177 typedef struct netdata_dcstat_pid {
178 uint64_t ct;
179 uint32_t tgid;
@@ -112,6 +186,13 @@ typedef struct netdata_dcstat_pid {
186 uint32_t not_found;
187 } netdata_dcstat_pid_t;
188
189 +typedef struct __attribute__((packed)) netdata_publish_swap {
190 + uint64_t ct;
191 +
192 + uint32_t read;
193 + uint32_t write;
194 +} netdata_publish_swap_t;
195 +
196 typedef struct netdata_ebpf_swap {
197 uint64_t ct;
198 uint32_t tgid;
@@ -123,6 +204,36 @@ typedef struct netdata_ebpf_swap {
204 uint32_t write;
205 } netdata_ebpf_swap_t;
206
207 +typedef struct netdata_publish_vfs {
208 + uint64_t ct;
209 +
210 + //Counter
211 + uint32_t write_call;
212 + uint32_t writev_call;
213 + uint32_t read_call;
214 + uint32_t readv_call;
215 + uint32_t unlink_call;
216 + uint32_t fsync_call;
217 + uint32_t open_call;
218 + uint32_t create_call;
219 +
220 + //Accumulator
221 + uint64_t write_bytes;
222 + uint64_t writev_bytes;
223 + uint64_t readv_bytes;
224 + uint64_t read_bytes;
225 +
226 + //Counter
227 + uint32_t write_err;
228 + uint32_t writev_err;
229 + uint32_t read_err;
230 + uint32_t readv_err;
231 + uint32_t unlink_err;
232 + uint32_t fsync_err;
233 + uint32_t open_err;
234 + uint32_t create_err;
235 +} netdata_publish_vfs_t;
236 +
237 typedef struct netdata_ebpf_vfs {
238 uint64_t ct;
239 uint32_t tgid;
@@ -157,6 +268,17 @@ typedef struct netdata_ebpf_vfs {
268 uint32_t create_err;
269 } netdata_ebpf_vfs_t;
270
271 +typedef struct netdata_publish_fd_stat {
272 + uint64_t ct;
273 +
274 + uint32_t open_call; // Open syscalls (open and openat)
275 + uint32_t close_call; // Close syscall (close)
276 +
277 + // Errors
278 + uint32_t open_err;
279 + uint32_t close_err;
280 +} netdata_publish_fd_stat_t;
281 +
282 typedef struct netdata_fd_stat {
283 uint64_t ct;
284 uint32_t tgid;
@@ -172,6 +294,15 @@ typedef struct netdata_fd_stat {
294 uint32_t close_err;
295 } netdata_fd_stat_t;
296
297 +typedef struct netdata_publish_shm {
298 + uint64_t ct;
299 +
300 + uint32_t get;
301 + uint32_t at;
302 + uint32_t dt;
303 + uint32_t ctl;
304 +} netdata_publish_shm_t;
305 +
306 typedef struct netdata_ebpf_shm {
307 uint64_t ct;
308 uint32_t tgid;
@@ -186,14 +317,17 @@ typedef struct netdata_ebpf_shm {
317 } netdata_ebpf_shm_t;
318
319 typedef struct netdata_ebpf_pid_stats {
189 - ebpf_process_stat_t process;
190 - netdata_socket_t socket;
191 - netdata_cachestat_pid_t cachestat;
192 - netdata_dcstat_pid_t directory_cache;
193 - netdata_ebpf_swap_t swap;
194 - netdata_ebpf_vfs_t vfs;
195 - netdata_fd_stat_t fd;
196 - netdata_ebpf_shm_t shm;
320 + uint32_t threads;
321 + uint32_t pid;
322 +
323 + ebpf_publish_process_t process;
324 + ebpf_socket_publish_apps_t socket;
325 + netdata_publish_cachestat_t cachestat;
326 + netdata_publish_dcstat_t directory_cache;
327 + netdata_publish_swap_t swap;
328 + netdata_publish_vfs_t vfs;
329 + netdata_publish_fd_stat_t fd;
330 + netdata_publish_shm_t shm;
331 } netdata_ebpf_pid_stats_t;
332
333 // ----------------------------------------------------------------------------
@@ -204,6 +338,12 @@ typedef struct netdata_ebpf_pid_stats {
338
339 int netdata_integration_initialize_shm(size_t pids);
340 void netdata_integration_cleanup_shm();
341 +netdata_ebpf_pid_stats_t *netdata_ebpf_get_shm_pointer_unsafe(uint32_t pid, enum ebpf_pids_index idx);
342 +bool netdata_ebpf_reset_shm_pointer_unsafe(int fd, uint32_t pid, enum ebpf_pids_index idx);
343 +void netdata_integration_current_ipc_data(ebpf_user_mem_stat_t *values);
344 +
345 +extern sem_t *shm_mutex_ebpf_integration;
346 +extern netdata_ebpf_pid_stats_t *integration_shm;
347
348 #ifdef __cplusplus
349 }
src/collectors/ebpf.plugin/ebpf.c
+68 -6
@@ -3697,6 +3697,15 @@ void ebpf_send_statistic_data()
3697 write_chart_dimension(memlock_stat, (long long)plugin_statistics.memlock_kern);
3698 ebpf_write_end_chart();
3699
3700 + ebpf_user_mem_stat_t ipc_data;
3701 + netdata_integration_current_ipc_data(&ipc_data);
3702 + NETDATA_DOUBLE ipc_value = 0.0;
3703 + if (ipc_data.total > 0 )
3704 + ipc_value = ( (NETDATA_DOUBLE)ipc_data.current/(NETDATA_DOUBLE)ipc_data.total )*100.0;
3705 + ebpf_write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_IPC_USAGE, "");
3706 + write_chart_dimension("positions", (long long)ipc_value);
3707 + ebpf_write_end_chart();
3708 +
3709 ebpf_write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_HASH_TABLES_LOADED, "");
3710 write_chart_dimension(hash_table_stat, (long long)plugin_statistics.hash_tables);
3711 ebpf_write_end_chart();
@@ -3823,6 +3832,34 @@ ebpf_create_thread_chart(char *name, char *title, char *units, int order, int up
3832 }
3833 }
3834
3835 +/**
3836 + * Create chart for Load Thread
3837 + *
3838 + * Write to standard output current values for load mode.
3839 + *
3840 + * @param update_every time used to update charts
3841 + */
3842 +static inline void ebpf_create_statistic_ipc_usage(int update_every)
3843 +{
3844 + ebpf_write_chart_cmd(
3845 + NETDATA_MONITORING_FAMILY,
3846 + NETDATA_EBPF_IPC_USAGE,
3847 + "",
3848 + "IPC used array positions.",
3849 + "%",
3850 + NETDATA_EBPF_FAMILY,
3851 + NETDATA_EBPF_CHART_TYPE_LINE,
3852 + NULL,
3853 + NETDATA_EBPF_ORDER_PIDS_IPC,
3854 + update_every,
3855 + NETDATA_EBPF_MODULE_NAME_PROCESS);
3856 +
3857 + ebpf_write_global_dimension(
3858 + "positions",
3859 + "positions",
3860 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
3861 +}
3862 +
3863 /**
3864 * Create chart for Load Thread
3865 *
@@ -4056,6 +4093,8 @@ static void ebpf_create_statistic_charts(int update_every)
4093 ebpf_create_thread_chart(name, "Time remaining for thread.", "seconds", j++, update_every, em);
4094 }
4095
4096 + ebpf_create_statistic_ipc_usage(update_every);
4097 +
4098 ebpf_create_statistic_load_chart(update_every);
4099
4100 ebpf_create_statistic_kernel_memory(update_every);
@@ -4170,6 +4209,28 @@ static pid_t ebpf_read_previous_pid(char *filename)
4209 return old_pid;
4210 }
4211
4212 +/**
4213 + * Validate Data Sharing Selection
4214 + *
4215 + * Validate user input avoid sigsegv
4216 + */
4217 +void ebpf_validate_data_sharing_selection()
4218 +{
4219 + uint32_t enabled = CONFIG_BOOLEAN_NO;
4220 + for (uint32_t i = 0; ebpf_modules[i].info.thread_name != NULL; i++) {
4221 + if (ebpf_modules[i].apps_charts || ebpf_modules[i].cgroup_charts) {
4222 + enabled = CONFIG_BOOLEAN_YES;
4223 + break;
4224 + }
4225 + }
4226 +
4227 + // TODO: MODIFY IN NEXT PRs THE OPTION TO ALSO USE SOCKET
4228 + if (enabled && integration_with_collectors != NETDATA_EBPF_INTEGRATION_SHM) {
4229 + //if (enabled && integration_with_collectors == NETDATA_EBPF_INTEGRATION_DISABLED) {
4230 + integration_with_collectors = NETDATA_EBPF_INTEGRATION_SHM;
4231 + }
4232 +}
4233 +
4234 /**
4235 * Initialize Data Sharing
4236 *
@@ -4177,6 +4238,9 @@ static pid_t ebpf_read_previous_pid(char *filename)
4238 */
4239 static void ebpf_initialize_data_sharing()
4240 {
4241 + ebpf_validate_data_sharing_selection();
4242 +
4243 + // Initialize
4244 switch (integration_with_collectors) {
4245 case NETDATA_EBPF_INTEGRATION_SOCKET: {
4246 socket_ipc =
@@ -4185,7 +4249,10 @@ static void ebpf_initialize_data_sharing()
4249 }
4250 case NETDATA_EBPF_INTEGRATION_SHM:
4251 // All pid_map_size have the same value
4188 - netdata_integration_initialize_shm(ebpf_modules[EBPF_MODULE_PROCESS_IDX].pid_map_size);
4252 + if (netdata_integration_initialize_shm(ebpf_modules[EBPF_MODULE_PROCESS_IDX].pid_map_size)) {
4253 + ebpf_set_apps_mode(NETDATA_EBPF_APPS_FLAG_NO);
4254 + ebpf_disable_cgroups();
4255 + }
4256 case NETDATA_EBPF_INTEGRATION_DISABLED:
4257 default:
4258 break;
@@ -4350,7 +4417,6 @@ int main(int argc, char **argv)
4417 heartbeat_init(&hb, USEC_PER_SEC);
4418 int update_apps_every = (int)EBPF_CFG_UPDATE_APPS_EVERY_DEFAULT;
4419 int update_apps_list = update_apps_every - 1;
4353 - int process_maps_per_core = ebpf_modules[EBPF_MODULE_PROCESS_IDX].maps_per_core;
4420 //Plugin will be killed when it receives a signal
4421 for (; !ebpf_plugin_stop(); global_iterations_counter++) {
4422 (void)heartbeat_next(&hb);
@@ -4370,10 +4436,6 @@ int main(int argc, char **argv)
4436 if (collect_pids) {
4437 pthread_mutex_lock(&collect_data_mutex);
4438 ebpf_parse_proc_files();
4373 - if (collect_pids & (1 << EBPF_MODULE_PROCESS_IDX)) {
4374 - collect_data_for_all_processes(process_pid_fd, process_maps_per_core);
4375 - }
4376 -
4439 ebpf_create_apps_charts(apps_groups_root_target);
4440 pthread_mutex_unlock(&collect_data_mutex);
4441 }
src/collectors/ebpf.plugin/ebpf.h
+1
@@ -152,6 +152,7 @@ typedef struct ebpf_tracepoint {
152 #define NETDATA_EBPF_THREADS "ebpf_threads"
153 #define NETDATA_EBPF_LIFE_TIME "ebpf_life_time"
154 #define NETDATA_EBPF_LOAD_METHOD "ebpf_load_methods"
155 +#define NETDATA_EBPF_IPC_USAGE "ebpf_ipc_usage"
156 #define NETDATA_EBPF_KERNEL_MEMORY "ebpf_kernel_memory"
157 #define NETDATA_EBPF_HASH_TABLES_LOADED "ebpf_hash_tables_count"
158 #define NETDATA_EBPF_HASH_TABLES_PER_CORE "ebpf_hash_tables_per_core"
src/collectors/ebpf.plugin/ebpf_apps.c
-117
@@ -925,123 +925,6 @@ static inline void aggregate_pid_on_target(struct ebpf_target *w, ebpf_pid_data_
925 w->root_pid = pid_on_target;
926 }
927
928 -/**
929 - * Process Accumulator
930 - *
931 - * Sum all values read from kernel and store in the first address.
932 - *
933 - * @param out the vector with read values.
934 - * @param maps_per_core do I need to read all cores?
935 - */
936 -void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core)
937 -{
938 - int i, end = (maps_per_core) ? ebpf_nprocs : 1;
939 - ebpf_process_stat_t *total = &out[0];
940 - uint64_t ct = total->ct;
941 - for (i = 1; i < end; i++) {
942 - ebpf_process_stat_t *w = &out[i];
943 - total->exit_call += w->exit_call;
944 - total->task_err += w->task_err;
945 - total->create_thread += w->create_thread;
946 - total->create_process += w->create_process;
947 - total->release_call += w->release_call;
948 -
949 - if (w->ct > ct)
950 - ct = w->ct;
951 - }
952 - total->ct = ct;
953 -}
954 -
955 -/**
956 - * Sum values for pid
957 - *
958 - * @param structure to store result.
959 - * @param root the structure with all available PIDs
960 - */
961 -void ebpf_process_sum_values_for_pids(ebpf_process_stat_t *process, struct ebpf_pid_on_target *root)
962 -{
963 - memset(process, 0, sizeof(ebpf_process_stat_t));
964 - for (; root; root = root->next) {
965 - int32_t pid = root->pid;
966 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_PROCESS_IDX);
967 - ebpf_publish_process_t *in = local_pid->process;
968 - if (!in)
969 - continue;
970 -
971 - process->task_err += in->task_err;
972 - process->release_call += in->release_call;
973 - process->exit_call += in->exit_call;
974 - process->create_thread += in->create_thread;
975 - process->create_process += in->create_process;
976 - }
977 -}
978 -
979 -/**
980 - * Collect data for all process
981 - *
982 - * Read data from hash table and store it in appropriate vectors.
983 - * It also creates the link between targets and PIDs.
984 - *
985 - * @param tbl_pid_stats_fd The mapped file descriptor for the hash table.
986 - * @param maps_per_core do I have hash maps per core?
987 - */
988 -void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core)
989 -{
990 - if (tbl_pid_stats_fd == -1)
991 - return;
992 -
993 - pids_fd[NETDATA_EBPF_PIDS_PROCESS_IDX] = tbl_pid_stats_fd;
994 - size_t length = sizeof(ebpf_process_stat_t);
995 - if (maps_per_core)
996 - length *= ebpf_nprocs;
997 -
998 - if (tbl_pid_stats_fd != -1) {
999 - uint32_t key = 0, next_key = 0;
1000 - while (bpf_map_get_next_key(tbl_pid_stats_fd, &key, &next_key) == 0) {
1001 - if (bpf_map_lookup_elem(tbl_pid_stats_fd, &key, process_stat_vector)) {
1002 - goto end_process_loop;
1003 - }
1004 -
1005 - ebpf_process_apps_accumulator(process_stat_vector, maps_per_core);
1006 -
1007 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, 0, NULL, NETDATA_EBPF_PIDS_PROCESS_IDX);
1008 - ebpf_publish_process_t *w = local_pid->process;
1009 - if (!w)
1010 - local_pid->process = w = ebpf_process_allocate_publish();
1011 -
1012 - if (!w->ct || w->ct != process_stat_vector[0].ct) {
1013 - w->ct = process_stat_vector[0].ct;
1014 - w->create_thread = process_stat_vector[0].create_thread;
1015 - w->exit_call = process_stat_vector[0].exit_call;
1016 - w->create_thread = process_stat_vector[0].create_thread;
1017 - w->create_process = process_stat_vector[0].create_process;
1018 - w->release_call = process_stat_vector[0].release_call;
1019 - w->task_err = process_stat_vector[0].task_err;
1020 - } else {
1021 - if (kill(key, 0)) { // No PID found
1022 - ebpf_reset_specific_pid_data(local_pid);
1023 - } else { // There is PID, but there is not data anymore
1024 - ebpf_release_pid_data(local_pid, tbl_pid_stats_fd, key, NETDATA_EBPF_PIDS_PROCESS_IDX);
1025 - ebpf_process_release_publish(w);
1026 - local_pid->process = NULL;
1027 - }
1028 - }
1029 -
1030 - end_process_loop:
1031 - memset(process_stat_vector, 0, length);
1032 - key = next_key;
1033 - }
1034 - }
1035 -
1036 - struct ebpf_target *w;
1037 - for (w = apps_groups_root_target; w; w = w->next) {
1038 - if (unlikely(!(w->processes)))
1039 - continue;
1040 -
1041 - ebpf_process_sum_values_for_pids(&w->process, w->root_pid);
1042 - }
1043 -}
1044 -
928 /**
929 *
930 */
src/collectors/ebpf.plugin/ebpf_apps.h
-112
@@ -71,22 +71,6 @@ enum ebpf_main_index {
71 EBPF_OPTION_UNITTEST
72 };
73
74 -// ----------------------------------------------------------------------------
75 -// Structures used to read information from kernel ring
76 -
77 -typedef struct __attribute__((packed)) ebpf_publish_process {
78 - uint64_t ct;
79 -
80 - //Counter
81 - uint32_t exit_call;
82 - uint32_t release_call;
83 - uint32_t create_process;
84 - uint32_t create_thread;
85 -
86 - //Counter
87 - uint32_t task_err;
88 -} ebpf_publish_process_t;
89 -
74 // ----------------------------------------------------------------------------
75 // pid_stat
76 //
@@ -171,102 +155,6 @@ extern size_t ebpf_all_pids_count;
155 extern size_t ebpf_hash_table_pids_count;
156 void ebpf_del_pid_entry(pid_t pid);
157
174 -static inline void *ebpf_cachestat_allocate_publish()
175 -{
176 - ebpf_hash_table_pids_count++;
177 - return callocz(1, sizeof(netdata_publish_cachestat_t));
178 -}
179 -
180 -static inline void ebpf_cachestat_release_publish(netdata_publish_cachestat_t *ptr)
181 -{
182 - ebpf_hash_table_pids_count--;
183 - freez(ptr);
184 -}
185 -
186 -static inline void *ebpf_dcallocate_publish()
187 -{
188 - ebpf_hash_table_pids_count++;
189 - return callocz(1, sizeof(netdata_publish_dcstat_t));
190 -}
191 -
192 -static inline void ebpf_dc_release_publish(netdata_publish_dcstat_t *ptr)
193 -{
194 - ebpf_hash_table_pids_count--;
195 - freez(ptr);
196 -}
197 -
198 -static inline void *ebpf_fd_allocate_publish()
199 -{
200 - ebpf_hash_table_pids_count++;
201 - return callocz(1, sizeof(netdata_publish_fd_stat_t));
202 -}
203 -
204 -static inline void ebpf_fd_release_publish(netdata_publish_fd_stat_t *ptr)
205 -{
206 - ebpf_hash_table_pids_count--;
207 - freez(ptr);
208 -}
209 -
210 -static inline void *ebpf_shm_allocate_publish()
211 -{
212 - ebpf_hash_table_pids_count++;
213 - return callocz(1, sizeof(netdata_publish_shm_t));
214 -}
215 -
216 -static inline void ebpf_shm_release_publish(netdata_publish_shm_t *ptr)
217 -{
218 - ebpf_hash_table_pids_count--;
219 - freez(ptr);
220 -}
221 -
222 -static inline void *ebpf_socket_allocate_publish()
223 -{
224 - ebpf_hash_table_pids_count++;
225 - return callocz(1, sizeof(ebpf_socket_publish_apps_t));
226 -}
227 -
228 -static inline void ebpf_socket_release_publish(ebpf_socket_publish_apps_t *ptr)
229 -{
230 - ebpf_hash_table_pids_count--;
231 - freez(ptr);
232 -}
233 -
234 -static inline void *ebpf_swap_allocate_publish_swap()
235 -{
236 - ebpf_hash_table_pids_count++;
237 - return callocz(1, sizeof(netdata_publish_swap_t));
238 -}
239 -
240 -static inline void ebpf_swap_release_publish(netdata_publish_swap_t *ptr)
241 -{
242 - ebpf_hash_table_pids_count--;
243 - freez(ptr);
244 -}
245 -
246 -static inline void *ebpf_vfs_allocate_publish()
247 -{
248 - ebpf_hash_table_pids_count++;
249 - return callocz(1, sizeof(netdata_publish_vfs_t));
250 -}
251 -
252 -static inline void ebpf_vfs_release_publish(netdata_publish_vfs_t *ptr)
253 -{
254 - ebpf_hash_table_pids_count--;
255 - freez(ptr);
256 -}
257 -
258 -static inline void *ebpf_process_allocate_publish()
259 -{
260 - ebpf_hash_table_pids_count++;
261 - return callocz(1, sizeof(ebpf_publish_process_t));
262 -}
263 -
264 -static inline void ebpf_process_release_publish(ebpf_publish_process_t *ptr)
265 -{
266 - ebpf_hash_table_pids_count--;
267 - freez(ptr);
268 -}
269 -
158 ebpf_pid_data_t *ebpf_find_or_create_pid_data(pid_t pid);
159
160 static inline ebpf_pid_data_t *ebpf_get_pid_data(uint32_t pid, uint32_t tgid, char *name, uint32_t idx)
src/collectors/ebpf.plugin/ebpf_cachestat.c
+28 -26
@@ -775,21 +775,17 @@ static void ebpf_read_cachestat_apps_table(int maps_per_core)
775
776 cachestat_apps_accumulator(cv, maps_per_core);
777
778 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
779 - netdata_publish_cachestat_t *publish = local_pid->cachestat;
780 - if (!publish)
781 - local_pid->cachestat = publish = ebpf_cachestat_allocate_publish();
778 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
779 + if (!local_pid)
780 + continue;
781 + netdata_publish_cachestat_t *publish = &local_pid->cachestat;
782
783 if (!publish->ct || publish->ct != cv->ct) {
784 cachestat_save_pid_values(publish, cv);
785 - local_pid->not_updated = 0;
785 } else {
787 - if (kill(key, 0)) { // No PID found
788 - ebpf_reset_specific_pid_data(local_pid);
789 - } else { // There is PID, but there is not data anymore
790 - ebpf_release_pid_data(local_pid, fd, key, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
791 - ebpf_cachestat_release_publish(publish);
792 - local_pid->cachestat = NULL;
786 + if (kill((pid_t)key, 0)) { // No PID found
787 + if (netdata_ebpf_reset_shm_pointer_unsafe(fd, key, NETDATA_EBPF_PIDS_CACHESTAT_IDX))
788 + memset(publish, 0, sizeof(*publish));
789 }
790 }
791
@@ -814,14 +810,15 @@ static void ebpf_update_cachestat_cgroup()
810 for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
811 struct pid_on_target2 *pids;
812 for (pids = ect->pids; pids; pids = pids->next) {
817 - int pid = pids->pid;
813 + uint32_t pid = pids->pid;
814 netdata_publish_cachestat_t *out = &pids->cachestat;
815
820 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
821 - netdata_publish_cachestat_t *in = local_pid->cachestat;
822 - if (!in)
816 + netdata_ebpf_pid_stats_t *local_pid =
817 + netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
818 + if (!local_pid)
819 continue;
820
821 + netdata_publish_cachestat_t *in = &local_pid->cachestat;
822 memcpy(&out->current, &in->current, sizeof(netdata_cachestat_t));
823 }
824 }
@@ -843,11 +840,11 @@ void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct ebpf_p
840
841 netdata_cachestat_t *dst = &publish->current;
842 for (; root; root = root->next) {
846 - int32_t pid = root->pid;
847 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
848 - netdata_publish_cachestat_t *w = local_pid->cachestat;
849 - if (!w)
843 + uint32_t pid = root->pid;
844 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_CACHESTAT_IDX);
845 + if (!local_pid)
846 continue;
847 + netdata_publish_cachestat_t *w = &local_pid->cachestat;
848
849 netdata_cachestat_t *src = &w->current;
850 dst->account_page_dirtied += src->account_page_dirtied;
@@ -860,16 +857,18 @@ void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct ebpf_p
857 /**
858 * Resume apps data
859 */
863 -void ebpf_resume_apps_data()
860 +void ebpf_cachestat_resume_apps_data()
861 {
862 struct ebpf_target *w;
863
864 + pthread_mutex_lock(&collect_data_mutex);
865 for (w = apps_groups_root_target; w; w = w->next) {
866 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_CACHESTAT_IDX))))
867 continue;
868
869 ebpf_cachestat_sum_pids(&w->cachestat, w->root_pid);
870 }
871 + pthread_mutex_unlock(&collect_data_mutex);
872 }
873
874 /**
@@ -884,9 +883,13 @@ void ebpf_resume_apps_data()
883 void *ebpf_read_cachestat_thread(void *ptr)
884 {
885 ebpf_module_t *em = (ebpf_module_t *)ptr;
886 + int collect_pid = (em->apps_charts || em->cgroup_charts);
887 + if (!collect_pid)
888 + return NULL;
889
890 int maps_per_core = em->maps_per_core;
891 int update_every = em->update_every;
892 + int cgroups = em->cgroup_charts;
893
894 int counter = update_every - 1;
895
@@ -900,10 +903,12 @@ void *ebpf_read_cachestat_thread(void *ptr)
903 if (ebpf_plugin_stop() || ++counter != update_every)
904 continue;
905
903 - pthread_mutex_lock(&collect_data_mutex);
906 + sem_wait(shm_mutex_ebpf_integration);
907 ebpf_read_cachestat_apps_table(maps_per_core);
905 - ebpf_resume_apps_data();
906 - pthread_mutex_unlock(&collect_data_mutex);
908 + ebpf_cachestat_resume_apps_data();
909 + if (cgroups && shm_ebpf_cgroup.header)
910 + ebpf_update_cachestat_cgroup();
911 + sem_post(shm_mutex_ebpf_integration);
912
913 counter = 0;
914
@@ -1516,9 +1521,6 @@ static void cachestat_collector(ebpf_module_t *em)
1521 netdata_apps_integration_flags_t apps = em->apps_charts;
1522 ebpf_cachestat_read_global_tables(stats, maps_per_core);
1523
1519 - if (cgroups && shm_ebpf_cgroup.header)
1520 - ebpf_update_cachestat_cgroup();
1521 -
1524 pthread_mutex_lock(&lock);
1525
1526 cachestat_send_global(&publish);
src/collectors/ebpf.plugin/ebpf_cachestat.h
-20
@@ -66,27 +66,7 @@ enum cachestat_indexes {
66
67 enum cachestat_tables { NETDATA_CACHESTAT_GLOBAL_STATS, NETDATA_CACHESTAT_PID_STATS, NETDATA_CACHESTAT_CTRL };
68
69 -typedef struct __attribute__((packed)) netdata_cachestat {
70 - uint32_t add_to_page_cache_lru;
71 - uint32_t mark_page_accessed;
72 - uint32_t account_page_dirtied;
73 - uint32_t mark_buffer_dirty;
74 -} netdata_cachestat_t;
75 -
76 -typedef struct __attribute__((packed)) netdata_publish_cachestat {
77 - uint64_t ct;
78 -
79 - long long ratio;
80 - long long dirty;
81 - long long hit;
82 - long long miss;
83 -
84 - netdata_cachestat_t current;
85 - netdata_cachestat_t prev;
86 -} netdata_publish_cachestat_t;
87 -
69 void *ebpf_cachestat_thread(void *ptr);
89 -void ebpf_cachestat_release(netdata_publish_cachestat_t *stat);
70
71 extern struct config cachestat_config;
72 extern netdata_ebpf_targets_t cachestat_targets[];
src/collectors/ebpf.plugin/ebpf_dcstat.c
+47 -49
@@ -574,25 +574,19 @@ static void ebpf_read_dc_apps_table(int maps_per_core)
574
575 ebpf_dcstat_apps_accumulator(cv, maps_per_core);
576
577 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(key, cv->tgid, cv->name, NETDATA_EBPF_PIDS_DCSTAT_IDX);
578 - netdata_publish_dcstat_t *publish = pid_stat->dc;
579 - if (!publish)
580 - pid_stat->dc = publish = ebpf_dcallocate_publish();
581 -
577 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_DCSTAT_IDX);
578 + if (!local_pid)
579 + continue;
580 + netdata_publish_dcstat_t *publish = &local_pid->directory_cache;
581 if (!publish->ct || publish->ct != cv->ct) {
582 publish->ct = cv->ct;
583 publish->curr.not_found = cv[0].not_found;
584 publish->curr.file_system = cv[0].file_system;
585 publish->curr.cache_access = cv[0].cache_access;
587 -
588 - pid_stat->not_updated = 0;
586 } else {
590 - if (kill(key, 0)) { // No PID found
591 - ebpf_reset_specific_pid_data(pid_stat);
592 - } else { // There is PID, but there is not data anymore
593 - ebpf_release_pid_data(pid_stat, fd, key, NETDATA_EBPF_PIDS_DCSTAT_IDX);
594 - ebpf_dc_release_publish(publish);
595 - pid_stat->dc = NULL;
587 + if (kill((pid_t)key, 0)) { // No PID found
588 + if (netdata_ebpf_reset_shm_pointer_unsafe(fd, key, NETDATA_EBPF_PIDS_DCSTAT_IDX))
589 + memset(publish, 0, sizeof(*publish));
590 }
591 }
592
@@ -615,11 +609,11 @@ void ebpf_dcstat_sum_pids(netdata_publish_dcstat_t *publish, struct ebpf_pid_on_
609 {
610 memset(&publish->curr, 0, sizeof(netdata_publish_dcstat_pid_t));
611 for (; root; root = root->next) {
618 - int32_t pid = root->pid;
619 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_DCSTAT_IDX);
620 - netdata_publish_dcstat_t *w = pid_stat->dc;
621 - if (!w)
612 + uint32_t pid = root->pid;
613 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_DCSTAT_IDX);
614 + if (!local_pid)
615 continue;
616 + netdata_publish_dcstat_t *w = &local_pid->directory_cache;
617
618 publish->curr.cache_access += w->curr.cache_access;
619 publish->curr.file_system += w->curr.file_system;
@@ -634,6 +628,7 @@ void ebpf_dc_resume_apps_data()
628 {
629 struct ebpf_target *w;
630
631 + pthread_mutex_lock(&collect_data_mutex);
632 for (w = apps_groups_root_target; w; w = w->next) {
633 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_DCSTAT_IDX))))
634 continue;
@@ -645,6 +640,35 @@ void ebpf_dc_resume_apps_data()
640
641 dcstat_update_publish(&w->dcstat, cache, not_found);
642 }
643 + pthread_mutex_unlock(&collect_data_mutex);
644 +}
645 +
646 +/**
647 + * Update cgroup
648 + *
649 + * Update cgroup data based in collected PID.
650 + *
651 + * @param maps_per_core do I need to read all cores?
652 + */
653 +static void ebpf_update_dc_cgroup()
654 +{
655 + ebpf_cgroup_target_t *ect;
656 + pthread_mutex_lock(&mutex_cgroup_shm);
657 + for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
658 + struct pid_on_target2 *pids;
659 + for (pids = ect->pids; pids; pids = pids->next) {
660 + uint32_t pid = pids->pid;
661 + netdata_dcstat_pid_t *out = &pids->dc;
662 + netdata_ebpf_pid_stats_t *local_pid =
663 + netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_DCSTAT_IDX);
664 + if (!local_pid)
665 + continue;
666 + netdata_publish_dcstat_t *in = &local_pid->directory_cache;
667 +
668 + memcpy(out, &in->curr, sizeof(netdata_publish_dcstat_pid_t));
669 + }
670 + }
671 + pthread_mutex_unlock(&mutex_cgroup_shm);
672 }
673
674 /**
@@ -663,6 +687,7 @@ void *ebpf_read_dcstat_thread(void *ptr)
687 int maps_per_core = em->maps_per_core;
688 int update_every = em->update_every;
689 int collect_pid = (em->apps_charts || em->cgroup_charts);
690 + int cgroups = em->cgroup_charts;
691 if (!collect_pid)
692 return NULL;
693
@@ -678,10 +703,13 @@ void *ebpf_read_dcstat_thread(void *ptr)
703 if (ebpf_plugin_stop() || ++counter != update_every)
704 continue;
705
681 - pthread_mutex_lock(&collect_data_mutex);
706 + sem_wait(shm_mutex_ebpf_integration);
707 ebpf_read_dc_apps_table(maps_per_core);
708 ebpf_dc_resume_apps_data();
684 - pthread_mutex_unlock(&collect_data_mutex);
709 + if (cgroups && shm_ebpf_cgroup.header)
710 + ebpf_update_dc_cgroup();
711 +
712 + sem_post(shm_mutex_ebpf_integration);
713
714 counter = 0;
715
@@ -790,33 +818,6 @@ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr)
818 *
819 *****************************************************************/
820
793 -/**
794 - * Update cgroup
795 - *
796 - * Update cgroup data based in collected PID.
797 - *
798 - * @param maps_per_core do I need to read all cores?
799 - */
800 -static void ebpf_update_dc_cgroup()
801 -{
802 - ebpf_cgroup_target_t *ect;
803 - pthread_mutex_lock(&mutex_cgroup_shm);
804 - for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
805 - struct pid_on_target2 *pids;
806 - for (pids = ect->pids; pids; pids = pids->next) {
807 - int pid = pids->pid;
808 - netdata_dcstat_pid_t *out = &pids->dc;
809 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_DCSTAT_IDX);
810 - netdata_publish_dcstat_t *in = local_pid->dc;
811 - if (!in)
812 - continue;
813 -
814 - memcpy(out, &in->curr, sizeof(netdata_publish_dcstat_pid_t));
815 - }
816 - }
817 - pthread_mutex_unlock(&mutex_cgroup_shm);
818 -}
819 -
821 /**
822 * Read global table
823 *
@@ -1354,9 +1355,6 @@ static void dcstat_collector(ebpf_module_t *em)
1355 netdata_apps_integration_flags_t apps = em->apps_charts;
1356 ebpf_dc_read_global_tables(stats, maps_per_core);
1357
1357 - if (cgroups && shm_ebpf_cgroup.header)
1358 - ebpf_update_dc_cgroup();
1359 -
1358 pthread_mutex_lock(&lock);
1359
1360 dcstat_send_global(&publish);
src/collectors/ebpf.plugin/ebpf_dcstat.h
-16
@@ -65,22 +65,6 @@ enum directory_cache_counters {
65
66 enum directory_cache_targets { NETDATA_DC_TARGET_LOOKUP_FAST, NETDATA_DC_TARGET_D_LOOKUP };
67
68 -typedef struct __attribute__((packed)) netdata_publish_dcstat_pid {
69 - uint64_t cache_access;
70 - uint32_t file_system;
71 - uint32_t not_found;
72 -} netdata_publish_dcstat_pid_t;
73 -
74 -typedef struct __attribute__((packed)) netdata_publish_dcstat {
75 - uint64_t ct;
76 -
77 - long long ratio;
78 - long long cache_access;
79 -
80 - netdata_publish_dcstat_pid_t curr;
81 - netdata_publish_dcstat_pid_t prev;
82 -} netdata_publish_dcstat_t;
83 -
68 void *ebpf_dcstat_thread(void *ptr);
69 void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr);
70 void ebpf_dcstat_release(netdata_publish_dcstat_t *stat);
src/collectors/ebpf.plugin/ebpf_fd.c
+49 -48
@@ -715,10 +715,10 @@ static void ebpf_read_fd_apps_table(int maps_per_core)
715
716 fd_apps_accumulator(fv, maps_per_core);
717
718 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(key, fv->tgid, fv->name, NETDATA_EBPF_PIDS_FD_IDX);
719 - netdata_publish_fd_stat_t *publish_fd = pid_stat->fd;
720 - if (!publish_fd)
721 - pid_stat->fd = publish_fd = ebpf_fd_allocate_publish();
718 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_FD_IDX);
719 + if (!local_pid)
720 + continue;
721 + netdata_publish_fd_stat_t *publish_fd = &local_pid->fd;
722
723 if (!publish_fd->ct || publish_fd->ct != fv->ct) {
724 publish_fd->ct = fv->ct;
@@ -726,15 +726,10 @@ static void ebpf_read_fd_apps_table(int maps_per_core)
726 publish_fd->close_call = fv->close_call;
727 publish_fd->open_err = fv->open_err;
728 publish_fd->close_err = fv->close_err;
729 -
730 - pid_stat->not_updated = 0;
729 } else {
732 - if (kill(key, 0)) { // No PID found
733 - ebpf_reset_specific_pid_data(pid_stat);
734 - } else { // There is PID, but there is not data anymore
735 - ebpf_release_pid_data(pid_stat, fd, key, NETDATA_EBPF_PIDS_FD_IDX);
736 - ebpf_fd_release_publish(publish_fd);
737 - pid_stat->fd = NULL;
730 + if (kill((pid_t)key, 0)) { // No PID found
731 + if (netdata_ebpf_reset_shm_pointer_unsafe(fd, key, NETDATA_EBPF_PIDS_FD_IDX))
732 + memset(publish_fd, 0, sizeof(*publish_fd));
733 }
734 }
735
@@ -758,11 +753,11 @@ static void ebpf_fd_sum_pids(netdata_fd_stat_t *fd, struct ebpf_pid_on_target *r
753 memset(fd, 0, sizeof(netdata_fd_stat_t));
754
755 for (; root; root = root->next) {
761 - int32_t pid = root->pid;
762 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_FD_IDX);
763 - netdata_publish_fd_stat_t *w = pid_stat->fd;
764 - if (!w)
756 + uint32_t pid = root->pid;
757 + netdata_ebpf_pid_stats_t *pid_stat = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_FD_IDX);
758 + if (!pid_stat)
759 continue;
760 + netdata_publish_fd_stat_t *w = &pid_stat->fd;
761
762 fd->open_call += w->open_call;
763 fd->close_call += w->close_call;
@@ -778,12 +773,44 @@ void ebpf_fd_resume_apps_data()
773 {
774 struct ebpf_target *w;
775
776 + pthread_mutex_lock(&collect_data_mutex);
777 for (w = apps_groups_root_target; w; w = w->next) {
778 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_FD_IDX))))
779 continue;
780
781 ebpf_fd_sum_pids(&w->fd, w->root_pid);
782 }
783 + pthread_mutex_unlock(&collect_data_mutex);
784 +}
785 +
786 +/**
787 + * Update cgroup
788 + *
789 + * Update cgroup data collected per PID.
790 + *
791 + * @param maps_per_core do I need to read all cores?
792 + */
793 +static void ebpf_update_fd_cgroup()
794 +{
795 + ebpf_cgroup_target_t *ect;
796 +
797 + pthread_mutex_lock(&mutex_cgroup_shm);
798 + for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
799 + struct pid_on_target2 *pids;
800 + for (pids = ect->pids; pids; pids = pids->next) {
801 + uint32_t pid = pids->pid;
802 + netdata_publish_fd_stat_t *out = &pids->fd;
803 +
804 + netdata_ebpf_pid_stats_t *pid_stat = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_FD_IDX);
805 + if (!pid_stat)
806 + continue;
807 +
808 + netdata_publish_fd_stat_t *in = &pid_stat->fd;
809 +
810 + memcpy(out, in, sizeof(netdata_publish_fd_stat_t));
811 + }
812 + }
813 + pthread_mutex_unlock(&mutex_cgroup_shm);
814 }
815
816 /**
@@ -808,6 +835,7 @@ void *ebpf_read_fd_thread(void *ptr)
835 int counter = update_every - 1;
836
837 uint32_t lifetime = em->lifetime;
838 + int cgroups = em->cgroup_charts;
839 uint32_t running_time = 0;
840 pids_fd[NETDATA_EBPF_PIDS_FD_IDX] = fd_maps[NETDATA_FD_PID_STATS].map_fd;
841
@@ -818,10 +846,13 @@ void *ebpf_read_fd_thread(void *ptr)
846 if (ebpf_plugin_stop() || ++counter != update_every)
847 continue;
848
821 - pthread_mutex_lock(&collect_data_mutex);
849 + sem_wait(shm_mutex_ebpf_integration);
850 ebpf_read_fd_apps_table(maps_per_core);
851 ebpf_fd_resume_apps_data();
824 - pthread_mutex_unlock(&collect_data_mutex);
852 + if (cgroups && shm_ebpf_cgroup.header)
853 + ebpf_update_fd_cgroup();
854 +
855 + sem_post(shm_mutex_ebpf_integration);
856
857 counter = 0;
858
@@ -838,33 +869,6 @@ void *ebpf_read_fd_thread(void *ptr)
869 return NULL;
870 }
871
841 -/**
842 - * Update cgroup
843 - *
844 - * Update cgroup data collected per PID.
845 - *
846 - * @param maps_per_core do I need to read all cores?
847 - */
848 -static void ebpf_update_fd_cgroup()
849 -{
850 - ebpf_cgroup_target_t *ect;
851 -
852 - pthread_mutex_lock(&mutex_cgroup_shm);
853 - for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
854 - struct pid_on_target2 *pids;
855 - for (pids = ect->pids; pids; pids = pids->next) {
856 - int pid = pids->pid;
857 - netdata_publish_fd_stat_t *out = &pids->fd;
858 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_FD_IDX);
859 - netdata_publish_fd_stat_t *in = local_pid->fd;
860 - if (!in)
861 - continue;
862 - memcpy(out, in, sizeof(netdata_publish_fd_stat_t));
863 - }
864 - }
865 - pthread_mutex_unlock(&mutex_cgroup_shm);
866 -}
867 -
872 /**
873 * Send data to Netdata calling auxiliary functions.
874 *
@@ -1298,9 +1302,6 @@ static void fd_collector(ebpf_module_t *em)
1302 netdata_apps_integration_flags_t apps = em->apps_charts;
1303 ebpf_fd_read_global_tables(stats, maps_per_core);
1304
1301 - if (cgroups && shm_ebpf_cgroup.header)
1302 - ebpf_update_fd_cgroup();
1303 -
1305 pthread_mutex_lock(&lock);
1306
1307 ebpf_fd_send_data(em);
src/collectors/ebpf.plugin/ebpf_fd.h
-11
@@ -41,17 +41,6 @@
41 // ARAL name
42 #define NETDATA_EBPF_FD_ARAL_NAME "ebpf_fd"
43
44 -typedef struct __attribute__((packed)) netdata_publish_fd_stat {
45 - uint64_t ct;
46 -
47 - uint32_t open_call; // Open syscalls (open and openat)
48 - uint32_t close_call; // Close syscall (close)
49 -
50 - // Errors
51 - uint32_t open_err;
52 - uint32_t close_err;
53 -} netdata_publish_fd_stat_t;
54 -
44 enum fd_tables {
45 NETDATA_FD_PID_STATS,
46 NETDATA_FD_GLOBAL_STATS,
src/collectors/ebpf.plugin/ebpf_process.c
+132 -6
@@ -244,13 +244,15 @@ static void ebpf_update_process_cgroup()
244 for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
245 struct pid_on_target2 *pids;
246 for (pids = ect->pids; pids; pids = pids->next) {
247 - int pid = pids->pid;
247 + uint32_t pid = pids->pid;
248 ebpf_publish_process_t *out = &pids->ps;
249 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_PROCESS_IDX);
250 - ebpf_publish_process_t *in = local_pid->process;
251 - if (!in)
249 + netdata_ebpf_pid_stats_t *local_pid =
250 + netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_PROCESS_IDX);
251 + if (!local_pid)
252 continue;
253
254 + ebpf_publish_process_t *in = &local_pid->process;
255 +
256 memcpy(out, in, sizeof(ebpf_publish_process_t));
257 }
258 }
@@ -1233,6 +1235,123 @@ void ebpf_process_update_cgroup_algorithm()
1235 }
1236 }
1237
1238 +/**
1239 + * Process Accumulator
1240 + *
1241 + * Sum all values read from kernel and store in the first address.
1242 + *
1243 + * @param out the vector with read values.
1244 + * @param maps_per_core do I need to read all cores?
1245 + */
1246 +void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core)
1247 +{
1248 + int i, end = (maps_per_core) ? ebpf_nprocs : 1;
1249 + ebpf_process_stat_t *total = &out[0];
1250 + uint64_t ct = total->ct;
1251 + for (i = 1; i < end; i++) {
1252 + ebpf_process_stat_t *w = &out[i];
1253 + total->exit_call += w->exit_call;
1254 + total->task_err += w->task_err;
1255 + total->create_thread += w->create_thread;
1256 + total->create_process += w->create_process;
1257 + total->release_call += w->release_call;
1258 +
1259 + if (w->ct > ct)
1260 + ct = w->ct;
1261 + }
1262 + total->ct = ct;
1263 +}
1264 +
1265 +/**
1266 + * Sum values for pid
1267 + *
1268 + * @param structure to store result.
1269 + * @param root the structure with all available PIDs
1270 + */
1271 +void ebpf_process_sum_values_for_pids(ebpf_process_stat_t *process, struct ebpf_pid_on_target *root)
1272 +{
1273 + memset(process, 0, sizeof(ebpf_process_stat_t));
1274 + for (; root; root = root->next) {
1275 + uint32_t pid = root->pid;
1276 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_PROCESS_IDX);
1277 + if (!local_pid)
1278 + continue;
1279 +
1280 + ebpf_publish_process_t *in = &local_pid->process;
1281 +
1282 + process->task_err += in->task_err;
1283 + process->release_call += in->release_call;
1284 + process->exit_call += in->exit_call;
1285 + process->create_thread += in->create_thread;
1286 + process->create_process += in->create_process;
1287 + }
1288 +}
1289 +
1290 +/**
1291 + * Collect data for all process
1292 + *
1293 + * Read data from hash table and store it in appropriate vectors.
1294 + * It also creates the link between targets and PIDs.
1295 + *
1296 + * @param tbl_pid_stats_fd The mapped file descriptor for the hash table.
1297 + * @param maps_per_core do I have hash maps per core?
1298 + */
1299 +void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core)
1300 +{
1301 + if (tbl_pid_stats_fd == -1)
1302 + return;
1303 +
1304 + pids_fd[NETDATA_EBPF_PIDS_PROCESS_IDX] = tbl_pid_stats_fd;
1305 + size_t length = sizeof(ebpf_process_stat_t);
1306 + if (maps_per_core)
1307 + length *= ebpf_nprocs;
1308 +
1309 + if (tbl_pid_stats_fd != -1) {
1310 + uint32_t key = 0, next_key = 0;
1311 + while (bpf_map_get_next_key(tbl_pid_stats_fd, &key, &next_key) == 0) {
1312 + if (bpf_map_lookup_elem(tbl_pid_stats_fd, &key, process_stat_vector)) {
1313 + goto end_process_loop;
1314 + }
1315 +
1316 + ebpf_process_apps_accumulator(process_stat_vector, maps_per_core);
1317 +
1318 + netdata_ebpf_pid_stats_t *local_pid =
1319 + netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_PROCESS_IDX);
1320 + if (!local_pid)
1321 + continue;
1322 +
1323 + ebpf_publish_process_t *w = &local_pid->process;
1324 +
1325 + if (!w->ct || w->ct != process_stat_vector[0].ct) {
1326 + w->ct = process_stat_vector[0].ct;
1327 + w->create_thread = process_stat_vector[0].create_thread;
1328 + w->exit_call = process_stat_vector[0].exit_call;
1329 + w->create_thread = process_stat_vector[0].create_thread;
1330 + w->create_process = process_stat_vector[0].create_process;
1331 + w->release_call = process_stat_vector[0].release_call;
1332 + w->task_err = process_stat_vector[0].task_err;
1333 + } else {
1334 + if (kill((pid_t)key, 0)) { // No PID found
1335 + if (netdata_ebpf_reset_shm_pointer_unsafe(tbl_pid_stats_fd, key, NETDATA_EBPF_PIDS_CACHESTAT_IDX))
1336 + memset(w, 0, sizeof(*w));
1337 + }
1338 + }
1339 +
1340 + end_process_loop:
1341 + memset(process_stat_vector, 0, length);
1342 + key = next_key;
1343 + }
1344 + }
1345 +
1346 + struct ebpf_target *w;
1347 + for (w = apps_groups_root_target; w; w = w->next) {
1348 + if (unlikely(!(w->processes)))
1349 + continue;
1350 +
1351 + ebpf_process_sum_values_for_pids(&w->process, w->root_pid);
1352 + }
1353 +}
1354 +
1355 /**
1356 * Main loop for this collector.
1357 *
@@ -1257,6 +1376,7 @@ static void process_collector(ebpf_module_t *em)
1376 memset(stats, 0, sizeof(em->hash_table_stats));
1377 heartbeat_t hb;
1378 heartbeat_init(&hb, USEC_PER_SEC);
1379 + int process_maps_per_core = ebpf_modules[EBPF_MODULE_PROCESS_IDX].maps_per_core;
1380 while (!ebpf_plugin_stop() && running_time < lifetime) {
1381 heartbeat_next(&hb);
1382
@@ -1269,12 +1389,17 @@ static void process_collector(ebpf_module_t *em)
1389 ebpf_read_process_hash_global_tables(stats, maps_per_core);
1390
1391 netdata_apps_integration_flags_t apps_enabled = em->apps_charts;
1272 - pthread_mutex_lock(&collect_data_mutex);
1392
1393 if (ebpf_all_pids_count > 0) {
1394 + sem_wait(shm_mutex_ebpf_integration);
1395 + pthread_mutex_lock(&collect_data_mutex);
1396 + collect_data_for_all_processes(process_pid_fd, process_maps_per_core);
1397 +
1398 if (cgroups && shm_ebpf_cgroup.header) {
1399 ebpf_update_process_cgroup();
1400 }
1401 + pthread_mutex_unlock(&collect_data_mutex);
1402 + sem_post(shm_mutex_ebpf_integration);
1403 }
1404
1405 pthread_mutex_lock(&lock);
@@ -1283,6 +1408,7 @@ static void process_collector(ebpf_module_t *em)
1408 ebpf_process_send_data(em);
1409 }
1410
1411 + pthread_mutex_lock(&collect_data_mutex);
1412 if (apps_enabled & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) {
1413 ebpf_process_send_apps_data(apps_groups_root_target, em);
1414 }
@@ -1291,8 +1417,8 @@ static void process_collector(ebpf_module_t *em)
1417 ebpf_process_send_cgroup_data(em);
1418 }
1419
1294 - pthread_mutex_unlock(&lock);
1420 pthread_mutex_unlock(&collect_data_mutex);
1421 + pthread_mutex_unlock(&lock);
1422
1423 pthread_mutex_lock(&ebpf_exit_cleanup);
1424 if (running_time && !em->running_time)
src/collectors/ebpf.plugin/ebpf_process.h
+1
@@ -45,6 +45,7 @@
45 enum netdata_ebpf_stats_order {
46 NETDATA_EBPF_ORDER_STAT_THREADS = 140000,
47 NETDATA_EBPF_ORDER_PIDS,
48 + NETDATA_EBPF_ORDER_PIDS_IPC,
49 NETDATA_EBPF_ORDER_STAT_LIFE_TIME,
50 NETDATA_EBPF_ORDER_STAT_LOAD_METHOD,
51 NETDATA_EBPF_ORDER_STAT_KERNEL_MEMORY,
src/collectors/ebpf.plugin/ebpf_shm.c
+25 -25
@@ -553,13 +553,14 @@ static void ebpf_update_shm_cgroup()
553 for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
554 struct pid_on_target2 *pids;
555 for (pids = ect->pids; pids; pids = pids->next) {
556 - int pid = pids->pid;
556 + uint32_t pid = pids->pid;
557 netdata_publish_shm_t *out = &pids->shm;
558 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_SHM_IDX);
559 - netdata_publish_shm_t *in = local_pid->shm;
560 - if (!in)
558 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_SHM_IDX);
559 + if (!local_pid)
560 continue;
561
562 + netdata_publish_shm_t *in = &local_pid->shm;
563 +
564 memcpy(out, in, sizeof(netdata_publish_shm_t));
565 }
566 }
@@ -589,21 +590,17 @@ static void ebpf_read_shm_apps_table(int maps_per_core)
590
591 shm_apps_accumulator(cv, maps_per_core);
592
592 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, NETDATA_EBPF_PIDS_SHM_IDX);
593 - netdata_publish_shm_t *publish = local_pid->shm;
594 - if (!publish)
595 - local_pid->shm = publish = ebpf_shm_allocate_publish();
593 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_SHM_IDX);
594 + if (!local_pid)
595 + continue;
596 + netdata_publish_shm_t *publish = &local_pid->shm;
597
598 if (!publish->ct || publish->ct != cv->ct) {
599 memcpy(publish, &cv[0], sizeof(netdata_publish_shm_t));
599 - local_pid->not_updated = 0;
600 } else {
601 - if (kill(key, 0)) { // No PID found
602 - ebpf_reset_specific_pid_data(local_pid);
603 - } else { // There is PID, but there is not data anymore
604 - ebpf_release_pid_data(local_pid, fd, key, NETDATA_EBPF_PIDS_SHM_IDX);
605 - ebpf_shm_release_publish(publish);
606 - local_pid->shm = NULL;
601 + if (kill((pid_t)key, 0)) { // No PID found
602 + if (netdata_ebpf_reset_shm_pointer_unsafe(fd, key, NETDATA_EBPF_PIDS_SHM_IDX))
603 + memset(publish, 0, sizeof(*publish));
604 }
605 }
606
@@ -667,12 +664,13 @@ static void ebpf_shm_sum_pids(netdata_publish_shm_t *shm, struct ebpf_pid_on_tar
664 {
665 memset(shm, 0, sizeof(netdata_publish_shm_t));
666 for (; root; root = root->next) {
670 - int32_t pid = root->pid;
671 - ebpf_pid_data_t *pid_stat = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_SHM_IDX);
672 - netdata_publish_shm_t *w = pid_stat->shm;
673 - if (!w)
667 + uint32_t pid = root->pid;
668 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_SHM_IDX);
669 + if (!local_pid)
670 continue;
671
672 + netdata_publish_shm_t *w = &local_pid->shm;
673 +
674 shm->get += w->get;
675 shm->at += w->at;
676 shm->dt += w->dt;
@@ -1061,12 +1059,14 @@ void ebpf_shm_send_cgroup_data(int update_every)
1059 void ebpf_shm_resume_apps_data()
1060 {
1061 struct ebpf_target *w;
1062 + pthread_mutex_lock(&collect_data_mutex);
1063 for (w = apps_groups_root_target; w; w = w->next) {
1064 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_SHM_IDX))))
1065 continue;
1066
1067 ebpf_shm_sum_pids(&w->shm, w->root_pid);
1068 }
1069 + pthread_mutex_unlock(&collect_data_mutex);
1070 }
1071
1072 /**
@@ -1091,6 +1091,7 @@ void *ebpf_read_shm_thread(void *ptr)
1091 int counter = update_every - 1;
1092
1093 uint32_t lifetime = em->lifetime;
1094 + int cgroups = em->cgroup_charts;
1095 uint32_t running_time = 0;
1096 pids_fd[NETDATA_EBPF_PIDS_SHM_IDX] = shm_maps[NETDATA_PID_SHM_TABLE].map_fd;
1097 heartbeat_t hb;
@@ -1100,10 +1101,13 @@ void *ebpf_read_shm_thread(void *ptr)
1101 if (ebpf_plugin_stop() || ++counter != update_every)
1102 continue;
1103
1103 - pthread_mutex_lock(&collect_data_mutex);
1104 + sem_wait(shm_mutex_ebpf_integration);
1105 ebpf_read_shm_apps_table(maps_per_core);
1106 ebpf_shm_resume_apps_data();
1106 - pthread_mutex_unlock(&collect_data_mutex);
1107 + if (cgroups && shm_ebpf_cgroup.header)
1108 + ebpf_update_shm_cgroup();
1109 +
1110 + sem_post(shm_mutex_ebpf_integration);
1111
1112 counter = 0;
1113
@@ -1146,10 +1150,6 @@ static void shm_collector(ebpf_module_t *em)
1150 ebpf_shm_read_global_table(stats, maps_per_core);
1151 pthread_mutex_lock(&lock);
1152
1149 - if (cgroups && shm_ebpf_cgroup.header) {
1150 - ebpf_update_shm_cgroup();
1151 - }
1152 -
1153 shm_send_global();
1154
1155 if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) {
src/collectors/ebpf.plugin/ebpf_shm.h
-9
@@ -29,15 +29,6 @@
29 #define NETDATA_SYSTEMD_SHM_DT_CONTEXT "systemd.service.shmdt"
30 #define NETDATA_SYSTEMD_SHM_CTL_CONTEXT "systemd.service.shmctl"
31
32 -typedef struct __attribute__((packed)) netdata_publish_shm {
33 - uint64_t ct;
34 -
35 - uint32_t get;
36 - uint32_t at;
37 - uint32_t dt;
38 - uint32_t ctl;
39 -} netdata_publish_shm_t;
40 -
32 enum shm_tables { NETDATA_PID_SHM_TABLE, NETDATA_SHM_CONTROLLER, NETDATA_SHM_GLOBAL_TABLE };
33
34 enum shm_counters {
src/collectors/ebpf.plugin/ebpf_socket.c
+67 -60
@@ -1849,17 +1849,19 @@ static void ebpf_update_array_vectors(ebpf_module_t *em)
1849 rw_spinlock_write_unlock(&pid_ptr->socket_stats.rw_spinlock);
1850 rw_spinlock_write_unlock(&ebpf_judy_pid.index.rw_spinlock);
1851
1852 - end_socket_loop:; // the empty statement is here to allow code to be compiled by old compilers
1853 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key.pid, 0, values[0].name, EBPF_MODULE_SOCKET_IDX);
1854 - ebpf_socket_publish_apps_t *curr = local_pid->socket;
1855 - if (!curr)
1856 - local_pid->socket = curr = ebpf_socket_allocate_publish();
1852 + end_socket_loop: ;// the empty statement is here to allow code to be compiled by old compilers
1853 + netdata_ebpf_pid_stats_t *local_pid =
1854 + netdata_ebpf_get_shm_pointer_unsafe(key.pid, NETDATA_EBPF_PIDS_SOCKET_IDX);
1855 + if (!local_pid)
1856 + continue;
1857 + ebpf_socket_publish_apps_t *curr = &local_pid->socket;
1858
1859 if (!deleted)
1860 ebpf_socket_fill_publish_apps(curr, values);
1861 else {
1861 - ebpf_release_pid_data(local_pid, fd, key.pid, EBPF_MODULE_SOCKET_IDX);
1862 - ebpf_socket_release_publish(curr);
1862 + netdata_ebpf_reset_shm_pointer_unsafe(fd, key.pid, NETDATA_EBPF_PIDS_SOCKET_IDX);
1863 + memset(curr, 0, sizeof(*curr));
1864 + bpf_map_delete_elem(fd, &key);
1865 }
1866 memset(values, 0, length);
1867 memcpy(&key, &next_key, sizeof(key));
@@ -1872,6 +1874,7 @@ void ebpf_socket_resume_apps_data()
1874 {
1875 struct ebpf_target *w;
1876
1877 + pthread_mutex_lock(&collect_data_mutex);
1878 for (w = apps_groups_root_target; w; w = w->next) {
1879 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_SOCKET_IDX))))
1880 continue;
@@ -1881,12 +1884,14 @@ void ebpf_socket_resume_apps_data()
1884 ebpf_socket_publish_apps_t *values = &w->socket;
1885 memset(&w->socket, 0, sizeof(ebpf_socket_publish_apps_t));
1886 for (; move; move = move->next) {
1884 - int32_t pid = move->pid;
1885 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_SOCKET_IDX);
1886 - ebpf_socket_publish_apps_t *ws = local_pid->socket;
1887 - if (!ws)
1887 + uint32_t pid = move->pid;
1888 + netdata_ebpf_pid_stats_t *local_pid =
1889 + netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_SOCKET_IDX);
1890 + if (!local_pid)
1891 continue;
1892
1893 + ebpf_socket_publish_apps_t *ws = &local_pid->socket;
1894 +
1895 values->call_tcp_v4_connection = ws->call_tcp_v4_connection;
1896 values->call_tcp_v6_connection = ws->call_tcp_v6_connection;
1897 values->bytes_sent = ws->bytes_sent;
@@ -1898,6 +1903,44 @@ void ebpf_socket_resume_apps_data()
1903 values->call_udp_received = ws->call_udp_received;
1904 }
1905 }
1906 + pthread_mutex_unlock(&collect_data_mutex);
1907 +}
1908 +
1909 +/**
1910 + * Update cgroup
1911 + *
1912 + * Update cgroup data based in PIDs.
1913 + */
1914 +static void ebpf_update_socket_cgroup()
1915 +{
1916 + ebpf_cgroup_target_t *ect;
1917 +
1918 + pthread_mutex_lock(&mutex_cgroup_shm);
1919 + for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
1920 + struct pid_on_target2 *pids;
1921 + for (pids = ect->pids; pids; pids = pids->next) {
1922 + uint32_t pid = pids->pid;
1923 + ebpf_socket_publish_apps_t *publish = &ect->publish_socket;
1924 + netdata_ebpf_pid_stats_t *local_pid =
1925 + netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_SOCKET_IDX);
1926 + if (!local_pid)
1927 + continue;
1928 +
1929 + ebpf_socket_publish_apps_t *in = &local_pid->socket;
1930 +
1931 + publish->bytes_sent = in->bytes_sent;
1932 + publish->bytes_received = in->bytes_received;
1933 + publish->call_tcp_sent = in->call_tcp_sent;
1934 + publish->call_tcp_received = in->call_tcp_received;
1935 + publish->retransmit = in->retransmit;
1936 + publish->call_udp_sent = in->call_udp_sent;
1937 + publish->call_udp_received = in->call_udp_received;
1938 + publish->call_close = in->call_close;
1939 + publish->call_tcp_v4_connection = in->call_tcp_v4_connection;
1940 + publish->call_tcp_v6_connection = in->call_tcp_v6_connection;
1941 + }
1942 + }
1943 + pthread_mutex_unlock(&mutex_cgroup_shm);
1944 }
1945
1946 /**
@@ -1923,6 +1966,7 @@ void *ebpf_read_socket_thread(void *ptr)
1966
1967 uint32_t running_time = 0;
1968 uint32_t lifetime = em->lifetime;
1969 + int cgroups = em->cgroup_charts;
1970 heartbeat_t hb;
1971 heartbeat_init(&hb, update_every * USEC_PER_SEC);
1972 while (!ebpf_plugin_stop() && running_time < lifetime) {
@@ -1930,10 +1974,13 @@ void *ebpf_read_socket_thread(void *ptr)
1974 if (ebpf_plugin_stop() || ++counter != update_every)
1975 continue;
1976
1933 - pthread_mutex_lock(&collect_data_mutex);
1977 + sem_wait(shm_mutex_ebpf_integration);
1978 ebpf_update_array_vectors(em);
1979 ebpf_socket_resume_apps_data();
1936 - pthread_mutex_unlock(&collect_data_mutex);
1980 + if (cgroups && shm_ebpf_cgroup.header)
1981 + ebpf_update_socket_cgroup();
1982 +
1983 + sem_post(shm_mutex_ebpf_integration);
1984
1985 counter = 0;
1986 }
@@ -2101,40 +2148,6 @@ void ebpf_socket_fill_publish_apps(ebpf_socket_publish_apps_t *curr, netdata_soc
2148 curr->call_udp_received = ns->udp.call_udp_received;
2149 }
2150
2104 -/**
2105 - * Update cgroup
2106 - *
2107 - * Update cgroup data based in PIDs.
2108 - */
2109 -static void ebpf_update_socket_cgroup()
2110 -{
2111 - ebpf_cgroup_target_t *ect;
2112 -
2113 - pthread_mutex_lock(&mutex_cgroup_shm);
2114 - for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
2115 - struct pid_on_target2 *pids;
2116 - for (pids = ect->pids; pids; pids = pids->next) {
2117 - int pid = pids->pid;
2118 - ebpf_socket_publish_apps_t *publish = &ect->publish_socket;
2119 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, EBPF_MODULE_SOCKET_IDX);
2120 - ebpf_socket_publish_apps_t *in = local_pid->socket;
2121 - if (!in)
2122 - continue;
2123 -
2124 - publish->bytes_sent = in->bytes_sent;
2125 - publish->bytes_received = in->bytes_received;
2126 - publish->call_tcp_sent = in->call_tcp_sent;
2127 - publish->call_tcp_received = in->call_tcp_received;
2128 - publish->retransmit = in->retransmit;
2129 - publish->call_udp_sent = in->call_udp_sent;
2130 - publish->call_udp_received = in->call_udp_received;
2131 - publish->call_close = in->call_close;
2132 - publish->call_tcp_v4_connection = in->call_tcp_v4_connection;
2133 - publish->call_tcp_v6_connection = in->call_tcp_v6_connection;
2134 - }
2135 - }
2136 - pthread_mutex_unlock(&mutex_cgroup_shm);
2137 -}
2151
2152 /**
2153 * Sum PIDs
@@ -2779,9 +2792,6 @@ static void socket_collector(ebpf_module_t *em)
2792 ebpf_socket_read_hash_global_tables(stats, maps_per_core);
2793 }
2794
2782 - if (cgroups && shm_ebpf_cgroup.header)
2783 - ebpf_update_socket_cgroup();
2784 -
2795 pthread_mutex_lock(&lock);
2796 if (socket_global_enabled)
2797 ebpf_socket_send_data(em);
@@ -2931,14 +2941,11 @@ void ebpf_parse_service_name_section(struct config *cfg)
2941 */
2942 void parse_table_size_options(struct config *cfg)
2943 {
2934 - socket_maps[NETDATA_SOCKET_OPEN_SOCKET].user_input = (uint32_t) inicfg_get_number(cfg,
2935 - EBPF_GLOBAL_SECTION,
2936 - EBPF_CONFIG_SOCKET_MONITORING_SIZE,
2937 - NETDATA_MAXIMUM_CONNECTIONS_ALLOWED);
2938 -
2939 - socket_maps[NETDATA_SOCKET_TABLE_UDP].user_input = (uint32_t) inicfg_get_number(cfg,
2940 - EBPF_GLOBAL_SECTION,
2941 - EBPF_CONFIG_UDP_SIZE, NETDATA_MAXIMUM_UDP_CONNECTIONS_ALLOWED);
2944 + socket_maps[NETDATA_SOCKET_OPEN_SOCKET].user_input = (uint32_t)inicfg_get_number(
2945 + cfg, EBPF_GLOBAL_SECTION, EBPF_CONFIG_SOCKET_MONITORING_SIZE, NETDATA_MAXIMUM_CONNECTIONS_ALLOWED);
2946 +
2947 + socket_maps[NETDATA_SOCKET_TABLE_UDP].user_input = (uint32_t)inicfg_get_number(
2948 + cfg, EBPF_GLOBAL_SECTION, EBPF_CONFIG_UDP_SIZE, NETDATA_MAXIMUM_UDP_CONNECTIONS_ALLOWED);
2949 }
2950
2951 /*
@@ -3005,8 +3012,8 @@ void *ebpf_socket_thread(void *ptr)
3012 rw_spinlock_write_lock(&network_viewer_opt.rw_spinlock);
3013 // It was not enabled from main config file (ebpf.d.conf)
3014 if (!network_viewer_opt.enabled)
3008 - network_viewer_opt.enabled = inicfg_get_boolean(&socket_config, EBPF_NETWORK_VIEWER_SECTION, "enabled",
3009 - CONFIG_BOOLEAN_YES);
3015 + network_viewer_opt.enabled =
3016 + inicfg_get_boolean(&socket_config, EBPF_NETWORK_VIEWER_SECTION, "enabled", CONFIG_BOOLEAN_YES);
3017
3018 rw_spinlock_write_unlock(&network_viewer_opt.rw_spinlock);
3019
src/collectors/ebpf.plugin/ebpf_socket.h
-14
@@ -158,20 +158,6 @@ typedef enum ebpf_socket_idx {
158 #define NETDATA_EBPF_PID_SOCKET_ARAL_TABLE_NAME "ebpf_pid_socket"
159 #define NETDATA_EBPF_SOCKET_ARAL_TABLE_NAME "ebpf_socket_tbl"
160
161 -typedef struct __attribute__((packed)) ebpf_socket_publish_apps {
162 - // Data read
163 - uint64_t bytes_sent; // Bytes sent
164 - uint64_t bytes_received; // Bytes received
165 - uint64_t call_tcp_sent; // Number of times tcp_sendmsg was called
166 - uint64_t call_tcp_received; // Number of times tcp_cleanup_rbuf was called
167 - uint64_t retransmit; // Number of times tcp_retransmit was called
168 - uint64_t call_udp_sent; // Number of times udp_sendmsg was called
169 - uint64_t call_udp_received; // Number of times udp_recvmsg was called
170 - uint64_t call_close; // Number of times tcp_close was called
171 - uint64_t call_tcp_v4_connection; // Number of times tcp_v4_connect was called
172 - uint64_t call_tcp_v6_connection; // Number of times tcp_v6_connect was called
173 -} ebpf_socket_publish_apps_t;
174 -
161 typedef struct ebpf_network_viewer_dimension_names {
162 char *name;
163 uint32_t hash;
src/collectors/ebpf.plugin/ebpf_swap.c
+24 -24
@@ -484,12 +484,13 @@ static void ebpf_update_swap_cgroup()
484 for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
485 struct pid_on_target2 *pids;
486 for (pids = ect->pids; pids; pids = pids->next) {
487 - int pid = pids->pid;
487 + uint32_t pid = pids->pid;
488 netdata_publish_swap_t *out = &pids->swap;
489 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_SWAP_IDX);
490 - netdata_publish_swap_t *in = local_pid->swap;
491 - if (!in)
489 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_SWAP_IDX);
490 + if (!local_pid)
491 continue;
492 + netdata_publish_swap_t *in = &local_pid->swap;
493 +
494 memcpy(out, in, sizeof(netdata_publish_swap_t));
495 }
496 }
@@ -510,11 +511,11 @@ static void ebpf_swap_sum_pids(netdata_publish_swap_t *swap, struct ebpf_pid_on_
511 uint64_t local_write = 0;
512
513 for (; root; root = root->next) {
513 - int32_t pid = root->pid;
514 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_SWAP_IDX);
515 - netdata_publish_swap_t *w = local_pid->swap;
516 - if (!w)
514 + uint32_t pid = root->pid;
515 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_SWAP_IDX);
516 + if (!local_pid)
517 continue;
518 + netdata_publish_swap_t *w = &local_pid->swap;
519
520 local_write += w->write;
521 local_read += w->read;
@@ -531,12 +532,14 @@ static void ebpf_swap_sum_pids(netdata_publish_swap_t *swap, struct ebpf_pid_on_
532 void ebpf_swap_resume_apps_data()
533 {
534 struct ebpf_target *w;
535 + pthread_mutex_lock(&collect_data_mutex);
536 for (w = apps_groups_root_target; w; w = w->next) {
537 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_SWAP_IDX))))
538 continue;
539
540 ebpf_swap_sum_pids(&w->swap, w->root_pid);
541 }
542 + pthread_mutex_unlock(&collect_data_mutex);
543 }
544
545 /**
@@ -562,21 +565,17 @@ static void ebpf_read_swap_apps_table(int maps_per_core)
565
566 swap_apps_accumulator(cv, maps_per_core);
567
565 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, cv->tgid, cv->name, NETDATA_EBPF_PIDS_SWAP_IDX);
566 - netdata_publish_swap_t *publish = local_pid->swap;
567 - if (!publish)
568 - local_pid->swap = publish = ebpf_swap_allocate_publish_swap();
568 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_SWAP_IDX);
569 + if (!local_pid)
570 + continue;
571 + netdata_publish_swap_t *publish = &local_pid->swap;
572
573 if (!publish->ct || publish->ct != cv->ct) {
574 memcpy(publish, cv, sizeof(netdata_publish_swap_t));
572 - local_pid->not_updated = 0;
575 } else {
574 - if (kill(key, 0)) { // No PID found
575 - ebpf_reset_specific_pid_data(local_pid);
576 - } else { // There is PID, but there is not data anymore
577 - ebpf_release_pid_data(local_pid, fd, key, NETDATA_EBPF_PIDS_SWAP_IDX);
578 - ebpf_swap_release_publish(publish);
579 - local_pid->swap = NULL;
576 + if (kill((pid_t)key, 0)) { // No PID found
577 + if (netdata_ebpf_reset_shm_pointer_unsafe(fd, key, NETDATA_EBPF_PIDS_SWAP_IDX))
578 + memset(publish, 0, sizeof(*publish));
579 }
580 }
581
@@ -610,6 +609,7 @@ void *ebpf_read_swap_thread(void *ptr)
609
610 uint32_t lifetime = em->lifetime;
611 uint32_t running_time = 0;
612 + int cgroups = em->cgroup_charts;
613 pids_fd[NETDATA_EBPF_PIDS_SWAP_IDX] = swap_maps[NETDATA_PID_SWAP_TABLE].map_fd;
614
615 heartbeat_t hb;
@@ -619,10 +619,13 @@ void *ebpf_read_swap_thread(void *ptr)
619 if (ebpf_plugin_stop() || ++counter != update_every)
620 continue;
621
622 - pthread_mutex_lock(&collect_data_mutex);
622 + sem_wait(shm_mutex_ebpf_integration);
623 ebpf_read_swap_apps_table(maps_per_core);
624 ebpf_swap_resume_apps_data();
625 - pthread_mutex_unlock(&collect_data_mutex);
625 + if (cgroups && shm_ebpf_cgroup.header)
626 + ebpf_update_swap_cgroup();
627 +
628 + sem_post(shm_mutex_ebpf_integration);
629
630 counter = 0;
631
@@ -975,9 +978,6 @@ static void swap_collector(ebpf_module_t *em)
978 netdata_apps_integration_flags_t apps = em->apps_charts;
979 ebpf_swap_read_global_table(stats, maps_per_core);
980
978 - if (cgroup && shm_ebpf_cgroup.header)
979 - ebpf_update_swap_cgroup();
980 -
981 pthread_mutex_lock(&lock);
982
983 swap_send_global();
src/collectors/ebpf.plugin/ebpf_swap.h
-7
@@ -24,13 +24,6 @@
24 #define NETDATA_SYSTEMD_SWAP_READ_CONTEXT "systemd.service.swap_read"
25 #define NETDATA_SYSTEMD_SWAP_WRITE_CONTEXT "systemd.service.swap_write"
26
27 -typedef struct __attribute__((packed)) netdata_publish_swap {
28 - uint64_t ct;
29 -
30 - uint32_t read;
31 - uint32_t write;
32 -} netdata_publish_swap_t;
33 -
27 enum swap_tables { NETDATA_PID_SWAP_TABLE, NETDATA_SWAP_CONTROLLER, NETDATA_SWAP_GLOBAL_TABLE };
28
29 enum swap_counters {
src/collectors/ebpf.plugin/ebpf_vfs.c
+27 -28
@@ -1166,12 +1166,13 @@ static void ebpf_vfs_sum_pids(netdata_publish_vfs_t *vfs, struct ebpf_pid_on_tar
1166 memset(vfs, 0, sizeof(netdata_publish_vfs_t));
1167
1168 for (; root; root = root->next) {
1169 - int32_t pid = root->pid;
1170 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_VFS_IDX);
1171 - netdata_publish_vfs_t *w = local_pid->vfs;
1172 - if (!w)
1169 + uint32_t pid = root->pid;
1170 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_VFS_IDX);
1171 + if (!local_pid)
1172 continue;
1173
1174 + netdata_publish_vfs_t *w = &local_pid->vfs;
1175 +
1176 vfs_aggregate_publish_vfs(vfs, w);
1177 }
1178 }
@@ -1298,7 +1299,7 @@ static void vfs_apps_accumulator(netdata_ebpf_vfs_t *out, int maps_per_core)
1299 /**
1300 * Read the hash table and store data to allocated vectors.
1301 */
1301 -static void ebpf_vfs_read_apps(int maps_per_core, uint32_t max_period)
1302 +static void ebpf_vfs_read_apps(int maps_per_core)
1303 {
1304 netdata_ebpf_vfs_t *vv = vfs_vector;
1305 int fd = vfs_maps[NETDATA_VFS_PID].map_fd;
@@ -1314,21 +1315,17 @@ static void ebpf_vfs_read_apps(int maps_per_core, uint32_t max_period)
1315
1316 vfs_apps_accumulator(vv, maps_per_core);
1317
1317 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(key, vv->tgid, vv->name, NETDATA_EBPF_PIDS_VFS_IDX);
1318 - netdata_publish_vfs_t *publish = local_pid->vfs;
1319 - if (!publish)
1320 - local_pid->vfs = publish = ebpf_vfs_allocate_publish();
1318 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(key, NETDATA_EBPF_PIDS_VFS_IDX);
1319 + if (!local_pid)
1320 + continue;
1321 + netdata_publish_vfs_t *publish = &local_pid->vfs;
1322
1323 if (!publish->ct || publish->ct != vv->ct) {
1324 vfs_aggregate_set_vfs(publish, vv);
1324 - local_pid->not_updated = 0;
1325 - } else if (++local_pid->not_updated >= max_period) {
1326 - if (kill(key, 0)) { // No PID found
1327 - ebpf_reset_specific_pid_data(local_pid);
1328 - } else { // There is PID, but there is not data anymore
1329 - ebpf_release_pid_data(local_pid, fd, key, NETDATA_EBPF_PIDS_VFS_IDX);
1330 - ebpf_vfs_release_publish(publish);
1331 - local_pid->vfs = NULL;
1325 + } else {
1326 + if (kill((pid_t)key, 0)) { // No PID found
1327 + if (netdata_ebpf_reset_shm_pointer_unsafe(fd, key, NETDATA_EBPF_PIDS_VFS_IDX))
1328 + memset(publish, 0, sizeof(*publish));
1329 }
1330 }
1331
@@ -1353,14 +1350,14 @@ static void read_update_vfs_cgroup()
1350 for (ect = ebpf_cgroup_pids; ect; ect = ect->next) {
1351 struct pid_on_target2 *pids;
1352 for (pids = ect->pids; pids; pids = pids->next) {
1356 - int pid = pids->pid;
1353 + uint32_t pid = pids->pid;
1354 netdata_publish_vfs_t *out = &pids->vfs;
1355 memset(out, 0, sizeof(netdata_publish_vfs_t));
1356
1360 - ebpf_pid_data_t *local_pid = ebpf_get_pid_data(pid, 0, NULL, NETDATA_EBPF_PIDS_VFS_IDX);
1361 - netdata_publish_vfs_t *in = local_pid->vfs;
1362 - if (!in)
1357 + netdata_ebpf_pid_stats_t *local_pid = netdata_ebpf_get_shm_pointer_unsafe(pid, NETDATA_EBPF_PIDS_VFS_IDX);
1358 + if (!local_pid)
1359 continue;
1360 + netdata_publish_vfs_t *in = &local_pid->vfs;
1361
1362 vfs_aggregate_publish_vfs(out, in);
1363 }
@@ -2288,12 +2285,14 @@ static void ebpf_vfs_send_cgroup_data(ebpf_module_t *em)
2285 void ebpf_vfs_resume_apps_data()
2286 {
2287 struct ebpf_target *w;
2288 + pthread_mutex_lock(&collect_data_mutex);
2289 for (w = apps_groups_root_target; w; w = w->next) {
2290 if (unlikely(!(w->charts_created & (1 << EBPF_MODULE_VFS_IDX))))
2291 continue;
2292
2293 ebpf_vfs_sum_pids(&w->vfs, w->root_pid);
2294 }
2295 + pthread_mutex_unlock(&collect_data_mutex);
2296 }
2297
2298 /**
@@ -2318,8 +2317,8 @@ void *ebpf_read_vfs_thread(void *ptr)
2317 int counter = update_every - 1;
2318
2319 uint32_t lifetime = em->lifetime;
2320 + int cgroups = em->cgroup_charts;
2321 uint32_t running_time = 0;
2322 - uint32_t max_period = EBPF_CLEANUP_FACTOR;
2322 pids_fd[NETDATA_EBPF_PIDS_VFS_IDX] = vfs_maps[NETDATA_VFS_PID].map_fd;
2323 heartbeat_t hb;
2324 heartbeat_init(&hb, update_every * USEC_PER_SEC);
@@ -2328,10 +2327,13 @@ void *ebpf_read_vfs_thread(void *ptr)
2327 if (ebpf_plugin_stop() || ++counter != update_every)
2328 continue;
2329
2331 - pthread_mutex_lock(&collect_data_mutex);
2332 - ebpf_vfs_read_apps(maps_per_core, max_period);
2330 + sem_wait(shm_mutex_ebpf_integration);
2331 + ebpf_vfs_read_apps(maps_per_core);
2332 ebpf_vfs_resume_apps_data();
2334 - pthread_mutex_unlock(&collect_data_mutex);
2333 + if (cgroups && shm_ebpf_cgroup.header)
2334 + read_update_vfs_cgroup();
2335 +
2336 + sem_post(shm_mutex_ebpf_integration);
2337
2338 counter = 0;
2339
@@ -2375,9 +2377,6 @@ static void vfs_collector(ebpf_module_t *em)
2377 netdata_apps_integration_flags_t apps = em->apps_charts;
2378 ebpf_vfs_read_global_table(stats, maps_per_core);
2379
2378 - if (cgroups && shm_ebpf_cgroup.header)
2379 - read_update_vfs_cgroup();
2380 -
2380 pthread_mutex_lock(&lock);
2381
2382 ebpf_vfs_send_data(em);
src/collectors/ebpf.plugin/ebpf_vfs.h
-31
@@ -76,37 +76,6 @@
76 // dimension
77 #define EBPF_COMMON_UNITS_BYTES "bytes/s"
78
79 -typedef struct __attribute__((packed)) netdata_publish_vfs {
80 - uint64_t ct;
81 -
82 - //Counter
83 - uint32_t write_call;
84 - uint32_t writev_call;
85 - uint32_t read_call;
86 - uint32_t readv_call;
87 - uint32_t unlink_call;
88 - uint32_t fsync_call;
89 - uint32_t open_call;
90 - uint32_t create_call;
91 -
92 - //Accumulator
93 - uint64_t write_bytes;
94 - uint64_t writev_bytes;
95 - uint64_t readv_bytes;
96 - uint64_t read_bytes;
97 -
98 - //Counter
99 - uint32_t write_err;
100 - uint32_t writev_err;
101 - uint32_t read_err;
102 - uint32_t readv_err;
103 - uint32_t unlink_err;
104 - uint32_t fsync_err;
105 - uint32_t open_err;
106 - uint32_t create_err;
107 -
108 -} netdata_publish_vfs_t;
109 -
79 enum netdata_publish_vfs_list {
80 NETDATA_KEY_PUBLISH_VFS_UNLINK,
81 NETDATA_KEY_PUBLISH_VFS_READ,
src/collectors/ebpf.plugin/metadata.yaml
+6
@@ -3292,3 +3292,9 @@ modules:
3292 chart_type: line
3293 dimensions:
3294 - name: thread
3295 + - name: netdata.ebpf_ipc_usage
3296 + description: IPC used array positions
3297 + unit: "%"
3298 + chart_type: line
3299 + dimensions:
3300 + - name: positions