summaryrefslogtreecommitdiffstats
path: root/collectors/ebpf.plugin/ebpf_process.c
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/ebpf.plugin/ebpf_process.c')
-rw-r--r--collectors/ebpf.plugin/ebpf_process.c223
1 files changed, 109 insertions, 114 deletions
diff --git a/collectors/ebpf.plugin/ebpf_process.c b/collectors/ebpf.plugin/ebpf_process.c
index f894f070..f6b379a5 100644
--- a/collectors/ebpf.plugin/ebpf_process.c
+++ b/collectors/ebpf.plugin/ebpf_process.c
@@ -47,9 +47,6 @@ ebpf_process_publish_apps_t **current_apps_data = NULL;
int process_enabled = 0;
-static struct bpf_object *objects = NULL;
-static struct bpf_link **probe_links = NULL;
-
struct config process_config = { .first_section = NULL,
.last_section = NULL,
.mutex = NETDATA_MUTEX_INITIALIZER,
@@ -58,6 +55,7 @@ struct config process_config = { .first_section = NULL,
static struct netdata_static_thread cgroup_thread = {"EBPF CGROUP", NULL, NULL,
1, NULL, NULL, NULL};
+static enum ebpf_threads_status ebpf_process_exited = NETDATA_THREAD_EBPF_RUNNING;
static char *threads_stat[NETDATA_EBPF_THREAD_STAT_END] = {"total", "running"};
static char *load_event_stat[NETDATA_EBPF_LOAD_STAT_END] = {"legacy", "co-re"};
@@ -177,11 +175,9 @@ void ebpf_process_remove_pids()
uint32_t pid = pids->pid;
ebpf_process_stat_t *w = global_process_stats[pid];
if (w) {
- if (w->removeme) {
- freez(w);
- global_process_stats[pid] = NULL;
- bpf_map_delete_elem(pid_fd, &pid);
- }
+ freez(w);
+ global_process_stats[pid] = NULL;
+ bpf_map_delete_elem(pid_fd, &pid);
}
pids = pids->next;
@@ -568,6 +564,8 @@ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr)
root,
em->update_every, NETDATA_EBPF_MODULE_NAME_PROCESS);
}
+
+ em->apps_charts |= NETDATA_EBPF_APPS_FLAG_CHART_CREATED;
}
/**
@@ -624,6 +622,72 @@ static void ebpf_create_apps_charts(struct target *root)
/*****************************************************************
*
+ * FUNCTIONS TO CLOSE THE THREAD
+ *
+ *****************************************************************/
+
+/**
+ * Process disable tracepoints
+ *
+ * Disable tracepoints when the plugin was responsible to enable it.
+ */
+static void ebpf_process_disable_tracepoints()
+{
+ char *default_message = { "Cannot disable the tracepoint" };
+ if (!was_sched_process_exit_enabled) {
+ if (ebpf_disable_tracing_values(tracepoint_sched_type, tracepoint_sched_process_exit))
+ error("%s %s/%s.", default_message, tracepoint_sched_type, tracepoint_sched_process_exit);
+ }
+
+ if (!was_sched_process_exec_enabled) {
+ if (ebpf_disable_tracing_values(tracepoint_sched_type, tracepoint_sched_process_exec))
+ error("%s %s/%s.", default_message, tracepoint_sched_type, tracepoint_sched_process_exec);
+ }
+
+ if (!was_sched_process_fork_enabled) {
+ if (ebpf_disable_tracing_values(tracepoint_sched_type, tracepoint_sched_process_fork))
+ error("%s %s/%s.", default_message, tracepoint_sched_type, tracepoint_sched_process_fork);
+ }
+}
+
+/**
+ * Process Exit
+ *
+ * Cancel child thread.
+ *
+ * @param ptr thread data.
+ */
+static void ebpf_process_exit(void *ptr)
+{
+ (void)ptr;
+ ebpf_process_exited = NETDATA_THREAD_EBPF_STOPPING;
+}
+
+/**
+ * Process cleanup
+ *
+ * Cleanup allocated memory.
+ *
+ * @param ptr thread data.
+ */
+static void ebpf_process_cleanup(void *ptr)
+{
+ ebpf_module_t *em = (ebpf_module_t *)ptr;
+ if (ebpf_process_exited != NETDATA_THREAD_EBPF_STOPPED)
+ return;
+
+ ebpf_cleanup_publish_syscall(process_publish_aggregated);
+ freez(process_hash_values);
+ freez(cgroup_thread.thread);
+
+ ebpf_process_disable_tracepoints();
+
+ cgroup_thread.enabled = NETDATA_MAIN_THREAD_EXITED;
+ em->enabled = NETDATA_MAIN_THREAD_EXITED;
+}
+
+/*****************************************************************
+ *
* FUNCTIONS WITH THE MAIN LOOP
*
*****************************************************************/
@@ -640,24 +704,33 @@ static void ebpf_create_apps_charts(struct target *root)
*/
void *ebpf_cgroup_update_shm(void *ptr)
{
- UNUSED(ptr);
+ netdata_thread_cleanup_push(ebpf_process_cleanup, ptr);
heartbeat_t hb;
heartbeat_init(&hb);
- usec_t step = 30 * USEC_PER_SEC;
- while (!close_ebpf_plugin) {
+ usec_t step = 3 * USEC_PER_SEC;
+ int counter = NETDATA_EBPF_CGROUP_UPDATE - 1;
+ //This will be cancelled by its parent
+ while (ebpf_process_exited == NETDATA_THREAD_EBPF_RUNNING) {
usec_t dt = heartbeat_next(&hb, step);
(void)dt;
-
- if (close_ebpf_plugin)
+ if (ebpf_process_exited == NETDATA_THREAD_EBPF_STOPPING)
break;
- if (!shm_ebpf_cgroup.header)
- ebpf_map_cgroup_shared_memory();
+ // We are using a small heartbeat time to wake up thread,
+ // but we should not update so frequently the shared memory data
+ if (++counter >= NETDATA_EBPF_CGROUP_UPDATE) {
+ counter = 0;
+ if (!shm_ebpf_cgroup.header)
+ ebpf_map_cgroup_shared_memory();
- ebpf_parse_cgroup_shm_data();
+ ebpf_parse_cgroup_shm_data();
+ }
}
+ ebpf_process_exited = NETDATA_THREAD_EBPF_STOPPED;
+
+ netdata_thread_cleanup_pop(1);
return NULL;
}
@@ -884,7 +957,7 @@ static int ebpf_send_systemd_process_charts(ebpf_module_t *em)
for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) {
if (unlikely(ect->systemd) && unlikely(ect->updated)) {
write_chart_dimension(ect->name, ect->publish_systemd_ps.create_process);
- } else
+ } else if (unlikely(ect->systemd))
ret = 0;
}
write_end_chart();
@@ -1019,32 +1092,36 @@ static void process_collector(ebpf_module_t *em)
cgroup_thread.thread = mallocz(sizeof(netdata_thread_t));
cgroup_thread.start_routine = ebpf_cgroup_update_shm;
- netdata_thread_create(cgroup_thread.thread, cgroup_thread.name, NETDATA_THREAD_OPTION_JOINABLE,
+ netdata_thread_create(cgroup_thread.thread, cgroup_thread.name, NETDATA_THREAD_OPTION_DEFAULT,
ebpf_cgroup_update_shm, em);
heartbeat_t hb;
heartbeat_init(&hb);
int publish_global = em->global_charts;
- int apps_enabled = em->apps_charts;
int cgroups = em->cgroup_charts;
int thread_enabled = em->enabled;
if (cgroups)
ebpf_process_update_cgroup_algorithm();
+ int update_apps_every = (int) EBPF_CFG_UPDATE_APPS_EVERY_DEFAULT;
int pid_fd = process_maps[NETDATA_PROCESS_PID_TABLE].map_fd;
int update_every = em->update_every;
int counter = update_every - 1;
- while (!close_ebpf_plugin) {
+ int update_apps_list = update_apps_every - 1;
+ while (!ebpf_exit_plugin) {
usec_t dt = heartbeat_next(&hb, USEC_PER_SEC);
(void)dt;
+ if (ebpf_exit_plugin)
+ break;
pthread_mutex_lock(&collect_data_mutex);
- cleanup_exited_pids();
- collect_data_for_all_processes(pid_fd);
+ if (++update_apps_list == update_apps_every) {
+ update_apps_list = 0;
+ cleanup_exited_pids();
+ collect_data_for_all_processes(pid_fd);
- ebpf_create_apps_charts(apps_groups_root_target);
-
- pthread_cond_broadcast(&collect_data_cond_var);
+ ebpf_create_apps_charts(apps_groups_root_target);
+ }
pthread_mutex_unlock(&collect_data_mutex);
if (++counter == update_every) {
@@ -1052,10 +1129,10 @@ static void process_collector(ebpf_module_t *em)
read_hash_global_tables();
- int publish_apps = 0;
+ netdata_apps_integration_flags_t apps_enabled = em->apps_charts;
+ pthread_mutex_lock(&collect_data_mutex);
if (all_pids_count > 0) {
if (apps_enabled) {
- publish_apps = 1;
ebpf_process_update_apps_data();
}
@@ -1072,7 +1149,7 @@ static void process_collector(ebpf_module_t *em)
ebpf_process_send_data(em);
}
- if (publish_apps) {
+ if (apps_enabled & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) {
ebpf_process_send_apps_data(apps_groups_root_target, em);
}
@@ -1081,6 +1158,7 @@ static void process_collector(ebpf_module_t *em)
}
}
pthread_mutex_unlock(&lock);
+ pthread_mutex_unlock(&collect_data_mutex);
}
fflush(stdout);
@@ -1089,89 +1167,6 @@ static void process_collector(ebpf_module_t *em)
/*****************************************************************
*
- * FUNCTIONS TO CLOSE THE THREAD
- *
- *****************************************************************/
-
-void clean_global_memory() {
- int pid_fd = process_maps[NETDATA_PROCESS_PID_TABLE].map_fd;
- struct pid_stat *pids = root_of_pids;
- while (pids) {
- uint32_t pid = pids->pid;
- freez(global_process_stats[pid]);
-
- bpf_map_delete_elem(pid_fd, &pid);
- freez(current_apps_data[pid]);
-
- pids = pids->next;
- }
-}
-
-/**
- * Process disable tracepoints
- *
- * Disable tracepoints when the plugin was responsible to enable it.
- */
-static void ebpf_process_disable_tracepoints()
-{
- char *default_message = { "Cannot disable the tracepoint" };
- if (!was_sched_process_exit_enabled) {
- if (ebpf_disable_tracing_values(tracepoint_sched_type, tracepoint_sched_process_exit))
- error("%s %s/%s.", default_message, tracepoint_sched_type, tracepoint_sched_process_exit);
- }
-
- if (!was_sched_process_exec_enabled) {
- if (ebpf_disable_tracing_values(tracepoint_sched_type, tracepoint_sched_process_exec))
- error("%s %s/%s.", default_message, tracepoint_sched_type, tracepoint_sched_process_exec);
- }
-
- if (!was_sched_process_fork_enabled) {
- if (ebpf_disable_tracing_values(tracepoint_sched_type, tracepoint_sched_process_fork))
- error("%s %s/%s.", default_message, tracepoint_sched_type, tracepoint_sched_process_fork);
- }
-}
-
-/**
- * Clean up the main thread.
- *
- * @param ptr thread data.
- */
-static void ebpf_process_cleanup(void *ptr)
-{
- UNUSED(ptr);
-
- heartbeat_t hb;
- heartbeat_init(&hb);
- uint32_t tick = 1 * USEC_PER_SEC;
- while (!finalized_threads) {
- usec_t dt = heartbeat_next(&hb, tick);
- UNUSED(dt);
- }
-
- ebpf_cleanup_publish_syscall(process_publish_aggregated);
- freez(process_hash_values);
-
- clean_global_memory();
- freez(global_process_stats);
- freez(current_apps_data);
-
- ebpf_process_disable_tracepoints();
-
- if (probe_links) {
- struct bpf_program *prog;
- size_t i = 0 ;
- bpf_object__for_each_program(prog, objects) {
- bpf_link__destroy(probe_links[i]);
- i++;
- }
- bpf_object__close(objects);
- }
-
- freez(cgroup_thread.thread);
-}
-
-/*****************************************************************
- *
* FUNCTIONS TO START THREAD
*
*****************************************************************/
@@ -1293,7 +1288,7 @@ static int ebpf_process_enable_tracepoints()
*/
void *ebpf_process_thread(void *ptr)
{
- netdata_thread_cleanup_push(ebpf_process_cleanup, ptr);
+ netdata_thread_cleanup_push(ebpf_process_exit, ptr);
ebpf_module_t *em = (ebpf_module_t *)ptr;
em->maps = process_maps;
@@ -1309,8 +1304,8 @@ void *ebpf_process_thread(void *ptr)
ebpf_update_pid_table(&process_maps[0], em);
set_local_pointers();
- probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
- if (!probe_links) {
+ em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
+ if (!em->probe_links) {
em->enabled = CONFIG_BOOLEAN_NO;
pthread_mutex_unlock(&lock);
goto endprocess;