summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>2015-12-20 04:32:16 +0200
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>2015-12-20 04:32:16 +0200
commit9e43f71f87b33a38dc157050fdf75552b1c23442 (patch)
tree7adb9682a2e46be3caf1fb01d2b4e691ccfe181b /src
parentf89a3efa14c2c351dd8d1c85722396c2fc20d283 (diff)
added config option "memory deduplication (ksm) = yes/no" to control memory deduplication with ksm #38
Diffstat (limited to 'src')
-rwxr-xr-xsrc/common.c35
-rwxr-xr-xsrc/common.h3
-rwxr-xr-xsrc/main.c5
-rwxr-xr-xsrc/rrd.c4
4 files changed, 38 insertions, 9 deletions
diff --git a/src/common.c b/src/common.c
index 2df676f902..63fed58511 100755
--- a/src/common.c
+++ b/src/common.c
@@ -14,8 +14,10 @@
#include "log.h"
#include "common.h"
+#include "appconfig.h"
char *global_host_prefix = "";
+int enable_ksm = 1;
/*
// http://stackoverflow.com/questions/7666509/hash-function-for-string
@@ -107,7 +109,7 @@ char *trim(char *s)
return s;
}
-void *mymmap(const char *filename, unsigned long size, int flags)
+void *mymmap(const char *filename, unsigned long size, int flags, int ksm)
{
int fd;
void *mem = NULL;
@@ -117,14 +119,35 @@ void *mymmap(const char *filename, unsigned long size, int flags)
if(fd != -1) {
if(lseek(fd, size, SEEK_SET) == (long)size) {
if(write(fd, "", 1) == 1) {
-
if(ftruncate(fd, size))
error("Cannot truncate file '%s' to size %ld. Will use the larger file.", filename, size);
- mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
- if(mem) {
- if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK|MADV_WILLNEED) != 0)
- error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
+ if(flags & MAP_SHARED || !enable_ksm || !ksm) {
+ mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
+ if(mem) {
+ int advise = MADV_SEQUENTIAL|MADV_DONTFORK;
+ if(flags & MAP_SHARED) advise |= MADV_WILLNEED;
+
+ if(madvise(mem, size, advise) != 0)
+ error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
+ }
+ }
+ else {
+ mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
+ if(mem) {
+ if(lseek(fd, 0, SEEK_SET) == 0) {
+ if(read(fd, mem, size) != size)
+ error("Cannot read from file '%s'", filename);
+ }
+ else
+ error("Cannot seek to beginning of file '%s'.", filename);
+
+ // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE
+ if(madvise(mem, size, MADV_MERGEABLE) != 0)
+ error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
+ }
+ else
+ error("Cannot allocate PRIVATE ANONYMOUS memory for KSM for file '%s'.", filename);
}
}
else error("Cannot write to file '%s' at position %ld.", filename, size);
diff --git a/src/common.h b/src/common.h
index 46af8bc867..ba00af74fd 100755
--- a/src/common.h
+++ b/src/common.h
@@ -17,12 +17,13 @@ extern void strreverse(char* begin, char* end);
extern char *mystrsep(char **ptr, char *s);
extern char *trim(char *s);
-extern void *mymmap(const char *filename, unsigned long size, int flags);
+extern void *mymmap(const char *filename, unsigned long size, int flags, int ksm);
extern int savememory(const char *filename, void *mem, unsigned long size);
extern int fd_is_valid(int fd);
extern char *global_host_prefix;
+extern int enable_ksm;
/* Number of ticks per second */
#define HZ hz
diff --git a/src/main.c b/src/main.c
index 11d69cdb15..1126c43866 100755
--- a/src/main.c
+++ b/src/main.c
@@ -289,6 +289,11 @@ int main(int argc, char **argv)
// --------------------------------------------------------------------
+ enable_ksm = config_get_boolean("global", "memory deduplication (ksm)", enable_ksm);
+
+ // --------------------------------------------------------------------
+
+
global_host_prefix = config_get("global", "host access prefix", "");
setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);
diff --git a/src/rrd.c b/src/rrd.c
index 3b35b4aade..9604337df3 100755
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -353,7 +353,7 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
debug(D_RRD_CALLS, "Creating RRD_STATS for '%s.%s'.", type, id);
snprintf(fullfilename, FILENAME_MAX, "%s/main.db", cache_dir);
- if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) st = (RRDSET *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE));
+ 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);
if(st) {
if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
errno = 0;
@@ -468,7 +468,7 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
rrdset_strncpy_name(filename, id, FILENAME_MAX);
snprintf(fullfilename, FILENAME_MAX, "%s/%s.db", st->cache_dir, filename);
- if(rrd_memory_mode != RRD_MEMORY_MODE_RAM) rd = (RRDDIM *)mymmap(fullfilename, size, ((rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE));
+ 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);
if(rd) {
struct timeval now;
gettimeofday(&now, NULL);