summaryrefslogtreecommitdiffstats
path: root/libnetdata/ebpf/ebpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/ebpf/ebpf.c')
-rw-r--r--libnetdata/ebpf/ebpf.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c
index 7cad597858..ee3ce3e003 100644
--- a/libnetdata/ebpf/ebpf.c
+++ b/libnetdata/ebpf/ebpf.c
@@ -454,6 +454,91 @@ void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em)
ebpf_stats_targets(report, em->targets);
}
+/**
+ * Update Kernel memory with memory
+ *
+ * This algorithm is an adaptation of https://elixir.bootlin.com/linux/v6.1.14/source/tools/bpf/bpftool/common.c#L402
+ * to get 'memlock' data and update report.
+ *
+ * @param report the output structure
+ * @param map pointer to a map.
+ * @param action What action will be done with this map.
+ */
+void ebpf_update_kernel_memory(ebpf_plugin_stats_t *report, ebpf_local_maps_t *map, ebpf_stats_action_t action)
+{
+ char filename[FILENAME_MAX+1];
+ snprintfz(filename, FILENAME_MAX, "/proc/self/fdinfo/%d", map->map_fd);
+ procfile *ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
+ if(unlikely(!ff)) {
+ error("Cannot open %s", filename);
+ return;
+ }
+
+ ff = procfile_readall(ff);
+ if(unlikely(!ff))
+ return;
+
+ unsigned long j, lines = procfile_lines(ff);
+ char *memlock = { "memlock" };
+ for (j = 0; j < lines ; j++) {
+ char *cmp = procfile_lineword(ff, j,0);
+ if (!strncmp(memlock, cmp, 7)) {
+ uint64_t memsize = (uint64_t) str2l(procfile_lineword(ff, j,1));
+ switch (action) {
+ case EBPF_ACTION_STAT_ADD: {
+ report->memlock_kern += memsize;
+ report->hash_tables += 1;
+#ifdef NETDATA_DEV_MODE
+ info("Hash table %u: %s (FD = %d) is consuming %lu bytes totalizing %lu bytes",
+ report->hash_tables, map->name, map->map_fd, memsize, report->memlock_kern);
+#endif
+ break;
+ }
+ case EBPF_ACTION_STAT_REMOVE: {
+ report->memlock_kern -= memsize;
+ report->hash_tables -= 1;
+#ifdef NETDATA_DEV_MODE
+ info("Hash table %s (FD = %d) was removed releasing %lu bytes, now we have %u tables loaded totalizing %lu bytes.",
+ map->name, map->map_fd, memsize, report->hash_tables, report->memlock_kern);
+#endif
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ procfile_close(ff);
+}
+
+/**
+ * Update Kernel memory with memory
+ *
+ * This algorithm is an adaptation of https://elixir.bootlin.com/linux/v6.1.14/source/tools/bpf/bpftool/common.c#L402
+ * to get 'memlock' data and update report.
+ *
+ * @param report the output structure
+ * @param map pointer to a map. Last map must fish with name = NULL
+ */
+void ebpf_update_kernel_memory_with_vector(ebpf_plugin_stats_t *report, ebpf_local_maps_t *maps)
+{
+ if (!maps)
+ return;
+
+ ebpf_local_maps_t *map;
+ int i = 0;
+ for (map = &maps[i]; maps[i].name; i++, map = &maps[i]) {
+ int fd = map->map_fd;
+ if (fd == ND_EBPF_MAP_FD_NOT_INITIALIZED)
+ continue;
+
+ ebpf_update_kernel_memory(report, map, EBPF_ACTION_STAT_ADD);
+ }
+}
+
//----------------------------------------------------------------------------------------------------------------------
void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em)