master
c 195 lines 9.13 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "plugin_proc.h"
4
5 #define PLUGIN_PROC_MODULE_KSM_NAME "/sys/kernel/mm/ksm"
6
7 typedef struct ksm_name_value {
8 char filename[FILENAME_MAX + 1];
9 unsigned long long value;
10 } KSM_NAME_VALUE;
11
12 #define PAGES_SHARED 0
13 #define PAGES_SHARING 1
14 #define PAGES_UNSHARED 2
15 #define PAGES_VOLATILE 3
16 // #define PAGES_TO_SCAN 4
17
18 KSM_NAME_VALUE values[] = {
19 [PAGES_SHARED] = { "/sys/kernel/mm/ksm/pages_shared", 0ULL },
20 [PAGES_SHARING] = { "/sys/kernel/mm/ksm/pages_sharing", 0ULL },
21 [PAGES_UNSHARED] = { "/sys/kernel/mm/ksm/pages_unshared", 0ULL },
22 [PAGES_VOLATILE] = { "/sys/kernel/mm/ksm/pages_volatile", 0ULL },
23 // [PAGES_TO_SCAN] = { "/sys/kernel/mm/ksm/pages_to_scan", 0ULL },
24 };
25
26 int do_sys_kernel_mm_ksm(int update_every, usec_t dt) {
27 (void)dt;
28 static procfile *ff_pages_shared = NULL, *ff_pages_sharing = NULL, *ff_pages_unshared = NULL, *ff_pages_volatile = NULL/*, *ff_pages_to_scan = NULL*/;
29 static unsigned long page_size = 0;
30
31 if(unlikely(page_size == 0))
32 page_size = (unsigned long)sysconf(_SC_PAGESIZE);
33
34 if(unlikely(!ff_pages_shared)) {
35 snprintfz(values[PAGES_SHARED].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_shared");
36 snprintfz(values[PAGES_SHARED].filename, FILENAME_MAX, "%s", inicfg_get(&netdata_config, "plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_shared", values[PAGES_SHARED].filename));
37 ff_pages_shared = procfile_open(values[PAGES_SHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
38 }
39
40 if(unlikely(!ff_pages_sharing)) {
41 snprintfz(values[PAGES_SHARING].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_sharing");
42 snprintfz(values[PAGES_SHARING].filename, FILENAME_MAX, "%s", inicfg_get(&netdata_config, "plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_sharing", values[PAGES_SHARING].filename));
43 ff_pages_sharing = procfile_open(values[PAGES_SHARING].filename, " \t:", PROCFILE_FLAG_DEFAULT);
44 }
45
46 if(unlikely(!ff_pages_unshared)) {
47 snprintfz(values[PAGES_UNSHARED].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_unshared");
48 snprintfz(values[PAGES_UNSHARED].filename, FILENAME_MAX, "%s", inicfg_get(&netdata_config, "plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_unshared", values[PAGES_UNSHARED].filename));
49 ff_pages_unshared = procfile_open(values[PAGES_UNSHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
50 }
51
52 if(unlikely(!ff_pages_volatile)) {
53 snprintfz(values[PAGES_VOLATILE].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_volatile");
54 snprintfz(values[PAGES_VOLATILE].filename, FILENAME_MAX, "%s", inicfg_get(&netdata_config, "plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_volatile", values[PAGES_VOLATILE].filename));
55 ff_pages_volatile = procfile_open(values[PAGES_VOLATILE].filename, " \t:", PROCFILE_FLAG_DEFAULT);
56 }
57
58 //if(unlikely(!ff_pages_to_scan)) {
59 // snprintfz(values[PAGES_TO_SCAN].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_to_scan");
60 // snprintfz(values[PAGES_TO_SCAN].filename, FILENAME_MAX, "%s", inicfg_get(&netdata_config, "plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_to_scan", values[PAGES_TO_SCAN].filename));
61 // ff_pages_to_scan = procfile_open(values[PAGES_TO_SCAN].filename, " \t:", PROCFILE_FLAG_DEFAULT);
62 //}
63
64 if(unlikely(!ff_pages_shared || !ff_pages_sharing || !ff_pages_unshared || !ff_pages_volatile /*|| !ff_pages_to_scan */))
65 return 1;
66
67 unsigned long long pages_shared = 0, pages_sharing = 0, pages_unshared = 0, pages_volatile = 0, /*pages_to_scan = 0,*/ offered = 0, saved = 0;
68
69 ff_pages_shared = procfile_readall(ff_pages_shared);
70 if(unlikely(!ff_pages_shared)) return 0; // we return 0, so that we will retry to open it next time
71 pages_shared = str2ull(procfile_lineword(ff_pages_shared, 0, 0), NULL);
72
73 ff_pages_sharing = procfile_readall(ff_pages_sharing);
74 if(unlikely(!ff_pages_sharing)) return 0; // we return 0, so that we will retry to open it next time
75 pages_sharing = str2ull(procfile_lineword(ff_pages_sharing, 0, 0), NULL);
76
77 ff_pages_unshared = procfile_readall(ff_pages_unshared);
78 if(unlikely(!ff_pages_unshared)) return 0; // we return 0, so that we will retry to open it next time
79 pages_unshared = str2ull(procfile_lineword(ff_pages_unshared, 0, 0), NULL);
80
81 ff_pages_volatile = procfile_readall(ff_pages_volatile);
82 if(unlikely(!ff_pages_volatile)) return 0; // we return 0, so that we will retry to open it next time
83 pages_volatile = str2ull(procfile_lineword(ff_pages_volatile, 0, 0), NULL);
84
85 //ff_pages_to_scan = procfile_readall(ff_pages_to_scan);
86 //if(unlikely(!ff_pages_to_scan)) return 0; // we return 0, so that we will retry to open it next time
87 //pages_to_scan = str2ull(procfile_lineword(ff_pages_to_scan, 0, 0));
88
89 offered = pages_sharing + pages_shared + pages_unshared + pages_volatile;
90 saved = pages_sharing;
91
92 if (!offered)
93 return 0;
94
95 // --------------------------------------------------------------------
96
97 {
98 static RRDSET *st_mem_ksm = NULL;
99 static RRDDIM *rd_shared = NULL, *rd_unshared = NULL, *rd_sharing = NULL, *rd_volatile = NULL/*, *rd_to_scan = NULL*/;
100
101 if (unlikely(!st_mem_ksm)) {
102 st_mem_ksm = rrdset_create_localhost(
103 "mem"
104 , "ksm"
105 , NULL
106 , "ksm"
107 , NULL
108 , "Kernel Same Page Merging"
109 , "MiB"
110 , PLUGIN_PROC_NAME
111 , PLUGIN_PROC_MODULE_KSM_NAME
112 , NETDATA_CHART_PRIO_MEM_KSM
113 , update_every
114 , RRDSET_TYPE_STACKED
115 );
116
117 rd_shared = rrddim_add(st_mem_ksm, "shared", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
118 rd_unshared = rrddim_add(st_mem_ksm, "unshared", NULL, -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
119 rd_sharing = rrddim_add(st_mem_ksm, "sharing", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
120 rd_volatile = rrddim_add(st_mem_ksm, "volatile", NULL, -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
121 //rd_to_scan = rrddim_add(st_mem_ksm, "to_scan", "to scan", -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
122 }
123
124 rrddim_set_by_pointer(st_mem_ksm, rd_shared, pages_shared * page_size);
125 rrddim_set_by_pointer(st_mem_ksm, rd_unshared, pages_unshared * page_size);
126 rrddim_set_by_pointer(st_mem_ksm, rd_sharing, pages_sharing * page_size);
127 rrddim_set_by_pointer(st_mem_ksm, rd_volatile, pages_volatile * page_size);
128 //rrddim_set_by_pointer(st_mem_ksm, rd_to_scan, pages_to_scan * page_size);
129
130 rrdset_done(st_mem_ksm);
131 }
132
133 // --------------------------------------------------------------------
134
135 {
136 static RRDSET *st_mem_ksm_savings = NULL;
137 static RRDDIM *rd_savings = NULL, *rd_offered = NULL;
138
139 if (unlikely(!st_mem_ksm_savings)) {
140 st_mem_ksm_savings = rrdset_create_localhost(
141 "mem"
142 , "ksm_savings"
143 , NULL
144 , "ksm"
145 , NULL
146 , "Kernel Same Page Merging Savings"
147 , "MiB"
148 , PLUGIN_PROC_NAME
149 , PLUGIN_PROC_MODULE_KSM_NAME
150 , NETDATA_CHART_PRIO_MEM_KSM_SAVINGS
151 , update_every
152 , RRDSET_TYPE_AREA
153 );
154
155 rd_savings = rrddim_add(st_mem_ksm_savings, "savings", NULL, -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
156 rd_offered = rrddim_add(st_mem_ksm_savings, "offered", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
157 }
158
159 rrddim_set_by_pointer(st_mem_ksm_savings, rd_savings, saved * page_size);
160 rrddim_set_by_pointer(st_mem_ksm_savings, rd_offered, offered * page_size);
161
162 rrdset_done(st_mem_ksm_savings);
163 }
164
165 // --------------------------------------------------------------------
166
167 {
168 static RRDSET *st_mem_ksm_ratios = NULL;
169 static RRDDIM *rd_savings = NULL;
170
171 if (unlikely(!st_mem_ksm_ratios)) {
172 st_mem_ksm_ratios = rrdset_create_localhost(
173 "mem"
174 , "ksm_ratios"
175 , NULL
176 , "ksm"
177 , NULL
178 , "Kernel Same Page Merging Effectiveness"
179 , "percentage"
180 , PLUGIN_PROC_NAME
181 , PLUGIN_PROC_MODULE_KSM_NAME
182 , NETDATA_CHART_PRIO_MEM_KSM_RATIOS
183 , update_every
184 , RRDSET_TYPE_LINE
185 );
186
187 rd_savings = rrddim_add(st_mem_ksm_ratios, "savings", NULL, 1, 10000, RRD_ALGORITHM_ABSOLUTE);
188 }
189
190 rrddim_set_by_pointer(st_mem_ksm_ratios, rd_savings, (saved * 1000000) / offered);
191 rrdset_done(st_mem_ksm_ratios);
192 }
193
194 return 0;
195 }