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);