diff --git a/doc/configuration.txt b/doc/configuration.txt index 4795dd21f..6660aa7b7 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1070,6 +1070,7 @@ The following keywords are supported in the "global" section : - maxsslconn - maxsslrate - maxzlibmem + - no-memory-trimming - noepoll - nokqueue - noevports @@ -2380,6 +2381,22 @@ maxzlibmem with "show info" on the line "MaxZlibMemUsage", the memory used by zlib is "ZlibMemUsage" in bytes. +no-memory-trimming + Disables memory trimming ("malloc_trim") at a few moments where attempts are + made to reclaim lots of memory (on memory shortage or on reload). Trimming + memory forces the system's allocator to scan all unused areas and to release + them. This is generally seen as nice action to leave more available memory to + a new process while the old one is unlikely to make significant use of it. + But some systems dealing with tens to hundreds of thousands of concurrent + connections may experience a lot of memory fragmentation, that may render + this release operation extremely long. During this time, no more traffic + passes through the process, new connections are not accepted anymore, some + health checks may even fail, and the watchdog may even trigger and kill the + unresponsive process, leaving a huge core dump. If this ever happens, then it + is suggested to use this option to disable trimming and stop trying to be + nice with the new process. Note that advanced memory allocators usually do + not suffer from such a problem. + noepoll Disables the use of the "epoll" event polling system on Linux. It is equivalent to the command-line argument "-de". The next polling system diff --git a/src/pool.c b/src/pool.c index b3520d744..fe10badbd 100644 --- a/src/pool.c +++ b/src/pool.c @@ -83,6 +83,7 @@ static const struct { static int mem_fail_rate __read_mostly = 0; static int using_default_allocator __read_mostly = 1; +static int disable_trim __read_mostly = 0; static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL; /* ask the allocator to trim memory pools. @@ -95,6 +96,9 @@ static void trim_all_pools(void) { int isolated = thread_isolated(); + if (disable_trim) + return; + if (!isolated) thread_isolate(); @@ -1073,9 +1077,21 @@ static int mem_parse_global_fail_alloc(char **args, int section_type, struct pro return 0; } +/* config parser for global "no-memory-trimming" */ +static int mem_parse_global_no_mem_trim(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (too_many_args(0, args, err, NULL)) + return -1; + disable_trim = 1; + return 0; +} + /* register global config keywords */ static struct cfg_kw_list mem_cfg_kws = {ILH, { { CFG_GLOBAL, "tune.fail-alloc", mem_parse_global_fail_alloc }, + { CFG_GLOBAL, "no-memory-trimming", mem_parse_global_no_mem_trim }, { 0, NULL, NULL } }};