]> arthur.barton.de Git - netdata.git/blob - src/sys_kernel_mm_ksm.c
added more fping alarms; added the ability to have alarms that never send CLEAR notif...
[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     static procfile *ff_pages_shared = NULL, *ff_pages_sharing = NULL, *ff_pages_unshared = NULL, *ff_pages_volatile = NULL, *ff_pages_to_scan = NULL;
24     static long page_size = -1;
25
26     if(dt) {};
27
28     if(page_size == -1)
29         page_size = sysconf(_SC_PAGESIZE);
30
31     if(!ff_pages_shared) {
32         snprintfz(values[PAGES_SHARED].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_shared");
33         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));
34         ff_pages_shared = procfile_open(values[PAGES_SHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
35     }
36
37     if(!ff_pages_sharing) {
38         snprintfz(values[PAGES_SHARING].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_sharing");
39         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));
40         ff_pages_sharing = procfile_open(values[PAGES_SHARING].filename, " \t:", PROCFILE_FLAG_DEFAULT);
41     }
42
43     if(!ff_pages_unshared) {
44         snprintfz(values[PAGES_UNSHARED].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_unshared");
45         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));
46         ff_pages_unshared = procfile_open(values[PAGES_UNSHARED].filename, " \t:", PROCFILE_FLAG_DEFAULT);
47     }
48
49     if(!ff_pages_volatile) {
50         snprintfz(values[PAGES_VOLATILE].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_volatile");
51         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));
52         ff_pages_volatile = procfile_open(values[PAGES_VOLATILE].filename, " \t:", PROCFILE_FLAG_DEFAULT);
53     }
54
55     if(!ff_pages_to_scan) {
56         snprintfz(values[PAGES_TO_SCAN].filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/kernel/mm/ksm/pages_to_scan");
57         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));
58         ff_pages_to_scan = procfile_open(values[PAGES_TO_SCAN].filename, " \t:", PROCFILE_FLAG_DEFAULT);
59     }
60
61     if(!ff_pages_shared || !ff_pages_sharing || !ff_pages_unshared || !ff_pages_volatile || !ff_pages_to_scan) return 1;
62
63     unsigned long long pages_shared = 0, pages_sharing = 0, pages_unshared = 0, pages_volatile = 0, pages_to_scan = 0, offered = 0, saved = 0;
64
65     ff_pages_shared = procfile_readall(ff_pages_shared);
66     if(!ff_pages_shared) return 0; // we return 0, so that we will retry to open it next time
67     pages_shared = str2ull(procfile_lineword(ff_pages_shared, 0, 0));
68
69     ff_pages_sharing = procfile_readall(ff_pages_sharing);
70     if(!ff_pages_sharing) return 0; // we return 0, so that we will retry to open it next time
71     pages_sharing = str2ull(procfile_lineword(ff_pages_sharing, 0, 0));
72
73     ff_pages_unshared = procfile_readall(ff_pages_unshared);
74     if(!ff_pages_unshared) return 0; // we return 0, so that we will retry to open it next time
75     pages_unshared = str2ull(procfile_lineword(ff_pages_unshared, 0, 0));
76
77     ff_pages_volatile = procfile_readall(ff_pages_volatile);
78     if(!ff_pages_volatile) return 0; // we return 0, so that we will retry to open it next time
79     pages_volatile = str2ull(procfile_lineword(ff_pages_volatile, 0, 0));
80
81     ff_pages_to_scan = procfile_readall(ff_pages_to_scan);
82     if(!ff_pages_to_scan) return 0; // we return 0, so that we will retry to open it next time
83     pages_to_scan = str2ull(procfile_lineword(ff_pages_to_scan, 0, 0));
84
85     offered = pages_sharing + pages_shared + pages_unshared + pages_volatile;
86     saved = pages_sharing - pages_shared;
87
88     if(!offered || !pages_to_scan) return 0;
89
90     RRDSET *st;
91
92     // --------------------------------------------------------------------
93
94     st = rrdset_find("mem.ksm");
95     if(!st) {
96         st = rrdset_create("mem", "ksm", NULL, "ksm", NULL, "Kernel Same Page Merging", "MB", 5000, update_every, RRDSET_TYPE_AREA);
97
98         rrddim_add(st, "shared", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
99         rrddim_add(st, "unshared", NULL, -1, 1024 * 1024, RRDDIM_ABSOLUTE);
100         rrddim_add(st, "sharing", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
101         rrddim_add(st, "volatile", NULL, -1, 1024 * 1024, RRDDIM_ABSOLUTE);
102         rrddim_add(st, "to_scan", "to scan", -1, 1024 * 1024, RRDDIM_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("mem.ksm_savings");
114     if(!st) {
115         st = rrdset_create("mem", "ksm_savings", NULL, "ksm", NULL, "Kernel Same Page Merging Savings", "MB", 5001, update_every, RRDSET_TYPE_AREA);
116
117         rrddim_add(st, "savings", NULL, -1, 1024 * 1024, RRDDIM_ABSOLUTE);
118         rrddim_add(st, "offered", NULL, 1, 1024 * 1024, RRDDIM_ABSOLUTE);
119     }
120     else rrdset_next(st);
121
122     rrddim_set(st, "savings", saved * page_size);
123     rrddim_set(st, "offered", offered * page_size);
124     rrdset_done(st);
125
126     st = rrdset_find("mem.ksm_ratios");
127     if(!st) {
128         st = rrdset_create("mem", "ksm_ratios", NULL, "ksm", NULL, "Kernel Same Page Merging Effectiveness", "percentage", 5002, update_every, RRDSET_TYPE_LINE);
129
130         rrddim_add(st, "savings", NULL, 1, 10000, RRDDIM_ABSOLUTE);
131     }
132     else rrdset_next(st);
133
134     rrddim_set(st, "savings", (saved * 1000000) / offered);
135     rrdset_done(st);
136
137     return 0;
138 }