From 6cf8f2d5174a53f582e61d715edbb88d6e3367cc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 14 Jun 2023 21:20:33 +0200 Subject: Adding upstream version 1.40.0. Signed-off-by: Daniel Baumann --- collectors/ebpf.plugin/ebpf_socket.c | 132 +++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 28 deletions(-) (limited to 'collectors/ebpf.plugin/ebpf_socket.c') diff --git a/collectors/ebpf.plugin/ebpf_socket.c b/collectors/ebpf.plugin/ebpf_socket.c index aebc9ca12..b45dec7d9 100644 --- a/collectors/ebpf.plugin/ebpf_socket.c +++ b/collectors/ebpf.plugin/ebpf_socket.c @@ -27,35 +27,67 @@ static ebpf_local_maps_t socket_maps[] = {{.name = "tbl_bandwidth", .internal_input = NETDATA_COMPILED_CONNECTIONS_ALLOWED, .user_input = NETDATA_MAXIMUM_CONNECTIONS_ALLOWED, .type = NETDATA_EBPF_MAP_RESIZABLE | NETDATA_EBPF_MAP_PID, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_HASH +#endif + }, {.name = "tbl_global_sock", .internal_input = NETDATA_SOCKET_COUNTER, .user_input = 0, .type = NETDATA_EBPF_MAP_STATIC, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_ARRAY +#endif + }, {.name = "tbl_lports", .internal_input = NETDATA_SOCKET_COUNTER, .user_input = 0, .type = NETDATA_EBPF_MAP_STATIC, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_HASH +#endif + }, {.name = "tbl_conn_ipv4", .internal_input = NETDATA_COMPILED_CONNECTIONS_ALLOWED, .user_input = NETDATA_MAXIMUM_CONNECTIONS_ALLOWED, .type = NETDATA_EBPF_MAP_STATIC, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_HASH +#endif + }, {.name = "tbl_conn_ipv6", .internal_input = NETDATA_COMPILED_CONNECTIONS_ALLOWED, .user_input = NETDATA_MAXIMUM_CONNECTIONS_ALLOWED, .type = NETDATA_EBPF_MAP_STATIC, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_HASH +#endif + }, {.name = "tbl_nv_udp", .internal_input = NETDATA_COMPILED_UDP_CONNECTIONS_ALLOWED, .user_input = NETDATA_MAXIMUM_UDP_CONNECTIONS_ALLOWED, .type = NETDATA_EBPF_MAP_STATIC, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_HASH +#endif + }, {.name = "socket_ctrl", .internal_input = NETDATA_CONTROLLER_END, .user_input = 0, .type = NETDATA_EBPF_MAP_CONTROLLER, - .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}, - {.name = NULL, .internal_input = 0, .user_input = 0}}; + .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_ARRAY +#endif + }, + {.name = NULL, .internal_input = 0, .user_input = 0, +#ifdef LIBBPF_MAJOR_VERSION + .map_type = BPF_MAP_TYPE_PERCPU_ARRAY +#endif + }}; static netdata_idx_t *socket_hash_values = NULL; static netdata_syscall_stat_t socket_aggregated_data[NETDATA_MAX_SOCKET_VECTOR]; @@ -362,7 +394,7 @@ static void ebpf_socket_set_hash_tables(struct socket_bpf *obj) * @param obj is the main structure for bpf objects. * @param em structure with configuration */ -static void ebpf_socket_adjust_map_size(struct socket_bpf *obj, ebpf_module_t *em) +static void ebpf_socket_adjust_map(struct socket_bpf *obj, ebpf_module_t *em) { ebpf_update_map_size(obj->maps.tbl_bandwidth, &socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH], em, bpf_map__name(obj->maps.tbl_bandwidth)); @@ -375,6 +407,15 @@ static void ebpf_socket_adjust_map_size(struct socket_bpf *obj, ebpf_module_t *e ebpf_update_map_size(obj->maps.tbl_nv_udp, &socket_maps[NETDATA_SOCKET_TABLE_UDP], em, bpf_map__name(obj->maps.tbl_nv_udp)); + + + ebpf_update_map_type(obj->maps.tbl_bandwidth, &socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH]); + ebpf_update_map_type(obj->maps.tbl_conn_ipv4, &socket_maps[NETDATA_SOCKET_TABLE_IPV4]); + ebpf_update_map_type(obj->maps.tbl_conn_ipv6, &socket_maps[NETDATA_SOCKET_TABLE_IPV6]); + ebpf_update_map_type(obj->maps.tbl_nv_udp, &socket_maps[NETDATA_SOCKET_TABLE_UDP]); + ebpf_update_map_type(obj->maps.socket_ctrl, &socket_maps[NETDATA_SOCKET_TABLE_CTRL]); + ebpf_update_map_type(obj->maps.tbl_global_sock, &socket_maps[NETDATA_SOCKET_GLOBAL]); + ebpf_update_map_type(obj->maps.tbl_lports, &socket_maps[NETDATA_SOCKET_LPORTS]); } /** @@ -403,14 +444,14 @@ static inline int ebpf_socket_load_and_attach(struct socket_bpf *obj, ebpf_modul ebpf_socket_disable_specific_probe(obj, em->mode); } + ebpf_socket_adjust_map(obj, em); + int ret = socket_bpf__load(obj); if (ret) { fprintf(stderr, "failed to load BPF object: %d\n", ret); return ret; } - ebpf_socket_adjust_map_size(obj, em); - if (test == EBPF_LOAD_TRAMPOLINE) { ret = socket_bpf__attach(obj); } else { @@ -1988,17 +2029,23 @@ static void hash_accumulator(netdata_socket_t *values, netdata_socket_idx_t *key * * @param fd the hash table with data. * @param family the family associated to the hash table + * @param maps_per_core do I need to read all cores? * * @return it returns 0 on success and -1 otherwise. */ -static void ebpf_read_socket_hash_table(int fd, int family) +static void ebpf_read_socket_hash_table(int fd, int family, int maps_per_core) { netdata_socket_idx_t key = {}; netdata_socket_idx_t next_key = {}; netdata_socket_t *values = socket_values; - size_t length = ebpf_nprocs*sizeof(netdata_socket_t); - int test, end = (running_on_kernel < NETDATA_KERNEL_V4_15) ? 1 : ebpf_nprocs; + size_t length = sizeof(netdata_socket_t); + int test, end; + if (maps_per_core) { + length *= ebpf_nprocs; + end = ebpf_nprocs; + } else + end = 1; while (bpf_map_get_next_key(fd, &key, &next_key) == 0) { // We need to reset the values when we are working on kernel 4.15 or newer, because kernel does not create @@ -2122,11 +2169,13 @@ static void read_listen_table() void *ebpf_socket_read_hash(void *ptr) { netdata_thread_cleanup_push(ebpf_socket_cleanup, ptr); + ebpf_module_t *em = (ebpf_module_t *)ptr; heartbeat_t hb; heartbeat_init(&hb); int fd_ipv4 = socket_maps[NETDATA_SOCKET_TABLE_IPV4].map_fd; int fd_ipv6 = socket_maps[NETDATA_SOCKET_TABLE_IPV6].map_fd; + int maps_per_core = em->maps_per_core; // This thread is cancelled from another thread for (;;) { (void)heartbeat_next(&hb, USEC_PER_SEC); @@ -2134,8 +2183,8 @@ void *ebpf_socket_read_hash(void *ptr) break; pthread_mutex_lock(&nv_mutex); - ebpf_read_socket_hash_table(fd_ipv4, AF_INET); - ebpf_read_socket_hash_table(fd_ipv6, AF_INET6); + ebpf_read_socket_hash_table(fd_ipv4, AF_INET, maps_per_core); + ebpf_read_socket_hash_table(fd_ipv6, AF_INET6, maps_per_core); pthread_mutex_unlock(&nv_mutex); } @@ -2145,23 +2194,30 @@ void *ebpf_socket_read_hash(void *ptr) /** * Read the hash table and store data to allocated vectors. + * + * @param maps_per_core do I need to read all cores? */ -static void read_hash_global_tables() +static void read_hash_global_tables(int maps_per_core) { uint64_t idx; netdata_idx_t res[NETDATA_SOCKET_COUNTER]; netdata_idx_t *val = socket_hash_values; + size_t length = sizeof(netdata_idx_t); + if (maps_per_core) + length *= ebpf_nprocs; + int fd = socket_maps[NETDATA_SOCKET_GLOBAL].map_fd; for (idx = 0; idx < NETDATA_SOCKET_COUNTER; idx++) { if (!bpf_map_lookup_elem(fd, &idx, val)) { uint64_t total = 0; int i; - int end = ebpf_nprocs; + int end = (maps_per_core) ? ebpf_nprocs : 1; for (i = 0; i < end; i++) total += val[i]; res[idx] = total; + memset(socket_hash_values, 0, length); } else { res[idx] = 0; } @@ -2220,9 +2276,9 @@ void ebpf_socket_fill_publish_apps(uint32_t current_pid, ebpf_bandwidth_t *eb) * * @param out the vector with the values to sum */ -void ebpf_socket_bandwidth_accumulator(ebpf_bandwidth_t *out) +void ebpf_socket_bandwidth_accumulator(ebpf_bandwidth_t *out, int maps_per_core) { - int i, end = (running_on_kernel >= NETDATA_KERNEL_V4_15) ? ebpf_nprocs : 1; + int i, end = (maps_per_core) ? ebpf_nprocs : 1; ebpf_bandwidth_t *total = &out[0]; for (i = 1; i < end; i++) { ebpf_bandwidth_t *move = &out[i]; @@ -2241,13 +2297,18 @@ void ebpf_socket_bandwidth_accumulator(ebpf_bandwidth_t *out) /** * Update the apps data reading information from the hash table + * + * @param maps_per_core do I need to read all cores? */ -static void ebpf_socket_update_apps_data() +static void ebpf_socket_update_apps_data(int maps_per_core) { int fd = socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH].map_fd; ebpf_bandwidth_t *eb = bandwidth_vector; uint32_t key; struct ebpf_pid_stat *pids = ebpf_root_of_pids; + size_t length = sizeof(ebpf_bandwidth_t); + if (maps_per_core) + length *= ebpf_nprocs; while (pids) { key = pids->pid; @@ -2256,10 +2317,12 @@ static void ebpf_socket_update_apps_data() continue; } - ebpf_socket_bandwidth_accumulator(eb); + ebpf_socket_bandwidth_accumulator(eb, maps_per_core); ebpf_socket_fill_publish_apps(key, eb); + memset(eb, 0, length); + pids = pids->next; } } @@ -2267,15 +2330,21 @@ static void ebpf_socket_update_apps_data() /** * Update cgroup * - * Update cgroup data based in + * Update cgroup data based in PIDs. + * + * @param maps_per_core do I need to read all cores? */ -static void ebpf_update_socket_cgroup() +static void ebpf_update_socket_cgroup(int maps_per_core) { ebpf_cgroup_target_t *ect ; ebpf_bandwidth_t *eb = bandwidth_vector; int fd = socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH].map_fd; + size_t length = sizeof(ebpf_bandwidth_t); + if (maps_per_core) + length *= ebpf_nprocs; + pthread_mutex_lock(&mutex_cgroup_shm); for (ect = ebpf_cgroup_pids; ect; ect = ect->next) { struct pid_on_target2 *pids; @@ -2298,7 +2367,7 @@ static void ebpf_update_socket_cgroup() publish->call_tcp_v6_connection = in->call_tcp_v6_connection; } else { if (!bpf_map_lookup_elem(fd, &pid, eb)) { - ebpf_socket_bandwidth_accumulator(eb); + ebpf_socket_bandwidth_accumulator(eb, maps_per_core); memcpy(out, eb, sizeof(ebpf_bandwidth_t)); @@ -2312,6 +2381,8 @@ static void ebpf_update_socket_cgroup() publish->call_close = out->close; publish->call_tcp_v4_connection = out->tcp_v4_connection; publish->call_tcp_v6_connection = out->tcp_v6_connection; + + memset(eb, 0, length); } } } @@ -2845,6 +2916,7 @@ static void socket_collector(ebpf_module_t *em) int socket_global_enabled = em->global_charts; int update_every = em->update_every; + int maps_per_core = em->maps_per_core; int counter = update_every - 1; while (!ebpf_exit_plugin) { (void)heartbeat_next(&hb, USEC_PER_SEC); @@ -2855,15 +2927,15 @@ static void socket_collector(ebpf_module_t *em) netdata_apps_integration_flags_t socket_apps_enabled = em->apps_charts; if (socket_global_enabled) { read_listen_table(); - read_hash_global_tables(); + read_hash_global_tables(maps_per_core); } pthread_mutex_lock(&collect_data_mutex); if (socket_apps_enabled) - ebpf_socket_update_apps_data(); + ebpf_socket_update_apps_data(maps_per_core); if (cgroups) - ebpf_update_socket_cgroup(); + ebpf_update_socket_cgroup(maps_per_core); if (network_connection) calculate_nv_plot(); @@ -3855,6 +3927,10 @@ void parse_table_size_options(struct config *cfg) */ static int ebpf_socket_load_bpf(ebpf_module_t *em) { +#ifdef LIBBPF_MAJOR_VERSION + ebpf_define_map_type(em->maps, em->maps_per_core, running_on_kernel); +#endif + int ret = 0; if (em->load & EBPF_LOAD_LEGACY) { -- cgit v1.2.3