diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c index 21b39231c7..6e3b522f36 100644 --- a/collectors/ebpf.plugin/ebpf.c +++ b/collectors/ebpf.plugin/ebpf.c @@ -435,9 +435,6 @@ ebpf_sync_syscalls_t local_syscalls[] = { }; -// Link with apps.plugin -ebpf_process_stat_t *global_process_stat = NULL; - // Link with cgroup.plugin netdata_ebpf_cgroup_shm_t shm_ebpf_cgroup = {NULL, NULL}; int shm_fd_ebpf_cgroup = -1; @@ -876,9 +873,9 @@ void ebpf_create_chart(char *type, * @param module chart module name, this is the eBPF thread. */ void ebpf_create_charts_on_apps(char *id, char *title, char *units, char *family, char *charttype, int order, - char *algorithm, struct target *root, int update_every, char *module) + char *algorithm, struct ebpf_target *root, int update_every, char *module) { - struct target *w; + struct ebpf_target *w; ebpf_write_chart_cmd(NETDATA_APPS_FAMILY, id, title, units, family, charttype, NULL, order, update_every, module); @@ -1386,8 +1383,8 @@ static void ebpf_allocate_common_vectors() return; } - all_pids = callocz((size_t)pid_max, sizeof(struct pid_stat *)); - global_process_stat = callocz((size_t)ebpf_nprocs, sizeof(ebpf_process_stat_t)); + ebpf_all_pids = callocz((size_t)pid_max, sizeof(struct ebpf_pid_stat *)); + ebpf_aral_init(); } /** diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h index 16e62498c4..a05c6d6db4 100644 --- a/collectors/ebpf.plugin/ebpf.h +++ b/collectors/ebpf.plugin/ebpf.h @@ -235,7 +235,7 @@ void ebpf_create_charts_on_apps(char *name, char *charttype, int order, char *algorithm, - struct target *root, + struct ebpf_target *root, int update_every, char *module); @@ -264,16 +264,15 @@ void ebpf_pid_file(char *filename, size_t length); // Common variables extern int debug_enabled; -extern struct pid_stat *root_of_pids; +extern struct ebpf_pid_stat *ebpf_root_of_pids; extern ebpf_cgroup_target_t *ebpf_cgroup_pids; extern char *ebpf_algorithms[]; extern struct config collector_config; -extern ebpf_process_stat_t *global_process_stat; extern netdata_ebpf_cgroup_shm_t shm_ebpf_cgroup; extern int shm_fd_ebpf_cgroup; extern sem_t *shm_sem_ebpf_cgroup; extern pthread_mutex_t mutex_cgroup_shm; -extern size_t all_pids_count; +extern size_t ebpf_all_pids_count; extern ebpf_plugin_stats_t plugin_statistics; #ifdef LIBBPF_MAJOR_VERSION extern struct btf *default_btf; diff --git a/collectors/ebpf.plugin/ebpf_apps.c b/collectors/ebpf.plugin/ebpf_apps.c index 7519e06402..2442c55dbf 100644 --- a/collectors/ebpf.plugin/ebpf_apps.c +++ b/collectors/ebpf.plugin/ebpf_apps.c @@ -4,6 +4,84 @@ #include "ebpf_socket.h" #include "ebpf_apps.h" +// ---------------------------------------------------------------------------- +// ARAL vectors used to speed up processing +ARAL *ebpf_aral_apps_pid_stat; +ARAL *ebpf_aral_process_stat; + +/** + * eBPF ARAL Init + * + * Initiallize array allocator that will be used when integration with apps and ebpf is created. + */ +void ebpf_aral_init(void) +{ + size_t max_elements = NETDATA_EBPF_ALLOC_MAX_PID; + if (max_elements < NETDATA_EBPF_ALLOC_MIN_ELEMENTS) { + error("Number of elements given is too small, adjusting it for %d", NETDATA_EBPF_ALLOC_MIN_ELEMENTS); + max_elements = NETDATA_EBPF_ALLOC_MIN_ELEMENTS; + } + + ebpf_aral_apps_pid_stat = aral_create("ebpf-pid_stat", sizeof(struct ebpf_pid_stat), + 0, max_elements, + NULL, NULL, NULL, false, false); + + ebpf_aral_process_stat = aral_create("ebpf-proc_stat", sizeof(ebpf_process_stat_t), + 0, max_elements, + NULL, NULL, NULL, false, false); +#ifdef NETDATA_DEV_MODE + info("Plugin is using ARAL with values %d", NETDATA_EBPF_ALLOC_MAX_PID); +#endif +} + +/** + * eBPF pid stat get + * + * Get a ebpf_pid_stat entry to be used with a specific PID. + * + * @return it returns the address on success. + */ +struct ebpf_pid_stat *ebpf_pid_stat_get(void) +{ + struct ebpf_pid_stat *target = aral_mallocz(ebpf_aral_apps_pid_stat); + memset(target, 0, sizeof(struct ebpf_pid_stat)); + return target; +} + +/** + * eBPF target release + * + * @param stat Release a target after usage. + */ +void ebpf_pid_stat_release(struct ebpf_pid_stat *stat) +{ + aral_freez(ebpf_aral_apps_pid_stat, stat); +} + +/** + * eBPF process stat get + * + * Get a ebpf_pid_stat entry to be used with a specific PID. + * + * @return it returns the address on success. + */ +ebpf_process_stat_t *ebpf_process_stat_get(void) +{ + ebpf_process_stat_t *target = aral_mallocz(ebpf_aral_process_stat); + memset(target, 0, sizeof(ebpf_process_stat_t)); + return target; +} + +/** + * eBPF process release + * + * @param stat Release a target after usage. + */ +void ebpf_process_stat_release(ebpf_process_stat_t *stat) +{ + aral_freez(ebpf_aral_process_stat, stat); +} + // ---------------------------------------------------------------------------- // internal flags // handled in code (automatically set) @@ -49,7 +127,7 @@ int ebpf_read_hash_table(void *ep, int fd, uint32_t pid) * * @return */ -size_t read_bandwidth_statistic_using_pid_on_target(ebpf_bandwidth_t **ep, int fd, struct pid_on_target *pids) +size_t read_bandwidth_statistic_using_pid_on_target(ebpf_bandwidth_t **ep, int fd, struct ebpf_pid_on_target *pids) { size_t count = 0; while (pids) { @@ -120,19 +198,19 @@ int am_i_running_as_root() * * @return it returns the number of structures that was reset. */ -size_t zero_all_targets(struct target *root) +size_t zero_all_targets(struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; size_t count = 0; for (w = root; w; w = w->next) { count++; if (unlikely(w->root_pid)) { - struct pid_on_target *pid_on_target = w->root_pid; + struct ebpf_pid_on_target *pid_on_target = w->root_pid; while (pid_on_target) { - struct pid_on_target *pid_on_target_to_free = pid_on_target; + struct ebpf_pid_on_target *pid_on_target_to_free = pid_on_target; pid_on_target = pid_on_target->next; freez(pid_on_target_to_free); } @@ -149,9 +227,9 @@ size_t zero_all_targets(struct target *root) * * @param agrt the pointer to be cleaned. */ -void clean_apps_groups_target(struct target *agrt) +void clean_apps_groups_target(struct ebpf_target *agrt) { - struct target *current_target; + struct ebpf_target *current_target; while (agrt) { current_target = agrt; agrt = current_target->target; @@ -170,7 +248,7 @@ void clean_apps_groups_target(struct target *agrt) * * @return It returns the target on success and NULL otherwise */ -struct target *get_apps_groups_target(struct target **agrt, const char *id, struct target *target, const char *name) +struct ebpf_target *get_apps_groups_target(struct ebpf_target **agrt, const char *id, struct ebpf_target *target, const char *name) { int tdebug = 0, thidden = target ? target->hidden : 0, ends_with = 0; const char *nid = id; @@ -188,9 +266,9 @@ struct target *get_apps_groups_target(struct target **agrt, const char *id, stru uint32_t hash = simple_hash(id); // find if it already exists - struct target *w, *last = *agrt; + struct ebpf_target *w, *last = *agrt; for (w = *agrt; w; w = w->next) { - if (w->idhash == hash && strncmp(nid, w->id, MAX_NAME) == 0) + if (w->idhash == hash && strncmp(nid, w->id, EBPF_MAX_NAME) == 0) return w; last = w; @@ -215,18 +293,18 @@ struct target *get_apps_groups_target(struct target **agrt, const char *id, stru "Internal Error: request to link process '%s' to target '%s' which is linked to target '%s'", id, target->id, target->target->id); - w = callocz(1, sizeof(struct target)); - strncpyz(w->id, nid, MAX_NAME); + w = callocz(1, sizeof(struct ebpf_target)); + strncpyz(w->id, nid, EBPF_MAX_NAME); w->idhash = simple_hash(w->id); if (unlikely(!target)) // copy the name - strncpyz(w->name, name, MAX_NAME); + strncpyz(w->name, name, EBPF_MAX_NAME); else // copy the id - strncpyz(w->name, nid, MAX_NAME); + strncpyz(w->name, nid, EBPF_MAX_NAME); - strncpyz(w->compare, nid, MAX_COMPARE_NAME); + strncpyz(w->compare, nid, EBPF_MAX_COMPARE_NAME); size_t len = strlen(w->compare); if (w->compare[len - 1] == '*') { w->compare[len - 1] = '\0'; @@ -267,7 +345,7 @@ struct target *get_apps_groups_target(struct target **agrt, const char *id, stru * * @return It returns 0 on success and -1 otherwise */ -int ebpf_read_apps_groups_conf(struct target **agdt, struct target **agrt, const char *path, const char *file) +int ebpf_read_apps_groups_conf(struct ebpf_target **agdt, struct ebpf_target **agrt, const char *path, const char *file) { char filename[FILENAME_MAX + 1]; @@ -297,7 +375,7 @@ int ebpf_read_apps_groups_conf(struct target **agdt, struct target **agrt, const continue; // find a possibly existing target - struct target *w = NULL; + struct ebpf_target *w = NULL; // loop through all words, skipping the first one (the name) for (word = 0; word < words; word++) { @@ -312,7 +390,7 @@ int ebpf_read_apps_groups_conf(struct target **agdt, struct target **agrt, const continue; // add this target - struct target *n = get_apps_groups_target(agrt, s, w, name); + struct ebpf_target *n = get_apps_groups_target(agrt, s, w, name); if (!n) { error("Cannot create target '%s' (line %zu, word %zu)", s, line, word); continue; @@ -331,7 +409,7 @@ int ebpf_read_apps_groups_conf(struct target **agdt, struct target **agrt, const if (!*agdt) fatal("Cannot create default target"); - struct target *ptr = *agdt; + struct ebpf_target *ptr = *agdt; if (ptr->target) *agdt = ptr->target; @@ -345,17 +423,15 @@ int ebpf_read_apps_groups_conf(struct target **agdt, struct target **agrt, const // ---------------------------------------------------------------------------- // string lengths -#define MAX_COMPARE_NAME 100 -#define MAX_NAME 100 #define MAX_CMDLINE 16384 -struct pid_stat **all_pids = NULL; // to avoid allocations, we pre-allocate the +struct ebpf_pid_stat **ebpf_all_pids = NULL; // to avoid allocations, we pre-allocate the // the entire pid space. -struct pid_stat *root_of_pids = NULL; // global list of all processes running +struct ebpf_pid_stat *ebpf_root_of_pids = NULL; // global list of all processes running -size_t all_pids_count = 0; // the number of processes running +size_t ebpf_all_pids_count = 0; // the number of processes running -struct target +struct ebpf_target *apps_groups_default_target = NULL, // the default target *apps_groups_root_target = NULL, // apps_groups.conf defined *users_root_target = NULL, // users @@ -416,7 +492,7 @@ static inline void debug_log_dummy(void) * * @return It returns the status value. */ -static inline int managed_log(struct pid_stat *p, uint32_t log, int status) +static inline int managed_log(struct ebpf_pid_stat *p, uint32_t log, int status) { if (unlikely(!status)) { // error("command failed log %u, errno %d", log, errno); @@ -476,23 +552,23 @@ static inline int managed_log(struct pid_stat *p, uint32_t log, int status) * * @return It returns the pid entry structure */ -static inline struct pid_stat *get_pid_entry(pid_t pid) +static inline struct ebpf_pid_stat *get_pid_entry(pid_t pid) { - if (unlikely(all_pids[pid])) - return all_pids[pid]; + if (unlikely(ebpf_all_pids[pid])) + return ebpf_all_pids[pid]; - struct pid_stat *p = callocz(1, sizeof(struct pid_stat)); + struct ebpf_pid_stat *p = ebpf_pid_stat_get(); - if (likely(root_of_pids)) - root_of_pids->prev = p; + if (likely(ebpf_root_of_pids)) + ebpf_root_of_pids->prev = p; - p->next = root_of_pids; - root_of_pids = p; + p->next = ebpf_root_of_pids; + ebpf_root_of_pids = p; p->pid = pid; - all_pids[pid] = p; - all_pids_count++; + ebpf_all_pids[pid] = p; + ebpf_all_pids_count++; return p; } @@ -502,14 +578,14 @@ static inline struct pid_stat *get_pid_entry(pid_t pid) * * @param p the pid_stat structure to assign for a target. */ -static inline void assign_target_to_pid(struct pid_stat *p) +static inline void assign_target_to_pid(struct ebpf_pid_stat *p) { targets_assignment_counter++; uint32_t hash = simple_hash(p->comm); size_t pclen = strlen(p->comm); - struct target *w; + struct ebpf_target *w; for (w = apps_groups_root_target; w; w = w->next) { // if(debug_enabled || (p->target && p->target->debug_enabled)) debug_log_int("\t\tcomparing '%s' with '%s'", w->compare, p->comm); @@ -543,11 +619,11 @@ static inline void assign_target_to_pid(struct pid_stat *p) /** * Read cmd line from /proc/PID/cmdline * - * @param p the pid_stat_structure. + * @param p the ebpf_pid_stat_structure. * * @return It returns 1 on success and 0 otherwise. */ -static inline int read_proc_pid_cmdline(struct pid_stat *p) +static inline int read_proc_pid_cmdline(struct ebpf_pid_stat *p) { static char cmdline[MAX_CMDLINE + 1]; @@ -596,7 +672,7 @@ cleanup: * @param p the pid stat structure to store the data. * @param ptr an useless argument. */ -static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) +static inline int read_proc_pid_stat(struct ebpf_pid_stat *p, void *ptr) { UNUSED(ptr); @@ -640,7 +716,7 @@ static inline int read_proc_pid_stat(struct pid_stat *p, void *ptr) debug_log("\tJust added %d (%s)", p->pid, comm); } - strncpyz(p->comm, comm, MAX_COMPARE_NAME); + strncpyz(p->comm, comm, EBPF_MAX_COMPARE_NAME); // /proc/<pid>/cmdline if (likely(proc_pid_cmdline_is_needed)) @@ -673,7 +749,7 @@ static inline int collect_data_for_pid(pid_t pid, void *ptr) return 0; } - struct pid_stat *p = get_pid_entry(pid); + struct ebpf_pid_stat *p = get_pid_entry(pid); if (unlikely(!p || p->read)) return 0; p->read = 1; @@ -701,11 +777,11 @@ static inline int collect_data_for_pid(pid_t pid, void *ptr) */ static inline void link_all_processes_to_their_parents(void) { - struct pid_stat *p, *pp; + struct ebpf_pid_stat *p, *pp; // link all children to their parents // and update children count on parents - for (p = root_of_pids; p; p = p->next) { + for (p = ebpf_root_of_pids; p; p = p->next) { // for each process found p->sortlist = 0; @@ -716,7 +792,7 @@ static inline void link_all_processes_to_their_parents(void) continue; } - pp = all_pids[p->ppid]; + pp = ebpf_all_pids[p->ppid]; if (likely(pp)) { p->parent = pp; pp->children_count++; @@ -738,7 +814,7 @@ static inline void link_all_processes_to_their_parents(void) */ static void apply_apps_groups_targets_inheritance(void) { - struct pid_stat *p = NULL; + struct ebpf_pid_stat *p = NULL; // children that do not have a target // inherit their target from their parent @@ -747,7 +823,7 @@ static void apply_apps_groups_targets_inheritance(void) if (unlikely(debug_enabled)) loops++; found = 0; - for (p = root_of_pids; p; p = p->next) { + for (p = ebpf_root_of_pids; p; p = p->next) { // if this process does not have a target // and it has a parent // and its parent has a target @@ -773,7 +849,7 @@ static void apply_apps_groups_targets_inheritance(void) loops++; found = 0; - for (p = root_of_pids; p; p = p->next) { + for (p = ebpf_root_of_pids; p; p = p->next) { if (unlikely(!p->sortlist && !p->children_count)) p->sortlist = sortlist++; @@ -809,17 +885,17 @@ static void apply_apps_groups_targets_inheritance(void) } // init goes always to default target - if (all_pids[INIT_PID]) - all_pids[INIT_PID]->target = apps_groups_default_target; + if (ebpf_all_pids[INIT_PID]) + ebpf_all_pids[INIT_PID]->target = apps_groups_default_target; // pid 0 goes always to default target - if (all_pids[0]) - all_pids[0]->target = apps_groups_default_target; + if (ebpf_all_pids[0]) + ebpf_all_pids[0]->target = apps_groups_default_target; // give a default target on all top level processes if (unlikely(debug_enabled)) loops++; - for (p = root_of_pids; p; p = p->next) { + for (p = ebpf_root_of_pids; p; p = p->next) { // if the process is not merged itself // then is is a top level process if (unlikely(!p->merged && !p->target)) @@ -830,8 +906,8 @@ static void apply_apps_groups_targets_inheritance(void) p->sortlist = sortlist++; } - if (all_pids[1]) - all_pids[1]->sortlist = sortlist++; + if (ebpf_all_pids[1]) + ebpf_all_pids[1]->sortlist = sortlist++; // give a target to all merged child processes found = 1; @@ -839,7 +915,7 @@ static void apply_apps_groups_targets_inheritance(void) if (unlikely(debug_enabled)) loops++; found = 0; - for (p = root_of_pids; p; p = p->next) { + for (p = ebpf_root_of_pids; p; p = p->next) { if (unlikely(!p->target && p->merged && p->parent && p->parent->target)) { p->target = p->parent->target; found++; @@ -860,9 +936,9 @@ static void apply_apps_groups_targets_inheritance(void) * * @param root the targets that will be updated. */ -static inline void post_aggregate_targets(struct target *root) +static inline void post_aggregate_targets(struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; for (w = root; w; w = w->next) { if (w->collected_starttime) { if (!w->starttime || w->collected_starttime < w->starttime) { @@ -881,7 +957,7 @@ static inline void post_aggregate_targets(struct target *root) */ static inline void del_pid_entry(pid_t pid) { - struct pid_stat *p = all_pids[pid]; + struct ebpf_pid_stat *p = ebpf_all_pids[pid]; if (unlikely(!p)) { error("attempted to free pid %d that is not allocated.", pid); @@ -890,8 +966,8 @@ static inline void del_pid_entry(pid_t pid) debug_log("process %d %s exited, deleting it.", pid, p->comm); - if (root_of_pids == p) - root_of_pids = p->next; + if (ebpf_root_of_pids == p) + ebpf_root_of_pids = p->next; if (p->next) p->next->prev = p->prev; @@ -903,10 +979,10 @@ static inline void del_pid_entry(pid_t pid) freez(p->io_filename); freez(p->cmdline_filename); freez(p->cmdline); - freez(p); + ebpf_pid_stat_release(p); - all_pids[pid] = NULL; - all_pids_count--; + ebpf_all_pids[pid] = NULL; + ebpf_all_pids_count--; } /** @@ -921,9 +997,9 @@ static inline void del_pid_entry(pid_t pid) */ int get_pid_comm(pid_t pid, size_t n, char *dest) { - struct pid_stat *stat; + struct ebpf_pid_stat *stat; - stat = all_pids[pid]; + stat = ebpf_all_pids[pid]; if (unlikely(stat == NULL)) { return -1; } @@ -991,9 +1067,9 @@ void cleanup_variables_from_other_threads(uint32_t pid) */ void cleanup_exited_pids() { - struct pid_stat *p = NULL; + struct ebpf_pid_stat *p = NULL; - for (p = root_of_pids; p;) { + for (p = ebpf_root_of_pids; p;) { if (!p->updated && (!p->keep || p->keeploops > 0)) { if (unlikely(debug_enabled && (p->keep || p->keeploops))) debug_log(" > CLEANUP cannot keep exited process %d (%s) anymore - removing it.", p->pid, p->comm); @@ -1002,12 +1078,9 @@ void cleanup_exited_pids() p = p->next; // Clean process structure - freez(global_process_stats[r]); + ebpf_process_stat_release(global_process_stats[r]); global_process_stats[r] = NULL; - freez(current_apps_data[r]); - current_apps_data[r] = NULL; - cleanup_variables_from_other_threads(r); del_pid_entry(r); @@ -1060,7 +1133,7 @@ static inline void read_proc_filesystem() * @param p the pid with information to update * @param o never used */ -static inline void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target *o) +static inline void aggregate_pid_on_target(struct ebpf_target *w, struct ebpf_pid_stat *p, struct ebpf_target *o) { UNUSED(o); @@ -1075,7 +1148,7 @@ static inline void aggregate_pid_on_target(struct target *w, struct pid_stat *p, } w->processes++; - struct pid_on_target *pid_on_target = mallocz(sizeof(struct pid_on_target)); + struct ebpf_pid_on_target *pid_on_target = mallocz(sizeof(struct ebpf_pid_on_target)); pid_on_target->pid = p->pid; pid_on_target->next = w->root_pid; w->root_pid = pid_on_target; @@ -1091,10 +1164,10 @@ static inline void aggregate_pid_on_target(struct target *w, struct pid_stat *p, */ void collect_data_for_all_processes(int tbl_pid_stats_fd) { - if (unlikely(!all_pids)) + if (unlikely(!ebpf_all_pids)) return; - struct pid_stat *pids = root_of_pids; // global list of all processes running + struct ebpf_pid_stat *pids = ebpf_root_of_pids; // global list of all processes running while (pids) { if (pids->updated_twice) { pids->read = 0; // mark it as not read, so that collect_data_for_pid() will read it @@ -1113,24 +1186,21 @@ void collect_data_for_all_processes(int tbl_pid_stats_fd) read_proc_filesystem(); uint32_t key; - pids = root_of_pids; // global list of all processes running + pids = ebpf_root_of_pids; // global list of all processes running // while (bpf_map_get_next_key(tbl_pid_stats_fd, &key, &next_key) == 0) { while (pids) { key = pids->pid; ebpf_process_stat_t *w = global_process_stats[key]; if (!w) { - w = callocz(1, sizeof(ebpf_process_stat_t)); + w = ebpf_process_stat_get(); global_process_stats[key] = w; } if (bpf_map_lookup_elem(tbl_pid_stats_fd, &key, w)) { // Clean Process structures - freez(w); + ebpf_process_stat_release(w); global_process_stats[key] = NULL; - freez(current_apps_data[key]); - current_apps_data[key] = NULL; - cleanup_variables_from_other_threads(key); pids = pids->next; @@ -1148,7 +1218,7 @@ void collect_data_for_all_processes(int tbl_pid_stats_fd) // this has to be done, before the cleanup // // concentrate everything on the targets - for (pids = root_of_pids; pids; pids = pids->next) + for (pids = ebpf_root_of_pids; pids; pids = pids->next) aggregate_pid_on_target(pids->target, pids, NULL); post_aggregate_targets(apps_groups_root_target); diff --git a/collectors/ebpf.plugin/ebpf_apps.h b/collectors/ebpf.plugin/ebpf_apps.h index 0bea9122f5..b6e771b82f 100644 --- a/collectors/ebpf.plugin/ebpf_apps.h +++ b/collectors/ebpf.plugin/ebpf_apps.h @@ -3,7 +3,6 @@ #ifndef NETDATA_EBPF_APPS_H #define NETDATA_EBPF_APPS_H 1 -#include "libnetdata/threads/threads.h" #include "libnetdata/locks/locks.h" #include "libnetdata/avl/avl.h" #include "libnetdata/clocks/clocks.h" @@ -34,92 +33,21 @@ #include "ebpf_swap.h" #include "ebpf_vfs.h" -#define MAX_COMPARE_NAME 100 -#define MAX_NAME 100 - -// ---------------------------------------------------------------------------- -// process_pid_stat -// -// Fields read from the kernel ring for a specific PID -// -typedef struct process_pid_stat { - uint64_t pid_tgid; // Unique identifier - uint32_t pid; // process id - - // Count number of calls done for specific function - uint32_t open_call; - uint32_t write_call; - uint32_t writev_call; - uint32_t read_call; - uint32_t readv_call; - uint32_t unlink_call; - uint32_t exit_call; - uint32_t release_call; - uint32_t fork_call; - uint32_t clone_call; - uint32_t close_call; - - // Count number of bytes written or read - uint64_t write_bytes; - uint64_t writev_bytes; - uint64_t readv_bytes; - uint64_t read_bytes; - - // Count number of errors for the specified function - uint32_t open_err; - uint32_t write_err; - uint32_t writev_err; - uint32_t read_err; - uint32_t readv_err; - uint32_t unlink_err; - uint32_t fork_err; - uint32_t clone_err; - uint32_t close_err; -} process_pid_stat_t; - -// ---------------------------------------------------------------------------- -// socket_bandwidth -// -// Fields read from the kernel ring for a specific PID -// -typedef struct socket_bandwidth { - uint64_t first; - uint64_t ct; - uint64_t sent; - uint64_t received; - unsigned char removed; -} socket_bandwidth_t; +#define EBPF_MAX_COMPARE_NAME 100 +#define EBPF_MAX_NAME 100 // ---------------------------------------------------------------------------- // pid_stat // -// structure to store data for each process running -// see: man proc for the description of the fields - -struct pid_fd { - int fd; - -#ifndef __FreeBSD__ - ino_t inode; - char *filename; - uint32_t link_hash; - size_t cache_iterations_counter; - size_t cache_iterations_reset; -#endif -}; - -struct target { - char compare[MAX_COMPARE_NAME + 1]; +struct ebpf_target { + char compare[EBPF_MAX_COMPARE_NAME + 1]; uint32_t comparehash; size_t comparelen; - char id[MAX_NAME + 1]; + char id[EBPF_MAX_NAME + 1]; uint32_t idhash; - char name[MAX_NAME + 1]; - - uid_t uid; - gid_t gid; + char name[EBPF_MAX_NAME + 1]; // Changes made to simplify integration between apps and eBPF. netdata_publish_cachestat_t cachestat; @@ -129,58 +57,9 @@ struct target { netdata_fd_stat_t fd; netdata_publish_shm_t shm; - /* These variables are not necessary for eBPF collector - kernel_uint_t minflt; - kernel_uint_t cminflt; - kernel_uint_t majflt; - kernel_uint_t cmajflt; - kernel_uint_t utime; - kernel_uint_t stime; - kernel_uint_t gtime; - kernel_uint_t cutime; - kernel_uint_t cstime; - kernel_uint_t cgtime; - kernel_uint_t num_threads; - // kernel_uint_t rss; - - kernel_uint_t status_vmsize; - kernel_uint_t status_vmrss; - kernel_uint_t status_vmshared; - kernel_uint_t status_rssfile; - kernel_uint_t status_rssshmem; - kernel_uint_t status_vmswap; - - kernel_uint_t io_logical_bytes_read; - kernel_uint_t io_logical_bytes_written; - // kernel_uint_t io_read_calls; - // kernel_uint_t io_write_calls; - kernel_uint_t io_storage_bytes_read; - kernel_uint_t io_storage_bytes_written; - // kernel_uint_t io_cancelled_write_bytes; - - int *target_fds; - int target_fds_size; - - kernel_uint_t openfiles; - kernel_uint_t openpipes; - kernel_uint_t opensockets; - kernel_uint_t openinotifies; - kernel_uint_t openeventfds; - kernel_uint_t opentimerfds; - kernel_uint_t opensignalfds; - kernel_uint_t openeventpolls; - kernel_uint_t openother; - */ - kernel_uint_t starttime; kernel_uint_t collected_starttime; - /* - kernel_uint_t uptime_min; - kernel_uint_t uptime_sum; - kernel_uint_t uptime_max; - */ - unsigned int processes; // how many processes have been merged to this int exposed; // if set, we have sent this to netdata int hidden; // if set, we set the hidden flag on the dimension @@ -189,20 +68,20 @@ struct target { int starts_with; // if set, the compare string matches only the // beginning of the command - struct pid_on_target *root_pid; // list of aggregated pids for target debugging + struct ebpf_pid_on_target *root_pid; // list of aggregated pids for target debugging - struct target *target; // the one that will be reported to netdata - struct target *next; + struct ebpf_target *target; // the one that will be reported to netdata + struct ebpf_target *next; }; -extern struct target *apps_groups_default_target; -extern struct target *apps_groups_root_target; -extern struct target *users_root_target; -extern struct target *groups_root_target; +extern struct ebpf_target *apps_groups_default_target; +extern struct ebpf_target *apps_groups_root_target; +extern struct ebpf_target *users_root_target; +extern struct ebpf_target *groups_root_target; -struct pid_stat { +struct ebpf_pid_stat { int32_t pid; - char comm[MAX_COMPARE_NAME + 1]; + char comm[EBPF_MAX_COMPARE_NAME + 1]; char *cmdline; uint32_t log_thrown; @@ -210,96 +89,6 @@ struct pid_stat { // char state; int32_t ppid; - // int32_t pgrp; - // int32_t session; - // int32_t tty_nr; - // int32_t tpgid; - // uint64_t flags; - - /* - // these are raw values collected - kernel_uint_t minflt_raw; - kernel_uint_t cminflt_raw; - kernel_uint_t majflt_raw; - kernel_uint_t cmajflt_raw; - kernel_uint_t utime_raw; - kernel_uint_t stime_raw; - kernel_uint_t gtime_raw; // guest_time - kernel_uint_t cutime_raw; - kernel_uint_t cstime_raw; - kernel_uint_t cgtime_raw; // cguest_time - - // these are rates - kernel_uint_t minflt; - kernel_uint_t cminflt; - kernel_uint_t majflt; - kernel_uint_t cmajflt; - kernel_uint_t utime; - kernel_uint_t stime; - kernel_uint_t gtime; - kernel_uint_t cutime; - kernel_uint_t cstime; - kernel_uint_t cgtime; - - // int64_t priority; - // int64_t nice; - int32_t num_threads; - // int64_t itrealvalue; - kernel_uint_t collected_starttime; - // kernel_uint_t vsize; - // kernel_uint_t rss; - // kernel_uint_t rsslim; - // kernel_uint_t starcode; - // kernel_uint_t endcode; - // kernel_uint_t startstack; - // kernel_uint_t kstkesp; - // kernel_uint_t kstkeip; - // uint64_t signal; - // uint64_t blocked; - // uint64_t sigignore; - // uint64_t sigcatch; - // uint64_t wchan; - // uint64_t nswap; - // uint64_t cnswap; - // int32_t exit_signal; - // int32_t processor; - // uint32_t rt_priority; - // uint32_t policy; - // kernel_uint_t delayacct_blkio_ticks; - - uid_t uid; - gid_t gid; - - kernel_uint_t status_vmsize; - kernel_uint_t status_vmrss; - kernel_uint_t status_vmshared; - kernel_uint_t status_rssfile; - kernel_uint_t status_rssshmem; - kernel_uint_t status_vmswap; -#ifndef __FreeBSD__ - ARL_BASE *status_arl; -#endif - - kernel_uint_t io_logical_bytes_read_raw; - kernel_uint_t io_logical_bytes_written_raw; - // kernel_uint_t io_read_calls_raw; - // kernel_uint_t io_write_calls_raw; - kernel_uint_t io_storage_bytes_read_raw; - kernel_uint_t io_storage_bytes_written_raw; - // kernel_uint_t io_cancelled_write_bytes_raw; - - kernel_uint_t io_logical_bytes_read; - kernel_uint_t io_logical_bytes_written; - // kernel_uint_t io_read_calls; - // kernel_uint_t io_write_calls; - kernel_uint_t io_storage_bytes_read; - kernel_uint_t io_storage_bytes_written; - // kernel_uint_t io_cancelled_write_bytes; - */ - - struct pid_fd *fds; // array of fds it uses - size_t fds_size; // the size of the fds array - int children_count; // number of processes directly referencing this unsigned char keep : 1; // 1 when we need to keep this process in memory even after it exited int keeploops; // increases by 1 every time keep is 1 and updated 0 @@ -312,28 +101,21 @@ struct pid_stat { // each process gets a unique number - struct target *target; // app_groups.conf targets - struct target *user_target; // uid based targets - struct target *group_target; // gid based targets + struct ebpf_target *target; // app_groups.conf targets + struct ebpf_target *user_target; // uid based targets + struct ebpf_target *group_target; // gid based targets usec_t stat_collected_usec; usec_t last_stat_collected_usec; - usec_t io_collected_usec; - usec_t last_io_collected_usec; - - kernel_uint_t uptime; - - char *fds_dirname; // the full directory name in /proc/PID/fd - char *stat_filename; char *status_filename; char *io_filename; char *cmdline_filename; - struct pid_stat *parent; - struct pid_stat *prev; - struct pid_stat *next; + struct ebpf_pid_stat *parent; + struct ebpf_pid_stat *prev; + struct ebpf_pid_stat *next; }; // ---------------------------------------------------------------------------- @@ -344,15 +126,15 @@ struct pid_stat { // // - Each entry in /etc/apps_groups.conf creates a target. // - Each user and group used by a process in the system, creates a target. -struct pid_on_target { +struct ebpf_pid_on_target { int32_t pid; - struct pid_on_target *next; + struct ebpf_pid_on_target *next; }; // ---------------------------------------------------------------------------- // Structures used to read information from kernel ring typedef struct ebpf_process_stat { - uint64_t pid_tgid; + uint64_t pid_tgid; // This cannot be removed, because it is used inside kernel ring. uint32_t pid; //Counter @@ -406,16 +188,16 @@ static inline void debug_log_int(const char *fmt, ...) // ---------------------------------------------------------------------------- // Exported variabled and functions // -extern struct pid_stat **all_pids; +extern struct ebpf_pid_stat **ebpf_all_pids; -int ebpf_read_apps_groups_conf(struct target **apps_groups_default_target, - struct target **apps_groups_root_target, - const char *path, - const char *file); +int ebpf_read_apps_groups_conf(struct ebpf_target **apps_groups_default_target, + struct ebpf_target **apps_groups_root_target, + const char *path, + const char *file); -void clean_apps_groups_target(struct target *apps_groups_root_target); +void clean_apps_groups_target(struct ebpf_target *apps_groups_root_target); -size_t zero_all_targets(struct target *root); +size_t zero_all_targets(struct ebpf_target *root); int am_i_running_as_root(); @@ -427,15 +209,30 @@ int get_pid_comm(pid_t pid, size_t n, char *dest); size_t read_processes_statistic_using_pid_on_target(ebpf_process_stat_t **ep, int fd, - struct pid_on_target *pids); + struct ebpf_pid_on_target *pids); -size_t read_bandwidth_statistic_using_pid_on_target(ebpf_bandwidth_t **ep, int fd, struct pid_on_target *pids); +size_t read_bandwidth_statistic_using_pid_on_target(ebpf_bandwidth_t **ep, int fd, struct ebpf_pid_on_target *pids); void collect_data_for_all_processes(int tbl_pid_stats_fd); extern ebpf_process_stat_t **global_process_stats; -extern ebpf_process_publish_apps_t **current_apps_data; extern netdata_publish_cachestat_t **cachestat_pid; extern netdata_publish_dcstat_t **dcstat_pid; +// The default value is at least 32 times smaller than maximum number of PIDs allowed on system, +// this is only possible because we are using ARAL (https://github.com/netdata/netdata/tree/master/libnetdata/aral). +#ifndef NETDATA_EBPF_ALLOC_MAX_PID +# define NETDATA_EBPF_ALLOC_MAX_PID 1024 +#endif +#define NETDATA_EBPF_ALLOC_MIN_ELEMENTS 256 + +extern void ebpf_aral_init(void); + +extern struct ebpf_pid_stat *ebpf_target_get(void); + +extern ebpf_process_stat_t *ebpf_process_stat_get(void); +extern void ebpf_process_stat_release(ebpf_process_stat_t *stat); + +#include "libnetdata/threads/threads.h" + #endif /* NETDATA_EBPF_APPS_H */ diff --git a/collectors/ebpf.plugin/ebpf_cachestat.c b/collectors/ebpf.plugin/ebpf_cachestat.c index b21cc6103d..58c075230c 100644 --- a/collectors/ebpf.plugin/ebpf_cachestat.c +++ b/collectors/ebpf.plugin/ebpf_cachestat.c @@ -521,7 +521,7 @@ static void read_apps_table() { netdata_cachestat_pid_t *cv = cachestat_vector; uint32_t key; - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; int fd = cachestat_maps[NETDATA_CACHESTAT_PID_STATS].map_fd; size_t length = sizeof(netdata_cachestat_pid_t)*ebpf_nprocs; while (pids) { @@ -589,7 +589,7 @@ static void ebpf_update_cachestat_cgroup() */ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_CACHESTAT_HIT_RATIO_CHART, "Hit ratio", EBPF_COMMON_DIMENSION_PERCENTAGE, @@ -694,7 +694,7 @@ static void cachestat_send_global(netdata_publish_cachestat_t *publish) * @param publish output structure. * @param root structure with listed IPs */ -void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct pid_on_target *root) +void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct ebpf_pid_on_target *root) { memcpy(&publish->prev, &publish->current,sizeof(publish->current)); memset(&publish->current, 0, sizeof(publish->current)); @@ -720,9 +720,9 @@ void ebpf_cachestat_sum_pids(netdata_publish_cachestat_t *publish, struct pid_on * * @param root the target list. */ -void ebpf_cache_send_apps_data(struct target *root) +void ebpf_cache_send_apps_data(struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; collected_number value; write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_CACHESTAT_HIT_RATIO_CHART); diff --git a/collectors/ebpf.plugin/ebpf_dcstat.c b/collectors/ebpf.plugin/ebpf_dcstat.c index 75e83214ab..3f26ce6d84 100644 --- a/collectors/ebpf.plugin/ebpf_dcstat.c +++ b/collectors/ebpf.plugin/ebpf_dcstat.c @@ -342,7 +342,7 @@ static void ebpf_dcstat_exit(void *ptr) */ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_DC_HIT_CHART, "Percentage of files inside directory cache", EBPF_COMMON_DIMENSION_PERCENTAGE, @@ -448,7 +448,7 @@ static void read_apps_table() { netdata_dcstat_pid_t *cv = dcstat_vector; uint32_t key; - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; int fd = dcstat_maps[NETDATA_DCSTAT_PID_STATS].map_fd; size_t length = sizeof(netdata_dcstat_pid_t)*ebpf_nprocs; while (pids) { @@ -540,7 +540,7 @@ static void ebpf_dc_read_global_table() * @param publish output structure. * @param root structure with listed IPs */ -void ebpf_dcstat_sum_pids(netdata_publish_dcstat_t *publish, struct pid_on_target *root) +void ebpf_dcstat_sum_pids(netdata_publish_dcstat_t *publish, struct ebpf_pid_on_target *root) { memset(&publish->curr, 0, sizeof(netdata_dcstat_pid_t)); netdata_dcstat_pid_t *dst = &publish->curr; @@ -563,9 +563,9 @@ void ebpf_dcstat_sum_pids(netdata_publish_dcstat_t *publish, struct pid_on_targe * * @param root the target list. */ -void ebpf_dcache_send_apps_data(struct target *root) +void ebpf_dcache_send_apps_data(struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; collected_number value; write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_DC_HIT_CHART); diff --git a/collectors/ebpf.plugin/ebpf_fd.c b/collectors/ebpf.plugin/ebpf_fd.c index 79537066c0..a542b02efc 100644 --- a/collectors/ebpf.plugin/ebpf_fd.c +++ b/collectors/ebpf.plugin/ebpf_fd.c @@ -495,7 +495,7 @@ static void read_apps_table() { netdata_fd_stat_t *fv = fd_vector; uint32_t key; - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; int fd = fd_maps[NETDATA_FD_PID_STATS].map_fd; size_t length = sizeof(netdata_fd_stat_t) * ebpf_nprocs; while (pids) { @@ -560,7 +560,7 @@ static void ebpf_update_fd_cgroup() * @param fd the output * @param root list of pids */ -static void ebpf_fd_sum_pids(netdata_fd_stat_t *fd, struct pid_on_target *root) +static void ebpf_fd_sum_pids(netdata_fd_stat_t *fd, struct ebpf_pid_on_target *root) { uint32_t open_call = 0; uint32_t close_call = 0; @@ -593,9 +593,9 @@ static void ebpf_fd_sum_pids(netdata_fd_stat_t *fd, struct pid_on_target *root) * @param em the structure with thread information * @param root the target list. */ -void ebpf_fd_send_apps_data(ebpf_module_t *em, struct target *root) +void ebpf_fd_send_apps_data(ebpf_module_t *em, struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { ebpf_fd_sum_pids(&w->fd, w->root_pid); @@ -972,7 +972,7 @@ static void fd_collector(ebpf_module_t *em) */ void ebpf_fd_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_FILE_OPEN, "Number of open files", EBPF_COMMON_DIMENSION_CALL, diff --git a/collectors/ebpf.plugin/ebpf_oomkill.c b/collectors/ebpf.plugin/ebpf_oomkill.c index 82420d54e8..fe08f6fe3b 100644 --- a/collectors/ebpf.plugin/ebpf_oomkill.c +++ b/collectors/ebpf.plugin/ebpf_oomkill.c @@ -54,11 +54,11 @@ static void oomkill_cleanup(void *ptr) static void oomkill_write_data(int32_t *keys, uint32_t total) { // for each app, see if it was OOM killed. record as 1 if so otherwise 0. - struct target *w; + struct ebpf_target *w; for (w = apps_groups_root_target; w != NULL; w = w->next) { if (likely(w->exposed && w->processes)) { bool was_oomkilled = false; - struct pid_on_target *pids = w->root_pid; + struct ebpf_pid_on_target *pids = w->root_pid; while (pids) { uint32_t j; for (j = 0; j < total; j++) { @@ -334,7 +334,7 @@ static void oomkill_collector(ebpf_module_t *em) */ void ebpf_oomkill_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_OOMKILL_CHART, "OOM kills", EBPF_COMMON_DIMENSION_KILLS, @@ -361,7 +361,7 @@ void *ebpf_oomkill_thread(void *ptr) em->maps = oomkill_maps; #define NETDATA_DEFAULT_OOM_DISABLED_MSG "Disabling OOMKILL thread, because" - if (unlikely(!all_pids || !em->apps_charts)) { + if (unlikely(!ebpf_all_pids || !em->apps_charts)) { // When we are not running integration with apps, we won't fill necessary variables for this thread to run, so // we need to disable it. if (em->thread->enabled) diff --git a/collectors/ebpf.plugin/ebpf_process.c b/collectors/ebpf.plugin/ebpf_process.c index 9a191d391d..1342260af1 100644 --- a/collectors/ebpf.plugin/ebpf_process.c +++ b/collectors/ebpf.plugin/ebpf_process.c @@ -43,7 +43,6 @@ static netdata_syscall_stat_t process_aggregated_data[NETDATA_KEY_PUBLISH_PROCES static netdata_publish_syscall_t process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_END]; ebpf_process_stat_t **global_process_stats = NULL; -ebpf_process_publish_apps_t **current_apps_data = NULL; int process_enabled = 0; bool publish_internal_metrics = true; @@ -138,19 +137,19 @@ static void ebpf_process_send_data(ebpf_module_t *em) * Sum values for pid * * @param root the structure with all available PIDs - * * @param offset the address that we are reading * * @return it returns the sum of all PIDs */ -long long ebpf_process_sum_values_for_pids(struct pid_on_target *root, size_t offset) +long long ebpf_process_sum_values_for_pids(struct ebpf_pid_on_target *root, size_t offset) { long long ret = 0; while (root) { int32_t pid = root->pid; - ebpf_process_publish_apps_t *w = current_apps_data[pid]; + ebpf_process_stat_t *w = global_process_stats[pid]; if (w) { - ret += get_value_from_structure((char *)w, offset); + uint32_t *value = (uint32_t *)((char *)w + offset); + ret += *value; } root = root->next; @@ -166,13 +165,13 @@ long long ebpf_process_sum_values_for_pids(struct pid_on_target *root, size_t of */ void ebpf_process_remove_pids() { - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; int pid_fd = process_maps[NETDATA_PROCESS_PID_TABLE].map_fd; while (pids) { uint32_t pid = pids->pid; ebpf_process_stat_t *w = global_process_stats[pid]; if (w) { - freez(w); + ebpf_process_stat_release(w); global_process_stats[pid] = NULL; bpf_map_delete_elem(pid_fd, &pid); } @@ -186,15 +185,15 @@ void ebpf_process_remove_pids() * * @param root the target list. */ -void ebpf_process_send_apps_data(struct target *root, ebpf_module_t *em) +void ebpf_process_send_apps_data(struct ebpf_target *root, ebpf_module_t *em) { - struct target *w; + struct ebpf_target *w; collected_number value; write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_PROCESS); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { - value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, create_process)); + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_stat_t, create_process)); write_chart_dimension(w->name, value); } } @@ -203,7 +202,7 @@ void ebpf_process_send_apps_data(struct target *root, ebpf_module_t *em) write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_THREAD); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { - value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, create_thread)); + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_stat_t, create_thread)); write_chart_dimension(w->name, value); } } @@ -212,8 +211,8 @@ void ebpf_process_send_apps_data(struct target *root, ebpf_module_t *em) write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_EXIT); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { - value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, - call_do_exit)); + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_stat_t, + exit_call)); write_chart_dimension(w->name, value); } } @@ -222,8 +221,8 @@ void ebpf_process_send_apps_data(struct target *root, ebpf_module_t *em) write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_CLOSE); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { - value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, - call_release_task)); + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_stat_t, + release_call)); write_chart_dimension(w->name, value); } } @@ -233,7 +232,7 @@ void ebpf_process_send_apps_data(struct target *root, ebpf_module_t *em) write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_ERROR); for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { - value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_stat_t, task_err)); write_chart_dimension(w->name, value); } @@ -283,38 +282,6 @@ static void read_hash_global_tables() process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_CLONE].ecall = res[NETDATA_KEY_ERROR_SYS_CLONE]; } -/** - * Read the hash table and store data to allocated vectors. - */ -static void ebpf_process_update_apps_data() -{ - struct pid_stat *pids = root_of_pids; - while (pids) { - uint32_t current_pid = pids->pid; - ebpf_process_stat_t *ps = global_process_stats[current_pid]; - if (!ps) { - pids = pids->next; - continue; - } - - ebpf_process_publish_apps_t *cad = current_apps_data[current_pid]; - if (!cad) { - cad = callocz(1, sizeof(ebpf_process_publish_apps_t)); - current_apps_data[current_pid] = cad; - } - - //Read data - cad->call_do_exit = ps->exit_call; - cad->call_release_task = ps->release_call; - cad->create_process = ps->create_process; - cad->create_thread = ps->create_thread; - - cad->task_err = ps->task_err; - - pids = pids->next; - } -} - /** * Update cgroup * @@ -532,7 +499,7 @@ static void ebpf_create_statistic_charts(ebpf_module_t *em) */ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_TASK_PROCESS, "Process started", EBPF_COMMON_DIMENSION_CALL, @@ -591,12 +558,12 @@ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr) * * @param root a pointer for the targets. */ -static void ebpf_create_apps_charts(struct target *root) +static void ebpf_create_apps_charts(struct ebpf_target *root) { - if (unlikely(!all_pids)) + if (unlikely(!ebpf_all_pids)) return; - struct target *w; + struct ebpf_target *w; int newly_added = 0; for (w = root; w; w = w->next) { @@ -604,7 +571,7 @@ static void ebpf_create_apps_charts(struct target *root) continue; if (unlikely(w->processes && (debug_enabled || w->debug_enabled))) { - struct pid_on_target *pid_on_target; + struct ebpf_pid_on_target *pid_on_target; fprintf( stderr, "ebpf.plugin: target '%s' has aggregated %u process%s:", w->name, w->processes, @@ -1079,11 +1046,7 @@ static void process_collector(ebpf_module_t *em) pthread_mutex_lock(&collect_data_mutex); ebpf_create_apps_charts(apps_groups_root_target); - if (all_pids_count > 0) { - if (apps_enabled) { - ebpf_process_update_apps_data(); - } - + if (ebpf_all_pids_count > 0) { if (cgroups && shm_ebpf_cgroup.header) { ebpf_update_process_cgroup(); } @@ -1133,7 +1096,6 @@ static void ebpf_process_allocate_global_vectors(size_t length) process_hash_values = callocz(ebpf_nprocs, sizeof(netdata_idx_t)); global_process_stats = callocz((size_t)pid_max, sizeof(ebpf_process_stat_t *)); - current_apps_data = callocz((size_t)pid_max, sizeof(ebpf_process_publish_apps_t *)); } static void change_syscalls() diff --git a/collectors/ebpf.plugin/ebpf_process.h b/collectors/ebpf.plugin/ebpf_process.h index 6fded16fc2..5f119aea1f 100644 --- a/collectors/ebpf.plugin/ebpf_process.h +++ b/collectors/ebpf.plugin/ebpf_process.h @@ -85,17 +85,6 @@ typedef enum netdata_publish_process { NETDATA_KEY_PUBLISH_PROCESS_END } netdata_publish_process_t; -typedef struct ebpf_process_publish_apps { - // Number of calls during the last read - uint64_t call_do_exit; - uint64_t call_release_task; - uint64_t create_process; - uint64_t create_thread; - - // Number of errors during the last read - uint64_t task_err; -} ebpf_process_publish_apps_t; - enum ebpf_process_tables { NETDATA_PROCESS_PID_TABLE, NETDATA_PROCESS_GLOBAL_TABLE, diff --git a/collectors/ebpf.plugin/ebpf_shm.c b/collectors/ebpf.plugin/ebpf_shm.c index 4057eff7fa..c2ec943369 100644 --- a/collectors/ebpf.plugin/ebpf_shm.c +++ b/collectors/ebpf.plugin/ebpf_shm.c @@ -411,7 +411,7 @@ static void read_apps_table() { netdata_publish_shm_t *cv = shm_vector; uint32_t key; - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; int fd = shm_maps[NETDATA_PID_SHM_TABLE].map_fd; size_t length = sizeof(netdata_publish_shm_t)*ebpf_nprocs; while (pids) { @@ -487,7 +487,7 @@ static void ebpf_shm_read_global_table() /** * Sum values for all targets. */ -static void ebpf_shm_sum_pids(netdata_publish_shm_t *shm, struct pid_on_target *root) +static void ebpf_shm_sum_pids(netdata_publish_shm_t *shm, struct ebpf_pid_on_target *root) { while (root) { int32_t pid = root->pid; @@ -513,9 +513,9 @@ static void ebpf_shm_sum_pids(netdata_publish_shm_t *shm, struct pid_on_target * * * @param root the target list. */ -void ebpf_shm_send_apps_data(struct target *root) +void ebpf_shm_send_apps_data(struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { ebpf_shm_sum_pids(&w->shm, w->root_pid); @@ -895,7 +895,7 @@ static void shm_collector(ebpf_module_t *em) */ void ebpf_shm_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_SHMGET_CHART, "Calls to syscall <code>shmget(2)</code>.", EBPF_COMMON_DIMENSION_CALL, diff --git a/collectors/ebpf.plugin/ebpf_socket.c b/collectors/ebpf.plugin/ebpf_socket.c index 1954be7148..6b359888d0 100644 --- a/collectors/ebpf.plugin/ebpf_socket.c +++ b/collectors/ebpf.plugin/ebpf_socket.c @@ -958,7 +958,7 @@ static void ebpf_socket_send_data(ebpf_module_t *em) * * @return it returns the sum of all PIDs */ -long long ebpf_socket_sum_values_for_pids(struct pid_on_target *root, size_t offset) +long long ebpf_socket_sum_values_for_pids(struct ebpf_pid_on_target *root, size_t offset) { long long ret = 0; while (root) { @@ -980,11 +980,11 @@ long long ebpf_socket_sum_values_for_pids(struct pid_on_target *root, size_t off * @param em the structure with thread information * @param root the target list. */ -void ebpf_socket_send_apps_data(ebpf_module_t *em, struct target *root) +void ebpf_socket_send_apps_data(ebpf_module_t *em, struct ebpf_target *root) { UNUSED(em); - struct target *w; + struct ebpf_target *w; collected_number value; write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V4); @@ -1217,7 +1217,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) */ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; int order = 20080; ebpf_create_charts_on_apps(NETDATA_NET_APPS_CONNECTION_TCP_V4, "Calls to tcp_v4_connection", EBPF_COMMON_DIMENSION_CONNECTIONS, @@ -2275,7 +2275,7 @@ static void ebpf_socket_update_apps_data() int fd = socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH].map_fd; ebpf_bandwidth_t *eb = bandwidth_vector; uint32_t key; - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; while (pids) { key = pids->pid; diff --git a/collectors/ebpf.plugin/ebpf_swap.c b/collectors/ebpf.plugin/ebpf_swap.c index 059efb63b2..57a46f42f9 100644 --- a/collectors/ebpf.plugin/ebpf_swap.c +++ b/collectors/ebpf.plugin/ebpf_swap.c @@ -341,7 +341,7 @@ static void read_apps_table() { netdata_publish_swap_t *cv = swap_vector; uint32_t key; - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; int fd = swap_maps[NETDATA_PID_SWAP_TABLE].map_fd; size_t length = sizeof(netdata_publish_swap_t)*ebpf_nprocs; while (pids) { @@ -410,7 +410,7 @@ static void ebpf_swap_read_global_table() * @param swap * @param root */ -static void ebpf_swap_sum_pids(netdata_publish_swap_t *swap, struct pid_on_target *root) +static void ebpf_swap_sum_pids(netdata_publish_swap_t *swap, struct ebpf_pid_on_target *root) { uint64_t local_read = 0; uint64_t local_write = 0; @@ -435,9 +435,9 @@ static void ebpf_swap_sum_pids(netdata_publish_swap_t *swap, struct pid_on_targe * * @param root the target list. */ -void ebpf_swap_send_apps_data(struct target *root) +void ebpf_swap_send_apps_data(struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { ebpf_swap_sum_pids(&w->swap, w->root_pid); @@ -707,7 +707,7 @@ static void swap_collector(ebpf_module_t *em) */ void ebpf_swap_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_MEM_SWAP_READ_CHART, "Calls to function <code>swap_readpage</code>.", EBPF_COMMON_DIMENSION_CALL, diff --git a/collectors/ebpf.plugin/ebpf_vfs.c b/collectors/ebpf.plugin/ebpf_vfs.c index b3c0ba45d4..e22c0cade1 100644 --- a/collectors/ebpf.plugin/ebpf_vfs.c +++ b/collectors/ebpf.plugin/ebpf_vfs.c @@ -540,7 +540,7 @@ static void ebpf_vfs_read_global_table() * @param swap output structure * @param root link list with structure to be used */ -static void ebpf_vfs_sum_pids(netdata_publish_vfs_t *vfs, struct pid_on_target *root) +static void ebpf_vfs_sum_pids(netdata_publish_vfs_t *vfs, struct ebpf_pid_on_target *root) { netdata_publish_vfs_t accumulator; memset(&accumulator, 0, sizeof(accumulator)); @@ -606,9 +606,9 @@ static void ebpf_vfs_sum_pids(netdata_publish_vfs_t *vfs, struct pid_on_target * * @param em the structure with thread information * @param root the target list. */ -void ebpf_vfs_send_apps_data(ebpf_module_t *em, struct target *root) +void ebpf_vfs_send_apps_data(ebpf_module_t *em, struct ebpf_target *root) { - struct target *w; + struct ebpf_target *w; for (w = root; w; w = w->next) { if (unlikely(w->exposed && w->processes)) { ebpf_vfs_sum_pids(&w->vfs, w->root_pid); @@ -787,7 +787,7 @@ static void vfs_fill_pid(uint32_t current_pid, netdata_publish_vfs_t *publish) */ static void ebpf_vfs_read_apps() { - struct pid_stat *pids = root_of_pids; + struct ebpf_pid_stat *pids = ebpf_root_of_pids; netdata_publish_vfs_t *vv = vfs_vector; int fd = vfs_maps[NETDATA_VFS_PID].map_fd; size_t length = sizeof(netdata_publish_vfs_t) * ebpf_nprocs; @@ -1683,7 +1683,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em) **/ void ebpf_vfs_create_apps_charts(struct ebpf_module *em, void *ptr) { - struct target *root = ptr; + struct ebpf_target *root = ptr; ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_FILE_DELETED, "Files deleted", diff --git a/libnetdata/libnetdata.c b/libnetdata/libnetdata.c index 66d41bd546..2633eeaab4 100644 --- a/libnetdata/libnetdata.c +++ b/libnetdata/libnetdata.c @@ -225,10 +225,6 @@ void posix_memfree(void *ptr) { libc_free(ptr); } -#define MALLOC_ALIGNMENT (sizeof(uintptr_t) * 2) -#define size_t_atomic_count(op, var, size) __atomic_## op ##_fetch(&(var), size, __ATOMIC_RELAXED) -#define size_t_atomic_bytes(op, var, size) __atomic_## op ##_fetch(&(var), ((size) % MALLOC_ALIGNMENT)?((size) + MALLOC_ALIGNMENT - ((size) % MALLOC_ALIGNMENT)):(size), __ATOMIC_RELAXED) - struct malloc_header_signature { uint32_t magic; uint32_t size; diff --git a/libnetdata/libnetdata.h b/libnetdata/libnetdata.h index 65f1b5185a..94d6e31eb1 100644 --- a/libnetdata/libnetdata.h +++ b/libnetdata/libnetdata.h @@ -32,6 +32,9 @@ extern "C" { #define OS_FREEBSD 2 #define OS_MACOS 3 +#define MALLOC_ALIGNMENT (sizeof(uintptr_t) * 2) +#define size_t_atomic_count(op, var, size) __atomic_## op ##_fetch(&(var), size, __ATOMIC_RELAXED) +#define size_t_atomic_bytes(op, var, size) __atomic_## op ##_fetch(&(var), ((size) % MALLOC_ALIGNMENT)?((size) + MALLOC_ALIGNMENT - ((size) % MALLOC_ALIGNMENT)):(size), __ATOMIC_RELAXED) // ---------------------------------------------------------------------------- // system include files for all netdata C programs