@cryptotaxi247 / netdata-1 / commits / 9e43f71f8

added config option "memory deduplication (ksm) = yes/no" to control memory deduplication with ksm #38

Costa Tsaousis (ktsaou) committed Dec 20, 2015 at 04:32 UTC 9e43f71f87b33a38dc157050fdf75552b1c23442
4 files changed +38 -9
src/common.c
+29 -6
@@ -14,8 +14,10 @@
14
15 #include "log.h"
16 #include "common.h"
17 +#include "appconfig.h"
18
19 char *global_host_prefix = "";
20 +int enable_ksm = 1;
21
22 /*
23 // http://stackoverflow.com/questions/7666509/hash-function-for-string
@@ -107,7 +109,7 @@ char *trim(char *s)
109 return s;
110 }
111
110 -void *mymmap(const char *filename, unsigned long size, int flags)
112 +void *mymmap(const char *filename, unsigned long size, int flags, int ksm)
113 {
114 int fd;
115 void *mem = NULL;
@@ -117,14 +119,35 @@ void *mymmap(const char *filename, unsigned long size, int flags)
119 if(fd != -1) {
120 if(lseek(fd, size, SEEK_SET) == (long)size) {
121 if(write(fd, "", 1) == 1) {
120 -
122 if(ftruncate(fd, size))
123 error("Cannot truncate file '%s' to size %ld. Will use the larger file.", filename, size);
124
124 - mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
125 - if(mem) {
126 - if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK|MADV_WILLNEED) != 0)
127 - error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
125 + if(flags & MAP_SHARED || !enable_ksm || !ksm) {
126 + mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
127 + if(mem) {
128 + int advise = MADV_SEQUENTIAL|MADV_DONTFORK;
129 + if(flags & MAP_SHARED) advise |= MADV_WILLNEED;
130 +
131 + if(madvise(mem, size, advise) != 0)
132 + error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
133 + }
134 + }
135 + else {
136 + mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
137 + if(mem) {
138 + if(lseek(fd, 0, SEEK_SET) == 0) {
139 + if(read(fd, mem, size) != size)
140 + error("Cannot read from file '%s'", filename);
141 + }
142 + else
143 + error("Cannot seek to beginning of file '%s'.", filename);
144 +
145 + // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE
146 + if(madvise(mem, size, MADV_MERGEABLE) != 0)
147 + error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
148 + }
149 + else
150 + error("Cannot allocate PRIVATE ANONYMOUS memory for KSM for file '%s'.", filename);
151 }
152 }
153 else error("Cannot write to file '%s' at position %ld.", filename, size);
src/common.h
+2 -1
@@ -17,12 +17,13 @@ extern void strreverse(char* begin, char* end);
17 extern char *mystrsep(char **ptr, char *s);
18 extern char *trim(char *s);
19
20 -extern void *mymmap(const char *filename, unsigned long size, int flags);
20 +extern void *mymmap(const char *filename, unsigned long size, int flags, int ksm);
21 extern int savememory(const char *filename, void *mem, unsigned long size);
22
23 extern int fd_is_valid(int fd);
24
25 extern char *global_host_prefix;
26 +extern int enable_ksm;
27
28 /* Number of ticks per second */
29 #define HZ hz
src/main.c
+5
@@ -289,6 +289,11 @@ int main(int argc, char **argv)
289
290 // --------------------------------------------------------------------
291
292 + enable_ksm = config_get_boolean("global", "memory deduplication (ksm)", enable_ksm);
293 +
294 + // --------------------------------------------------------------------
295 +
296 +
297 global_host_prefix = config_get("global", "host access prefix", "");
298 setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);
299
src/rrd.c
+2 -2
@@ -353,7 +353,7 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
353 debug(D_RRD_CALLS, "Creating RRD_STATS for '%s.%s'.", type, id);
354
355 snprintf(fullfilename, FILENAME_MAX, "%s/main.db", cache_dir);
356 - if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) st = (RRDSET *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE));
356 + if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) st = (RRDSET *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE), 0);
357 if(st) {
358 if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
359 errno = 0;
@@ -468,7 +468,7 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
468
469 rrdset_strncpy_name(filename, id, FILENAME_MAX);
470 snprintf(fullfilename, FILENAME_MAX, "%s/%s.db", st->cache_dir, filename);
471 - if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) rd = (RRDDIM *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE));
471 + if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) rd = (RRDDIM *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE), 1);
472 if(rd) {
473 struct timeval now;
474 gettimeofday(&now, NULL);