master
c 126 lines 4.12 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "debugfs_plugin.h"
4
5 #define NETDATA_ORDER_FRAGMENTATION 11
6
7 static char *orders[NETDATA_ORDER_FRAGMENTATION] = { "order0", "order1", "order2", "order3", "order4",
8 "order5", "order6", "order7", "order8", "order9",
9 "order10"
10 };
11
12 static struct netdata_extrafrag {
13 char *node_zone;
14 uint32_t hash;
15
16 char *id;
17
18 collected_number orders[NETDATA_ORDER_FRAGMENTATION];
19
20 struct netdata_extrafrag *next;
21 } *netdata_extrafrags_root = NULL;
22
23 static struct netdata_extrafrag *find_or_create_extrafrag(const char *name)
24 {
25 struct netdata_extrafrag *extrafrag;
26 uint32_t hash = simple_hash(name);
27
28 // search it, from beginning to the end
29 for (extrafrag = netdata_extrafrags_root ; extrafrag ; extrafrag = extrafrag->next) {
30 if (unlikely(hash == extrafrag->hash && !strcmp(name, extrafrag->node_zone))) {
31 return extrafrag;
32 }
33 }
34
35 extrafrag = callocz(1, sizeof(struct netdata_extrafrag));
36 extrafrag->node_zone = strdupz(name);
37 extrafrag->hash = hash;
38
39 if (netdata_extrafrags_root) {
40 struct netdata_extrafrag *last_node;
41 for (last_node = netdata_extrafrags_root; last_node->next ; last_node = last_node->next);
42
43 last_node->next = extrafrag;
44 } else
45 netdata_extrafrags_root = extrafrag;
46
47
48 return extrafrag;
49 }
50
51 static void extfrag_send_chart(char *chart_id, collected_number *values)
52 {
53 int i;
54 printf(PLUGINSD_KEYWORD_BEGIN " mem.fragmentation_index_%s\n", chart_id);
55
56 for (i = 0; i < NETDATA_ORDER_FRAGMENTATION; i++)
57 printf(PLUGINSD_KEYWORD_SET " %s = %lld\n", orders[i], values[i]);
58
59 printf(PLUGINSD_KEYWORD_END "\n");
60 }
61
62 int do_module_numa_extfrag(int update_every, const char *name) {
63 static procfile *ff = NULL;;
64
65 if (unlikely(!ff)) {
66 char filename[FILENAME_MAX + 1];
67 snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/debug/extfrag/extfrag_index");
68
69 ff = procfile_open(filename, " \t,", PROCFILE_FLAG_DEFAULT);
70 if (unlikely(!ff))
71 return 1;
72 }
73
74 ff = procfile_readall(ff);
75 if (unlikely(!ff))
76 return 1;
77
78 size_t l, i, j, lines = procfile_lines(ff);
79 for (l = 0; l < lines; l++) {
80 char chart_id[64];
81 char zone_lowercase[32];
82 if (unlikely(procfile_linewords(ff, l) < 15)) continue;
83 char *zone = procfile_lineword(ff, l, 3);
84 strncpyz(zone_lowercase, zone, 31);
85 debugfs2lower(zone_lowercase);
86
87 char *id = procfile_lineword(ff, l, 1);
88 snprintfz(chart_id, 63, "node_%s_%s", id, zone_lowercase);
89 debugfs2lower(chart_id);
90
91 struct netdata_extrafrag *extrafrag = find_or_create_extrafrag(chart_id);
92 collected_number *line_orders = extrafrag->orders;
93 for (i = 4, j = 0 ; i < 15; i++, j++) {
94 NETDATA_DOUBLE value = str2ndd(procfile_lineword(ff, l, i), NULL);
95 line_orders[j] = (collected_number) (value * 1000.0);
96 }
97
98 netdata_mutex_lock(&stdout_mutex);
99
100 if (unlikely(!extrafrag->id)) {
101 extrafrag->id = extrafrag->node_zone;
102 printf(
103 PLUGINSD_KEYWORD_CHART " mem.fragmentation_index_%s '' 'Memory fragmentation index for each order' 'index' 'fragmentation' 'mem.numa_node_zone_fragmentation_index' 'line' %d %d '' 'debugfs.plugin' '%s'\n",
104 extrafrag->node_zone,
105 NETDATA_CHART_PRIO_MEM_FRAGMENTATION,
106 update_every,
107 name);
108
109 for (i = 0; i < NETDATA_ORDER_FRAGMENTATION; i++)
110 printf(PLUGINSD_KEYWORD_DIMENSION " '%s' '%s' absolute 1 1000 ''\n", orders[i], orders[i]);
111
112 printf(
113 PLUGINSD_KEYWORD_CLABEL " 'numa_node' 'node%s' 1\n"
114 PLUGINSD_KEYWORD_CLABEL " 'zone' '%s' 1\n"
115 PLUGINSD_KEYWORD_CLABEL_COMMIT "\n",
116 id,
117 zone);
118 }
119 extfrag_send_chart(chart_id, line_orders);
120
121 fflush(stdout);
122 netdata_mutex_unlock(&stdout_mutex);
123 }
124
125 return 0;
126 }