diff --git a/doc/management.txt b/doc/management.txt index a53a953a3..e770b794c 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -223,11 +223,13 @@ list of options is : generally be the "select" poller, which cannot be disabled and is limited to 1024 file descriptors. - -m : limit the total allocatable memory to megabytes per - process. This may cause some connection refusals or some slowdowns + -m : limit the total allocatable memory to megabytes across + all processes. This may cause some connection refusals or some slowdowns depending on the amount of memory needed for normal operations. This is - mostly used to force the process to work in a constrained resource usage - scenario. + mostly used to force the processes to work in a constrained resource usage + scenario. It is important to note that the memory is not shared between + processes, so in a multi-process scenario, this value is first divided by + global.nbproc before forking. -n : limits the per-process connection limit to . This is equivalent to the global section's keyword "maxconn". It has precedence diff --git a/include/types/global.h b/include/types/global.h index ca96193df..61f039167 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -115,7 +115,8 @@ struct global { int maxpipes; /* max # of pipes */ int maxsock; /* max # of sockets */ int rlimit_nofile; /* default ulimit-n value : 0=unset */ - int rlimit_memmax; /* default ulimit-d in megs value : 0=unset */ + int rlimit_memmax_all; /* default all-process memory limit in megs ; 0=unset */ + int rlimit_memmax; /* default per-process memory limit in megs ; 0=unset */ long maxzlibmem; /* max RAM for zlib in bytes */ int mode; unsigned int req_count; /* request counter (HTTP or TCP session) for logs and unique_id */ diff --git a/src/haproxy.c b/src/haproxy.c index 5cd337998..21a5e1286 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -581,7 +581,7 @@ void init(int argc, char **argv) #ifdef HAPROXY_MEMMAX - global.rlimit_memmax = HAPROXY_MEMMAX; + global.rlimit_memmax_all = HAPROXY_MEMMAX; #endif tv_update_date(-1,-1); @@ -729,7 +729,7 @@ void init(int argc, char **argv) switch (*flag) { case 'C' : change_dir = *argv; break; case 'n' : cfg_maxconn = atol(*argv); break; - case 'm' : global.rlimit_memmax = atol(*argv); break; + case 'm' : global.rlimit_memmax_all = atol(*argv); break; case 'N' : cfg_maxpconn = atol(*argv); break; case 'L' : strncpy(localpeer, *argv, sizeof(localpeer) - 1); break; case 'f' : @@ -794,6 +794,22 @@ void init(int argc, char **argv) exit(1); } + /* recompute the amount of per-process memory depending on nbproc and + * the shared SSL cache size (allowed to exist in all processes). + */ + if (global.rlimit_memmax_all) { +#if defined (USE_OPENSSL) && !defined(USE_PRIVATE_CACHE) + int64_t ssl_cache_bytes = global.tune.sslcachesize * 200LL; + + global.rlimit_memmax = + ((((int64_t)global.rlimit_memmax_all * 1048576LL) - + ssl_cache_bytes) / global.nbproc + + ssl_cache_bytes + 1048575LL) / 1048576LL; +#else + global.rlimit_memmax = global.rlimit_memmax_all / global.nbproc; +#endif + } + #ifdef CONFIG_HAP_NS err_code |= netns_init(); if (err_code & (ERR_ABORT|ERR_FATAL)) { @@ -1645,7 +1661,7 @@ int main(int argc, char **argv) if (global.rlimit_memmax) { limit.rlim_cur = limit.rlim_max = - global.rlimit_memmax * 1048576ULL / global.nbproc; + global.rlimit_memmax * 1048576ULL; #ifdef RLIMIT_AS if (setrlimit(RLIMIT_AS, &limit) == -1) { Warning("[%s.main()] Cannot fix MEM limit to %d megs.\n",