diff options
Diffstat (limited to 'collectors/ebpf.plugin/ebpf_swap.c')
-rw-r--r-- | collectors/ebpf.plugin/ebpf_swap.c | 190 |
1 files changed, 188 insertions, 2 deletions
diff --git a/collectors/ebpf.plugin/ebpf_swap.c b/collectors/ebpf.plugin/ebpf_swap.c index 906c83da5..7d8423358 100644 --- a/collectors/ebpf.plugin/ebpf_swap.c +++ b/collectors/ebpf.plugin/ebpf_swap.c @@ -41,6 +41,154 @@ static struct bpf_object *objects = NULL; struct netdata_static_thread swap_threads = {"SWAP KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; +netdata_ebpf_targets_t swap_targets[] = { {.name = "swap_readpage", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "swap_writepage", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}}; + +#ifdef LIBBPF_MAJOR_VERSION +#include "includes/swap.skel.h" // BTF code + +static struct swap_bpf *bpf_obj = NULL; + +/** + * Disable probe + * + * Disable all probes to use exclusively another method. + * + * @param obj is the main structure for bpf objects + */ +static void ebpf_swap_disable_probe(struct swap_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_swap_readpage_probe, false); + bpf_program__set_autoload(obj->progs.netdata_swap_writepage_probe, false); +} + +/* + * Disable trampoline + * + * Disable all trampoline to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_swap_disable_trampoline(struct swap_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_swap_readpage_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_swap_writepage_fentry, false); +} + +/** + * Set trampoline target + * + * Set the targets we will monitor. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_swap_set_trampoline_target(struct swap_bpf *obj) +{ + bpf_program__set_attach_target(obj->progs.netdata_swap_readpage_fentry, 0, + swap_targets[NETDATA_KEY_SWAP_READPAGE_CALL].name); + + bpf_program__set_attach_target(obj->progs.netdata_swap_writepage_fentry, 0, + swap_targets[NETDATA_KEY_SWAP_WRITEPAGE_CALL].name); +} + +/** + * Mount Attach Probe + * + * Attach probes to target + * + * @param obj is the main structure for bpf objects. + * + * @return It returns 0 on success and -1 otherwise. + */ +static int ebpf_swap_attach_kprobe(struct swap_bpf *obj) +{ + obj->links.netdata_swap_readpage_probe = bpf_program__attach_kprobe(obj->progs.netdata_swap_readpage_probe, + false, + swap_targets[NETDATA_KEY_SWAP_READPAGE_CALL].name); + int ret = libbpf_get_error(obj->links.netdata_swap_readpage_probe); + if (ret) + return -1; + + obj->links.netdata_swap_writepage_probe = bpf_program__attach_kprobe(obj->progs.netdata_swap_writepage_probe, + false, + swap_targets[NETDATA_KEY_SWAP_WRITEPAGE_CALL].name); + ret = libbpf_get_error(obj->links.netdata_swap_writepage_probe); + if (ret) + return -1; + + return 0; +} + +/** + * Set hash tables + * + * Set the values for maps according the value given by kernel. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_swap_set_hash_tables(struct swap_bpf *obj) +{ + swap_maps[NETDATA_PID_SWAP_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_pid_swap); + swap_maps[NETDATA_SWAP_CONTROLLER].map_fd = bpf_map__fd(obj->maps.swap_ctrl); + swap_maps[NETDATA_SWAP_GLOBAL_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_swap); +} + +/** + * Adjust Map Size + * + * Resize maps according input from users. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + */ +static void ebpf_swap_adjust_map_size(struct swap_bpf *obj, ebpf_module_t *em) +{ + ebpf_update_map_size(obj->maps.tbl_pid_swap, &swap_maps[NETDATA_PID_SWAP_TABLE], + em, bpf_map__name(obj->maps.tbl_pid_swap)); +} + +/** + * Load and attach + * + * Load and attach the eBPF code in kernel. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + * + * @return it returns 0 on succes and -1 otherwise + */ +static inline int ebpf_swap_load_and_attach(struct swap_bpf *obj, ebpf_module_t *em) +{ + netdata_ebpf_targets_t *mt = em->targets; + netdata_ebpf_program_loaded_t test = mt[NETDATA_KEY_SWAP_READPAGE_CALL].mode; + + if (test == EBPF_LOAD_TRAMPOLINE) { + ebpf_swap_disable_probe(obj); + + ebpf_swap_set_trampoline_target(obj); + } else { + ebpf_swap_disable_trampoline(obj); + } + + int ret = swap_bpf__load(obj); + if (ret) { + return ret; + } + + ebpf_swap_adjust_map_size(obj, em); + + ret = (test == EBPF_LOAD_TRAMPOLINE) ? swap_bpf__attach(obj) : ebpf_swap_attach_kprobe(obj); + if (!ret) { + ebpf_swap_set_hash_tables(obj); + + ebpf_update_controller(swap_maps[NETDATA_SWAP_CONTROLLER].map_fd, em); + } + + return ret; +} +#endif + /***************************************************************** * * FUNCTIONS TO CLOSE THE THREAD @@ -92,6 +240,10 @@ static void ebpf_swap_cleanup(void *ptr) } bpf_object__close(objects); } +#ifdef LIBBPF_MAJOR_VERSION + else if (bpf_obj) + swap_bpf__destroy(bpf_obj); +#endif } /***************************************************************** @@ -654,6 +806,38 @@ static void ebpf_create_swap_charts(int update_every) update_every, NETDATA_EBPF_MODULE_NAME_SWAP); } +/* + * Load BPF + * + * Load BPF files. + * + * @param em the structure with configuration + */ +static int ebpf_swap_load_bpf(ebpf_module_t *em) +{ + int ret = 0; + if (em->load == EBPF_LOAD_LEGACY) { + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); + if (!probe_links) { + ret = -1; + } + } +#ifdef LIBBPF_MAJOR_VERSION + else { + bpf_obj = swap_bpf__open(); + if (!bpf_obj) + ret = -1; + else + ret = ebpf_swap_load_and_attach(bpf_obj, em); + } +#endif + + if (ret) + error("%s %s", EBPF_DEFAULT_ERROR_MSG, em->thread_name); + + return ret; +} + /** * SWAP thread * @@ -675,8 +859,10 @@ void *ebpf_swap_thread(void *ptr) if (!em->enabled) goto endswap; - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { +#ifdef LIBBPF_MAJOR_VERSION + ebpf_adjust_thread_load(em, default_btf); +#endif + if (ebpf_swap_load_bpf(em)) { em->enabled = CONFIG_BOOLEAN_NO; goto endswap; } |