diff options
author | thiagoftsm <thiagoftsm@gmail.com> | 2022-08-23 12:44:47 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-23 12:44:47 +0000 |
commit | 575986a692003638f09c975da847062637b915f4 (patch) | |
tree | e66dc73a7992953edcfdd1c9c442ec6ca5b14b1a /libnetdata | |
parent | 711e6fc5e75eb12455054116eea159b8ac83d7a9 (diff) |
Improve PID monitoring (step 2) (#13530)
Diffstat (limited to 'libnetdata')
-rw-r--r-- | libnetdata/ebpf/ebpf.c | 81 | ||||
-rw-r--r-- | libnetdata/ebpf/ebpf.h | 15 |
2 files changed, 78 insertions, 18 deletions
diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c index 268515a98d..7e113e8417 100644 --- a/libnetdata/ebpf/ebpf.c +++ b/libnetdata/ebpf/ebpf.c @@ -444,9 +444,9 @@ void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em) // In theory the `else if` is useless, because when this function is called, the module should not stay in // EBPF_LOAD_PLAY_DICE. We have this additional condition to detect errors from developers. - if (em->load == EBPF_LOAD_LEGACY) + if (em->load & EBPF_LOAD_LEGACY) report->legacy++; - else if (em->load == EBPF_LOAD_CORE) + else if (em->load & EBPF_LOAD_CORE) report->core++; ebpf_stats_targets(report, em->targets); @@ -826,9 +826,9 @@ netdata_ebpf_load_mode_t epbf_convert_string_to_load_mode(char *str) */ static char *ebpf_convert_load_mode_to_string(netdata_ebpf_load_mode_t mode) { - if (mode == EBPF_LOAD_CORE) + if (mode & EBPF_LOAD_CORE) return EBPF_CFG_CORE_PROGRAM; - else if (mode == EBPF_LOAD_LEGACY) + else if (mode & EBPF_LOAD_LEGACY) return EBPF_CFG_LEGACY_PROGRAM; return EBPF_CFG_DEFAULT_PROGRAM; @@ -850,7 +850,7 @@ static char *ebpf_convert_collect_pid_to_string(netdata_apps_level_t level) else if (level == NETDATA_APPS_LEVEL_ALL) return EBPF_CFG_PID_ALL; - return EBPF_CFG_PID_ALL; + return EBPF_CFG_PID_INTERNAL_USAGE; } /** @@ -903,9 +903,11 @@ netdata_ebpf_program_loaded_t ebpf_convert_core_type(char *str, netdata_run_mode void ebpf_adjust_thread_load(ebpf_module_t *mod, struct btf *file) { if (!file) { - mod->load = EBPF_LOAD_LEGACY; + mod->load &= ~EBPF_LOAD_CORE; + mod->load |= EBPF_LOAD_LEGACY; } else if (mod->load == EBPF_LOAD_PLAY_DICE && file) { - mod->load = EBPF_LOAD_CORE; + mod->load &= ~EBPF_LOAD_LEGACY; + mod->load |= EBPF_LOAD_CORE; } } @@ -1019,13 +1021,38 @@ static void ebpf_update_target_with_conf(ebpf_module_t *em, netdata_ebpf_program } /** + * Select Load Mode + * + * Select the load mode according the given inputs. + * + * @param btf_file a pointer to the loaded btf file. + * @parma load current value. + * + * @return it returns the new load mode. + */ +static netdata_ebpf_load_mode_t ebpf_select_load_mode(struct btf *btf_file, netdata_ebpf_load_mode_t load) +{ +#ifdef LIBBPF_MAJOR_VERSION + if ((load & EBPF_LOAD_CORE) || (load & EBPF_LOAD_PLAY_DICE)) { + load = (!btf_file) ? EBPF_LOAD_LEGACY : EBPF_LOAD_CORE; + } +#else + load = EBPF_LOAD_LEGACY; +#endif + + return load; +} + +/** * Update Module using config * * Update configuration for a specific thread. * * @param modules structure that will be updated + * @oaram origin specify the configuration file loaded + * @param btf_file a pointer to the loaded btf file. */ -void ebpf_update_module_using_config(ebpf_module_t *modules) +void ebpf_update_module_using_config(ebpf_module_t *modules, netdata_ebpf_load_mode_t origin, struct btf *btf_file) { char default_value[EBPF_MAX_MODE_LENGTH + 1]; ebpf_select_mode_string(default_value, EBPF_MAX_MODE_LENGTH, modules->mode); @@ -1044,9 +1071,11 @@ void ebpf_update_module_using_config(ebpf_module_t *modules) modules->pid_map_size = (uint32_t)appconfig_get_number(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_PID_SIZE, modules->pid_map_size); - value = ebpf_convert_load_mode_to_string(modules->load); + value = ebpf_convert_load_mode_to_string(modules->load & NETDATA_EBPF_LOAD_METHODS); value = appconfig_get(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_TYPE_FORMAT, value); - modules->load = epbf_convert_string_to_load_mode(value); + netdata_ebpf_load_mode_t load = epbf_convert_string_to_load_mode(value); + load = ebpf_select_load_mode(btf_file, load); + modules->load = origin | load; value = appconfig_get(modules->cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_CORE_ATTACH, EBPF_CFG_ATTACH_TRAMPOLINE); netdata_ebpf_program_loaded_t fill_lm = ebpf_convert_core_type(value, modules->mode); @@ -1066,10 +1095,13 @@ void ebpf_update_module_using_config(ebpf_module_t *modules) * update the variables. * * @param em the module structure + * @param btf_file a pointer to the loaded btf file. */ -void ebpf_update_module(ebpf_module_t *em) +void ebpf_update_module(ebpf_module_t *em, struct btf *btf_file) { char filename[FILENAME_MAX+1]; + netdata_ebpf_load_mode_t origin; + ebpf_mount_config_name(filename, FILENAME_MAX, ebpf_user_config_dir, em->config_file); if (!ebpf_load_config(em->cfg, filename)) { ebpf_mount_config_name(filename, FILENAME_MAX, ebpf_stock_config_dir, em->config_file); @@ -1077,9 +1109,32 @@ void ebpf_update_module(ebpf_module_t *em) error("Cannot load the ebpf configuration file %s", em->config_file); return; } - } + // If user defined data globaly, we will have here EBPF_LOADED_FROM_USER, we need to consider this, to avoid + // forcing users to configure thread by thread. + origin = (!(em->load & NETDATA_EBPF_LOAD_SOURCE)) ? EBPF_LOADED_FROM_STOCK : em->load & NETDATA_EBPF_LOAD_SOURCE; + } else + origin = EBPF_LOADED_FROM_USER; - ebpf_update_module_using_config(em); + ebpf_update_module_using_config(em, origin, btf_file); +} + +/** + * Adjust Apps Cgroup + * + * Apps and cgroup has internal cleanup that needs attaching tracers to release_task, to avoid overload the function + * we will enable this integration by default, if and only if, we are running with trampolines. + * + * @param em a poiter to the main thread structure. + * @param mode is the mode used with different + */ +void ebpf_adjust_apps_cgroup(ebpf_module_t *em, netdata_ebpf_program_loaded_t mode) +{ + if ((em->load & EBPF_LOADED_FROM_STOCK) && + (em->apps_charts || em->cgroup_charts) && + mode != EBPF_LOAD_TRAMPOLINE) { + em->apps_charts = NETDATA_EBPF_APPS_FLAG_NO; + em->cgroup_charts = 0; + } } //---------------------------------------------------------------------------------------------------------------------- diff --git a/libnetdata/ebpf/ebpf.h b/libnetdata/ebpf/ebpf.h index 61006f9478..7b06750048 100644 --- a/libnetdata/ebpf/ebpf.h +++ b/libnetdata/ebpf/ebpf.h @@ -30,6 +30,7 @@ #define EBPF_CFG_PID_REAL_PARENT "real parent" #define EBPF_CFG_PID_PARENT "parent" #define EBPF_CFG_PID_ALL "all" +#define EBPF_CFG_PID_INTERNAL_USAGE "not used" #define EBPF_CFG_CORE_ATTACH "ebpf co-re tracing" #define EBPF_CFG_ATTACH_TRAMPOLINE "trampoline" @@ -201,11 +202,14 @@ typedef struct ebpf_specify_name { } ebpf_specify_name_t; typedef enum netdata_ebpf_load_mode { - EBPF_LOAD_LEGACY, // Select legacy mode, this means we will load binaries - EBPF_LOAD_CORE, // When CO-RE is used, it is necessary to use the souce code - - EBPF_LOAD_PLAY_DICE // Take a look on environment and choose the best option + EBPF_LOAD_LEGACY = 1<<0, // Select legacy mode, this means we will load binaries + EBPF_LOAD_CORE = 1<<1, // When CO-RE is used, it is necessary to use the souce code + EBPF_LOAD_PLAY_DICE = 1<<2, // Take a look on environment and choose the best option + EBPF_LOADED_FROM_STOCK = 1<<3, // Configuration loaded from Stock file + EBPF_LOADED_FROM_USER = 1<<4 // Configuration loaded from user } netdata_ebpf_load_mode_t; +#define NETDATA_EBPF_LOAD_METHODS (EBPF_LOAD_LEGACY|EBPF_LOAD_CORE|EBPF_LOAD_PLAY_DICE) +#define NETDATA_EBPF_LOAD_SOURCE (EBPF_LOADED_FROM_STOCK|EBPF_LOADED_FROM_USER) typedef enum netdata_ebpf_program_loaded { EBPF_LOAD_PROBE, // Attach probes on targets @@ -274,8 +278,9 @@ extern struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, extern void ebpf_mount_config_name(char *filename, size_t length, char *path, const char *config); extern int ebpf_load_config(struct config *config, char *filename); -extern void ebpf_update_module(ebpf_module_t *em); +extern void ebpf_update_module(ebpf_module_t *em, struct btf *btf_file); extern void ebpf_update_names(ebpf_specify_name_t *opt, ebpf_module_t *em); +extern void ebpf_adjust_apps_cgroup(ebpf_module_t *em, netdata_ebpf_program_loaded_t mode); extern char *ebpf_find_symbol(char *search); extern void ebpf_load_addresses(ebpf_addresses_t *fa, int fd); extern void ebpf_fill_algorithms(int *algorithms, size_t length, int algorithm); |