summaryrefslogtreecommitdiffstats
path: root/collectors/debugfs.plugin/debugfs_extfrag.c
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/debugfs.plugin/debugfs_extfrag.c')
-rw-r--r--collectors/debugfs.plugin/debugfs_extfrag.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/collectors/debugfs.plugin/debugfs_extfrag.c b/collectors/debugfs.plugin/debugfs_extfrag.c
new file mode 100644
index 000000000..75da4deca
--- /dev/null
+++ b/collectors/debugfs.plugin/debugfs_extfrag.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "debugfs_plugin.h"
+
+#define NETDATA_ORDER_FRAGMENTATION 11
+
+static char *orders[NETDATA_ORDER_FRAGMENTATION] = { "order0", "order1", "order2", "order3", "order4",
+ "order5", "order6", "order7", "order8", "order9",
+ "order10"
+};
+
+static struct netdata_extrafrag {
+ char *node_zone;
+ uint32_t hash;
+
+ char *id;
+
+ collected_number orders[NETDATA_ORDER_FRAGMENTATION];
+
+ struct netdata_extrafrag *next;
+} *netdata_extrafrags_root = NULL;
+
+static struct netdata_extrafrag *find_or_create_extrafrag(const char *name)
+{
+ struct netdata_extrafrag *extrafrag;
+ uint32_t hash = simple_hash(name);
+
+ // search it, from beginning to the end
+ for (extrafrag = netdata_extrafrags_root ; extrafrag ; extrafrag = extrafrag->next) {
+ if (unlikely(hash == extrafrag->hash && !strcmp(name, extrafrag->node_zone))) {
+ return extrafrag;
+ }
+ }
+
+ extrafrag = callocz(1, sizeof(struct netdata_extrafrag));
+ extrafrag->node_zone = strdupz(name);
+ extrafrag->hash = hash;
+
+ if (netdata_extrafrags_root) {
+ struct netdata_extrafrag *last_node;
+ for (last_node = netdata_extrafrags_root; last_node->next ; last_node = last_node->next);
+
+ last_node->next = extrafrag;
+ } else
+ netdata_extrafrags_root = extrafrag;
+
+
+ return extrafrag;
+}
+
+static void extfrag_send_chart(char *chart_id, collected_number *values)
+{
+ int i;
+ fprintf(stdout, "BEGIN mem.fragmentation_index_%s\n", chart_id);
+ for (i = 0; i < NETDATA_ORDER_FRAGMENTATION; i++) {
+ fprintf(stdout, "SET %s = %lld\n", orders[i], values[i]);
+ }
+ fprintf(stdout, "END\n");
+ fflush(stdout);
+}
+
+int do_debugfs_extfrag(int update_every, const char *name) {
+ static procfile *ff = NULL;
+ static int chart_order = NETDATA_CHART_PRIO_MEM_FRAGMENTATION;
+
+ if (unlikely(!ff)) {
+ char filename[FILENAME_MAX + 1];
+ snprintfz(filename,
+ FILENAME_MAX,
+ "%s%s",
+ netdata_configured_host_prefix,
+ "/sys/kernel/debug/extfrag/extfrag_index");
+
+ ff = procfile_open(filename, " \t,", PROCFILE_FLAG_DEFAULT);
+ if (unlikely(!ff)) return 1;
+ }
+
+ ff = procfile_readall(ff);
+ if (unlikely(!ff)) return 1;
+
+ size_t l, i, j, lines = procfile_lines(ff);
+ for (l = 0; l < lines; l++) {
+ char chart_id[64];
+ char zone_lowercase[32];
+ if (unlikely(procfile_linewords(ff, l) < 15)) continue;
+ char *zone = procfile_lineword(ff, l, 3);
+ strncpyz(zone_lowercase, zone, 31);
+ debugfs2lower(zone_lowercase);
+
+ char *id = procfile_lineword(ff, l, 1);
+ snprintfz(chart_id, 63, "node_%s_%s", id, zone_lowercase);
+ debugfs2lower(chart_id);
+
+ struct netdata_extrafrag *extrafrag = find_or_create_extrafrag(chart_id);
+ collected_number *line_orders = extrafrag->orders;
+ for (i = 4, j = 0 ; i < 15; i++, j++) {
+ NETDATA_DOUBLE value = str2ndd(procfile_lineword(ff, l, i), NULL);
+ line_orders[j] = (collected_number) (value * 1000.0);
+ }
+
+ if (unlikely(!extrafrag->id)) {
+ extrafrag->id = extrafrag->node_zone;
+ fprintf(
+ stdout,
+ "CHART mem.fragmentation_index_%s '' 'Memory fragmentation index for each order' 'index' 'fragmentation' 'mem.fragmentation_index_%s' 'line' %d %d '' 'debugfs.plugin' '%s'\n",
+ extrafrag->node_zone,
+ zone_lowercase,
+ chart_order++, // FIXME: the same zones must have the same order
+ update_every,
+ name);
+ for (i = 0; i < NETDATA_ORDER_FRAGMENTATION; i++) {
+ fprintf(stdout, "DIMENSION '%s' '%s' absolute 1 1000 ''\n", orders[i], orders[i]);
+ }
+ fprintf(stdout,
+ "CLABEL 'numa_node' 'node%s' 1\n"
+ "CLABEL_COMMIT\n",
+ id);
+ }
+ extfrag_send_chart(chart_id, line_orders);
+ }
+
+ return 0;
+}