diff options
author | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2015-12-20 04:32:16 +0200 |
---|---|---|
committer | Costa Tsaousis (ktsaou) <costa@tsaousis.gr> | 2015-12-20 04:32:16 +0200 |
commit | 9e43f71f87b33a38dc157050fdf75552b1c23442 (patch) | |
tree | 7adb9682a2e46be3caf1fb01d2b4e691ccfe181b /src | |
parent | f89a3efa14c2c351dd8d1c85722396c2fc20d283 (diff) |
added config option "memory deduplication (ksm) = yes/no" to control memory deduplication with ksm #38
Diffstat (limited to 'src')
-rwxr-xr-x | src/common.c | 35 | ||||
-rwxr-xr-x | src/common.h | 3 | ||||
-rwxr-xr-x | src/main.c | 5 | ||||
-rwxr-xr-x | src/rrd.c | 4 |
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); @@ -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); |