summaryrefslogtreecommitdiffstats
path: root/collectors/ebpf.plugin/ebpf_swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/ebpf.plugin/ebpf_swap.c')
-rw-r--r--collectors/ebpf.plugin/ebpf_swap.c190
1 files changed, 188 insertions, 2 deletions
diff --git a/collectors/ebpf.plugin/ebpf_swap.c b/collectors/ebpf.plugin/ebpf_swap.c
index 906c83da..7d842335 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;
}