source file for ksm #38
Costa Tsaousis (ktsaou) committed
Dec 25, 2015 at 03:26 UTC
f5b523a3fef1e4d6810763142fc2c39b61af7e97
1 file changed
+150
src/sys_kernel_mm_ksm.c
new
+150
@@ -0,0 +1,150 @@
1
+#ifdef HAVE_CONFIG_H
2
+#include <config.h>
3
+#endif
4
+#include <stdio.h>
5
+#include <stdlib.h>
6
+#include <string.h>
7
+
8
+#include "common.h"
9
+#include "log.h"
10
+#include "appconfig.h"
11
+#include "procfile.h"
12
+#include "rrd.h"
13
+#include "plugin_proc.h"
14
+
15
+typedef struct name_value {
16
+ char filename[FILENAME_MAX + 1];
17
+ unsigned long long value;
18
+} NAME_VALUE;
19
+
20
+#define PAGES_SHARED 0
21
+#define PAGES_SHARING 1
22
+#define PAGES_UNSHARED 2
23
+#define PAGES_VOLATILE 3
24
+#define PAGES_TO_SCAN 4
25
+
26
+NAME_VALUE values[] = {
27
+ [PAGES_SHARED] = { "/sys/kernel/mm/ksm/pages_shared", 0ULL },
28
+ [PAGES_SHARING] = { "/sys/kernel/mm/ksm/pages_sharing", 0ULL },
29
+ [PAGES_UNSHARED] = { "/sys/kernel/mm/ksm/pages_unshared", 0ULL },
30
+ [PAGES_VOLATILE] = { "/sys/kernel/mm/ksm/pages_volatile", 0ULL },
31
+ [PAGES_TO_SCAN] = { "/sys/kernel/mm/ksm/pages_to_scan", 0ULL },
32
+};
33
+
34
+int do_sys_kernel_mm_ksm(int update_every, unsigned long long dt) {
35
+ static procfile *ff_pages_shared = NULL, *ff_pages_sharing = NULL, *ff_pages_unshared = NULL, *ff_pages_volatile = NULL, *ff_pages_to_scan = NULL;
36
+ static long page_size = -1;
37
+
38
+ if(dt) {};
39
+
40
+ if(page_size == -1)
41
+ page_size = sysconf(_SC_PAGESIZE);
42
+
43
+ if(!ff_pages_shared) {
44
+ snprintf(values[PAGES_SHARED].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_shared");
45
+ snprintf(values[PAGES_SHARED].filename, FILENAME_MAX, "%s", config_get("plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_shared", values[PAGES_SHARED].filename));
46
+ ff_pages_shared = procfile_open(values[PAGES_SHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
47
+ }
48
+
49
+ if(!ff_pages_sharing) {
50
+ snprintf(values[PAGES_SHARING].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_sharing");
51
+ snprintf(values[PAGES_SHARING].filename, FILENAME_MAX, "%s", config_get("plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_sharing", values[PAGES_SHARING].filename));
52
+ ff_pages_sharing = procfile_open(values[PAGES_SHARING].filename, " \t:", PROCFILE_FLAG_DEFAULT);
53
+ }
54
+
55
+ if(!ff_pages_unshared) {
56
+ snprintf(values[PAGES_UNSHARED].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_unshared");
57
+ snprintf(values[PAGES_UNSHARED].filename, FILENAME_MAX, "%s", config_get("plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_unshared", values[PAGES_UNSHARED].filename));
58
+ ff_pages_unshared = procfile_open(values[PAGES_UNSHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
59
+ }
60
+
61
+ if(!ff_pages_volatile) {
62
+ snprintf(values[PAGES_VOLATILE].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_volatile");
63
+ snprintf(values[PAGES_VOLATILE].filename, FILENAME_MAX, "%s", config_get("plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_volatile", values[PAGES_VOLATILE].filename));
64
+ ff_pages_volatile = procfile_open(values[PAGES_VOLATILE].filename, " \t:", PROCFILE_FLAG_DEFAULT);
65
+ }
66
+
67
+ if(!ff_pages_to_scan) {
68
+ snprintf(values[PAGES_TO_SCAN].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_to_scan");
69
+ snprintf(values[PAGES_TO_SCAN].filename, FILENAME_MAX, "%s", config_get("plugin:proc:/sys/kernel/mm/ksm", "/sys/kernel/mm/ksm/pages_to_scan", values[PAGES_TO_SCAN].filename));
70
+ ff_pages_to_scan = procfile_open(values[PAGES_TO_SCAN].filename, " \t:", PROCFILE_FLAG_DEFAULT);
71
+ }
72
+
73
+ if(!ff_pages_shared || !ff_pages_sharing || !ff_pages_unshared || !ff_pages_volatile || !ff_pages_to_scan) return 1;
74
+
75
+ unsigned long long pages_shared = 0, pages_sharing = 0, pages_unshared = 0, pages_volatile = 0, pages_to_scan = 0, offered = 0, saved = 0;
76
+
77
+ ff_pages_shared = procfile_readall(ff_pages_shared);
78
+ if(!ff_pages_shared) return 0; // we return 0, so that we will retry to open it next time
79
+ pages_shared = strtoull(procfile_lineword(ff_pages_shared, 0, 0), NULL, 10);
80
+
81
+ ff_pages_sharing = procfile_readall(ff_pages_sharing);
82
+ if(!ff_pages_sharing) return 0; // we return 0, so that we will retry to open it next time
83
+ pages_sharing = strtoull(procfile_lineword(ff_pages_sharing, 0, 0), NULL, 10);
84
+
85
+ ff_pages_unshared = procfile_readall(ff_pages_unshared);
86
+ if(!ff_pages_unshared) return 0; // we return 0, so that we will retry to open it next time
87
+ pages_unshared = strtoull(procfile_lineword(ff_pages_unshared, 0, 0), NULL, 10);
88
+
89
+ ff_pages_volatile = procfile_readall(ff_pages_volatile);
90
+ if(!ff_pages_volatile) return 0; // we return 0, so that we will retry to open it next time
91
+ pages_volatile = strtoull(procfile_lineword(ff_pages_volatile, 0, 0), NULL, 10);
92
+
93
+ ff_pages_to_scan = procfile_readall(ff_pages_to_scan);
94
+ if(!ff_pages_to_scan) return 0; // we return 0, so that we will retry to open it next time
95
+ pages_to_scan = strtoull(procfile_lineword(ff_pages_to_scan, 0, 0), NULL, 10);
96
+
97
+ offered = pages_sharing + pages_unshared + pages_volatile;
98
+ saved = pages_sharing - pages_shared;
99
+
100
+ if(!offered || !pages_to_scan) return 0;
101
+
102
+ RRDSET *st;
103
+
104
+ // --------------------------------------------------------------------
105
+
106
+ st = rrdset_find("mem.ksm");
107
+ if(!st) {
108
+ st = rrdset_create("mem", "ksm", NULL, "ksm", "Kernel Same Page Merging", "MB", 5000, update_every, RRDSET_TYPE_AREA);
109
+
110
+ rrddim_add(st, "shared", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
111
+ rrddim_add(st, "unshared", NULL, -1, 1024 * 1024, RRDDIM_ABSOLUTE);
112
+ rrddim_add(st, "sharing", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
113
+ rrddim_add(st, "volatile", NULL, -1, 1024 * 1024, RRDDIM_ABSOLUTE);
114
+ rrddim_add(st, "to_scan", "to scan", -1, 1024 * 1024, RRDDIM_ABSOLUTE);
115
+ }
116
+ else rrdset_next(st);
117
+
118
+ rrddim_set(st, "shared", pages_shared * page_size);
119
+ rrddim_set(st, "unshared", pages_unshared * page_size);
120
+ rrddim_set(st, "sharing", pages_sharing * page_size);
121
+ rrddim_set(st, "volatile", pages_volatile * page_size);
122
+ rrddim_set(st, "to_scan", pages_to_scan * page_size);
123
+ rrdset_done(st);
124
+
125
+ st = rrdset_find("mem.ksm_savings");
126
+ if(!st) {
127
+ st = rrdset_create("mem", "ksm_savings", NULL, "ksm", "Kernel Same Page Merging Savings", "MB", 5001, update_every, RRDSET_TYPE_AREA);
128
+
129
+ rrddim_add(st, "savings", NULL, -1, 1024 * 1024, RRDDIM_ABSOLUTE);
130
+ rrddim_add(st, "offered", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
131
+ }
132
+ else rrdset_next(st);
133
+
134
+ rrddim_set(st, "savings", saved * page_size);
135
+ rrddim_set(st, "offered", offered * page_size);
136
+ rrdset_done(st);
137
+
138
+ st = rrdset_find("mem.ksm_ratios");
139
+ if(!st) {
140
+ st = rrdset_create("mem", "ksm_ratios", NULL, "ksm", "Kernel Same Page Merging Effectiveness", "percentage", 5002, update_every, RRDSET_TYPE_LINE);
141
+
142
+ rrddim_add(st, "savings", NULL, 1, 10000, RRDDIM_ABSOLUTE);
143
+ }
144
+ else rrdset_next(st);
145
+
146
+ rrddim_set(st, "savings", (saved * 1000000) / offered);
147
+ rrdset_done(st);
148
+
149
+ return 0;
150
+}