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