]> arthur.barton.de Git - netdata.git/blob - src/sys_kernel_mm_ksm.c
dns_query_time plugin: replace "." with "_" in dimensions
[netdata.git] / src / sys_kernel_mm_ksm.c
1 #include "common.h"
2
3 typedef struct ksm_name_value {
4     char filename[FILENAME_MAX + 1];
5     unsigned long long value;
6 } KSM_NAME_VALUE;
7
8 #define PAGES_SHARED 0
9 #define PAGES_SHARING 1
10 #define PAGES_UNSHARED 2
11 #define PAGES_VOLATILE 3
12 #define PAGES_TO_SCAN 4
13
14 KSM_NAME_VALUE values[] = {
15         [PAGES_SHARED] = { "/sys/kernel/mm/ksm/pages_shared", 0ULL },
16         [PAGES_SHARING] = { "/sys/kernel/mm/ksm/pages_sharing", 0ULL },
17         [PAGES_UNSHARED] = { "/sys/kernel/mm/ksm/pages_unshared", 0ULL },
18         [PAGES_VOLATILE] = { "/sys/kernel/mm/ksm/pages_volatile", 0ULL },
19         [PAGES_TO_SCAN] = { "/sys/kernel/mm/ksm/pages_to_scan", 0ULL },
20 };
21
22 int do_sys_kernel_mm_ksm(int update_every, usec_t dt) {
23     (void)dt;
24     static procfile *ff_pages_shared = NULL, *ff_pages_sharing = NULL, *ff_pages_unshared = NULL, *ff_pages_volatile = NULL, *ff_pages_to_scan = NULL;
25     static long page_size = -1;
26
27     if(page_size == -1)
28         page_size = sysconf(_SC_PAGESIZE);
29
30     if(!ff_pages_shared) {
31         snprintfz(values[PAGES_SHARED].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_shared");
32         snprintfz(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));
33         ff_pages_shared = procfile_open(values[PAGES_SHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
34     }
35
36     if(!ff_pages_sharing) {
37         snprintfz(values[PAGES_SHARING].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_sharing");
38         snprintfz(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));
39         ff_pages_sharing = procfile_open(values[PAGES_SHARING].filename, " \t:", PROCFILE_FLAG_DEFAULT);
40     }
41
42     if(!ff_pages_unshared) {
43         snprintfz(values[PAGES_UNSHARED].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_unshared");
44         snprintfz(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));
45         ff_pages_unshared = procfile_open(values[PAGES_UNSHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
46     }
47
48     if(!ff_pages_volatile) {
49         snprintfz(values[PAGES_VOLATILE].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_volatile");
50         snprintfz(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));
51         ff_pages_volatile = procfile_open(values[PAGES_VOLATILE].filename, " \t:", PROCFILE_FLAG_DEFAULT);
52     }
53
54     if(!ff_pages_to_scan) {
55         snprintfz(values[PAGES_TO_SCAN].filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/kernel/mm/ksm/pages_to_scan");
56         snprintfz(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));
57         ff_pages_to_scan = procfile_open(values[PAGES_TO_SCAN].filename, " \t:", PROCFILE_FLAG_DEFAULT);
58     }
59
60     if(!ff_pages_shared || !ff_pages_sharing || !ff_pages_unshared || !ff_pages_volatile || !ff_pages_to_scan) return 1;
61
62     unsigned long long pages_shared = 0, pages_sharing = 0, pages_unshared = 0, pages_volatile = 0, pages_to_scan = 0, offered = 0, saved = 0;
63
64     ff_pages_shared = procfile_readall(ff_pages_shared);
65     if(!ff_pages_shared) return 0; // we return 0, so that we will retry to open it next time
66     pages_shared = str2ull(procfile_lineword(ff_pages_shared, 0, 0));
67
68     ff_pages_sharing = procfile_readall(ff_pages_sharing);
69     if(!ff_pages_sharing) return 0; // we return 0, so that we will retry to open it next time
70     pages_sharing = str2ull(procfile_lineword(ff_pages_sharing, 0, 0));
71
72     ff_pages_unshared = procfile_readall(ff_pages_unshared);
73     if(!ff_pages_unshared) return 0; // we return 0, so that we will retry to open it next time
74     pages_unshared = str2ull(procfile_lineword(ff_pages_unshared, 0, 0));
75
76     ff_pages_volatile = procfile_readall(ff_pages_volatile);
77     if(!ff_pages_volatile) return 0; // we return 0, so that we will retry to open it next time
78     pages_volatile = str2ull(procfile_lineword(ff_pages_volatile, 0, 0));
79
80     ff_pages_to_scan = procfile_readall(ff_pages_to_scan);
81     if(!ff_pages_to_scan) return 0; // we return 0, so that we will retry to open it next time
82     pages_to_scan = str2ull(procfile_lineword(ff_pages_to_scan, 0, 0));
83
84     offered = pages_sharing + pages_shared + pages_unshared + pages_volatile;
85     saved = pages_sharing - pages_shared;
86
87     if(!offered || !pages_to_scan) return 0;
88
89     RRDSET *st;
90
91     // --------------------------------------------------------------------
92
93     st = rrdset_find_localhost("mem.ksm");
94     if(!st) {
95         st = rrdset_create_localhost("mem", "ksm", NULL, "ksm", NULL, "Kernel Same Page Merging", "MB", 5000
96                                      , update_every, RRDSET_TYPE_AREA);
97
98         rrddim_add(st, "shared", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
99         rrddim_add(st, "unshared", NULL, -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
100         rrddim_add(st, "sharing", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
101         rrddim_add(st, "volatile", NULL, -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
102         rrddim_add(st, "to_scan", "to scan", -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
103     }
104     else rrdset_next(st);
105
106     rrddim_set(st, "shared", pages_shared * page_size);
107     rrddim_set(st, "unshared", pages_unshared * page_size);
108     rrddim_set(st, "sharing", pages_sharing * page_size);
109     rrddim_set(st, "volatile", pages_volatile * page_size);
110     rrddim_set(st, "to_scan", pages_to_scan * page_size);
111     rrdset_done(st);
112
113     st = rrdset_find_localhost("mem.ksm_savings");
114     if(!st) {
115         st = rrdset_create_localhost("mem", "ksm_savings", NULL, "ksm", NULL, "Kernel Same Page Merging Savings", "MB"
116                                      , 5001, update_every, RRDSET_TYPE_AREA);
117
118         rrddim_add(st, "savings", NULL, -1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
119         rrddim_add(st, "offered", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
120     }
121     else rrdset_next(st);
122
123     rrddim_set(st, "savings", saved * page_size);
124     rrddim_set(st, "offered", offered * page_size);
125     rrdset_done(st);
126
127     st = rrdset_find_localhost("mem.ksm_ratios");
128     if(!st) {
129         st = rrdset_create_localhost("mem", "ksm_ratios", NULL, "ksm", NULL, "Kernel Same Page Merging Effectiveness"
130                                      , "percentage", 5002, update_every, RRDSET_TYPE_LINE);
131
132         rrddim_add(st, "savings", NULL, 1, 10000, RRD_ALGORITHM_ABSOLUTE);
133     }
134     else rrdset_next(st);
135
136     rrddim_set(st, "savings", (saved * 1000000) / offered);
137     rrdset_done(st);
138
139     return 0;
140 }