From a836a244a3d2bdd4da1ee2641e3e957850668cea Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 8 May 2023 18:27:04 +0200 Subject: Adding upstream version 1.39.0. Signed-off-by: Daniel Baumann --- collectors/ebpf.plugin/ebpf_cgroup.c | 145 ++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 35 deletions(-) (limited to 'collectors/ebpf.plugin/ebpf_cgroup.c') diff --git a/collectors/ebpf.plugin/ebpf_cgroup.c b/collectors/ebpf.plugin/ebpf_cgroup.c index 42c045368..6d7c555bd 100644 --- a/collectors/ebpf.plugin/ebpf_cgroup.c +++ b/collectors/ebpf.plugin/ebpf_cgroup.c @@ -6,6 +6,7 @@ #include "ebpf_cgroup.h" ebpf_cgroup_target_t *ebpf_cgroup_pids = NULL; +static void *ebpf_mapped_memory = NULL; int send_cgroup_chart = 0; // -------------------------------------------------------------------------------------------------------------------- @@ -19,7 +20,7 @@ int send_cgroup_chart = 0; * @param fd file descriptor returned after shm_open was called. * @param length length of the shared memory * - * @return It returns a pointer to the region mapped. + * @return It returns a pointer to the region mapped on success and MAP_FAILED otherwise. */ static inline void *ebpf_cgroup_map_shm_locally(int fd, size_t length) { @@ -36,6 +37,16 @@ static inline void *ebpf_cgroup_map_shm_locally(int fd, size_t length) return value; } +/** + * Unmap Shared Memory + * + * Unmap shared memory used to integrate eBPF and cgroup plugin + */ +void ebpf_unmap_cgroup_shared_memory() +{ + munmap(ebpf_mapped_memory, shm_ebpf_cgroup.header->body_length); +} + /** * Map cgroup shared memory * @@ -56,40 +67,47 @@ void ebpf_map_cgroup_shared_memory() limit_try++; next_try = curr_time + NETDATA_EBPF_CGROUP_NEXT_TRY_SEC; - shm_fd_ebpf_cgroup = shm_open(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME, O_RDWR, 0660); if (shm_fd_ebpf_cgroup < 0) { - if (limit_try == NETDATA_EBPF_CGROUP_MAX_TRIES) - error("Shared memory was not initialized, integration between processes won't happen."); + shm_fd_ebpf_cgroup = shm_open(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME, O_RDWR, 0660); + if (shm_fd_ebpf_cgroup < 0) { + if (limit_try == NETDATA_EBPF_CGROUP_MAX_TRIES) + error("Shared memory was not initialized, integration between processes won't happen."); - return; + return; + } } // Map only header - shm_ebpf_cgroup.header = (netdata_ebpf_cgroup_shm_header_t *) ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup, - sizeof(netdata_ebpf_cgroup_shm_header_t)); - if (!shm_ebpf_cgroup.header) { - limit_try = NETDATA_EBPF_CGROUP_MAX_TRIES + 1; + void *mapped = (netdata_ebpf_cgroup_shm_header_t *) ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup, + sizeof(netdata_ebpf_cgroup_shm_header_t)); + if (unlikely(mapped == SEM_FAILED)) { return; } + netdata_ebpf_cgroup_shm_header_t *header = mapped; - size_t length = shm_ebpf_cgroup.header->body_length; + size_t length = header->body_length; - munmap(shm_ebpf_cgroup.header, sizeof(netdata_ebpf_cgroup_shm_header_t)); + munmap(header, sizeof(netdata_ebpf_cgroup_shm_header_t)); - shm_ebpf_cgroup.header = (netdata_ebpf_cgroup_shm_header_t *)ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup, length); - if (!shm_ebpf_cgroup.header) { - limit_try = NETDATA_EBPF_CGROUP_MAX_TRIES + 1; + if (length <= ((sizeof(netdata_ebpf_cgroup_shm_header_t) + sizeof(netdata_ebpf_cgroup_shm_body_t)))) { return; } - shm_ebpf_cgroup.body = (netdata_ebpf_cgroup_shm_body_t *) ((char *)shm_ebpf_cgroup.header + - sizeof(netdata_ebpf_cgroup_shm_header_t)); + + ebpf_mapped_memory = (void *)ebpf_cgroup_map_shm_locally(shm_fd_ebpf_cgroup, length); + if (unlikely(ebpf_mapped_memory == MAP_FAILED)) { + return; + } + shm_ebpf_cgroup.header = ebpf_mapped_memory; + shm_ebpf_cgroup.body = ebpf_mapped_memory + sizeof(netdata_ebpf_cgroup_shm_header_t); shm_sem_ebpf_cgroup = sem_open(NETDATA_NAMED_SEMAPHORE_EBPF_CGROUP_NAME, O_CREAT, 0660, 1); if (shm_sem_ebpf_cgroup == SEM_FAILED) { error("Cannot create semaphore, integration between eBPF and cgroup won't happen"); - munmap(shm_ebpf_cgroup.header, length); + limit_try = NETDATA_EBPF_CGROUP_MAX_TRIES + 1; + munmap(ebpf_mapped_memory, length); shm_ebpf_cgroup.header = NULL; + shm_ebpf_cgroup.body = NULL; close(shm_fd_ebpf_cgroup); shm_fd_ebpf_cgroup = -1; shm_unlink(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME); @@ -258,32 +276,38 @@ void ebpf_reset_updated_var() void ebpf_parse_cgroup_shm_data() { static int previous = 0; - if (shm_ebpf_cgroup.header) { - sem_wait(shm_sem_ebpf_cgroup); - int i, end = shm_ebpf_cgroup.header->cgroup_root_count; + if (!shm_ebpf_cgroup.header || shm_sem_ebpf_cgroup == SEM_FAILED) + return; - pthread_mutex_lock(&mutex_cgroup_shm); + sem_wait(shm_sem_ebpf_cgroup); + int i, end = shm_ebpf_cgroup.header->cgroup_root_count; + if (end <= 0) { + sem_post(shm_sem_ebpf_cgroup); + return; + } - ebpf_remove_cgroup_target_update_list(); + pthread_mutex_lock(&mutex_cgroup_shm); + ebpf_remove_cgroup_target_update_list(); - ebpf_reset_updated_var(); + ebpf_reset_updated_var(); - for (i = 0; i < end; i++) { - netdata_ebpf_cgroup_shm_body_t *ptr = &shm_ebpf_cgroup.body[i]; - if (ptr->enabled) { - ebpf_cgroup_target_t *ect = ebpf_cgroup_find_or_create(ptr); - ebpf_update_pid_link_list(ect, ptr->path); - } + for (i = 0; i < end; i++) { + netdata_ebpf_cgroup_shm_body_t *ptr = &shm_ebpf_cgroup.body[i]; + if (ptr->enabled) { + ebpf_cgroup_target_t *ect = ebpf_cgroup_find_or_create(ptr); + ebpf_update_pid_link_list(ect, ptr->path); } - send_cgroup_chart = previous != shm_ebpf_cgroup.header->cgroup_root_count; - previous = shm_ebpf_cgroup.header->cgroup_root_count; + } + send_cgroup_chart = previous != shm_ebpf_cgroup.header->cgroup_root_count; + previous = shm_ebpf_cgroup.header->cgroup_root_count; + sem_post(shm_sem_ebpf_cgroup); + pthread_mutex_unlock(&mutex_cgroup_shm); #ifdef NETDATA_DEV_MODE - error("Updating cgroup %d (Previous: %d, Current: %d)", send_cgroup_chart, previous, shm_ebpf_cgroup.header->cgroup_root_count); + info("Updating cgroup %d (Previous: %d, Current: %d)", + send_cgroup_chart, previous, shm_ebpf_cgroup.header->cgroup_root_count); #endif - pthread_mutex_unlock(&mutex_cgroup_shm); - sem_post(shm_sem_ebpf_cgroup); - } + sem_post(shm_sem_ebpf_cgroup); } // -------------------------------------------------------------------------------------------------------------------- @@ -315,3 +339,54 @@ void ebpf_create_charts_on_systemd(char *id, char *title, char *units, char *fam fprintf(stdout, "DIMENSION %s '' %s 1 1\n", w->name, algorithm); } } + +// -------------------------------------------------------------------------------------------------------------------- +// Cgroup main thread + +/** + * CGROUP exit + * + * Clean up the main thread. + * + * @param ptr thread data. + */ +static void ebpf_cgroup_exit(void *ptr) +{ + UNUSED(ptr); +} + +/** + * Cgroup integratin + * + * Thread responsible to call functions responsible to sync data between plugins. + * + * @param ptr It is a NULL value for this thread. + * + * @return It always returns NULL. + */ +void *ebpf_cgroup_integration(void *ptr) +{ + netdata_thread_cleanup_push(ebpf_cgroup_exit, ptr); + + usec_t step = USEC_PER_SEC; + int counter = NETDATA_EBPF_CGROUP_UPDATE - 1; + heartbeat_t hb; + heartbeat_init(&hb); + //Plugin will be killed when it receives a signal + while (!ebpf_exit_plugin) { + (void)heartbeat_next(&hb, step); + + // 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(); + else + ebpf_parse_cgroup_shm_data(); + } + } + + netdata_thread_cleanup_pop(1); + return NULL; +} -- cgit v1.2.3