diff options
-rw-r--r-- | erts/configure.in | 2 | ||||
-rw-r--r-- | erts/doc/src/erts_alloc.xml | 10 | ||||
-rw-r--r-- | erts/emulator/beam/erl_alloc.c | 40 | ||||
-rw-r--r-- | erts/etc/common/erlexec.c | 1 |
4 files changed, 50 insertions, 3 deletions
diff --git a/erts/configure.in b/erts/configure.in index 8288a1aab1..b47a6ff094 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1977,7 +1977,7 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop gethrtime localtime_r gmtime_r inet_pton \ mmap mremap memcpy mallopt sbrk _sbrk __sbrk brk _brk __brk \ flockfile fstat strlcpy strlcat setsid posix2time time2posix \ - setlocale nl_langinfo poll]) + setlocale nl_langinfo poll mlockall]) case X$erl_xcomp_posix_memalign in diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index 9dab5b3876..90bc35cdc9 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -604,6 +604,16 @@ </item> </taglist> </item> + <tag><marker id="Mlpm"><c>+Mlpm all|no</c></marker></tag> + <item>Lock physical memory. The default value is <c>no</c>, i.e., + no physical memory will be locked. If set to <c>all</c>, all + memory mappings made by the runtime system, will be locked into + physical memory. If set to <c>all</c>, the runtime system will fail + to start if this feature is not supported, the user has not got enough + privileges, or the user is not allowed to lock enough physical memory. + The runtime system will also fail with an out of memory condition + if the user limit on the amount of locked memory is reached. + </item> </taglist> <p>Only some default values have been presented here. diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index d8da616d05..8e20d58161 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -100,6 +100,8 @@ static Uint install_debug_functions(void); #endif #endif +static int lock_all_physical_memory = 0; + ErtsAllocatorFunctions_t erts_allctrs[ERTS_ALC_A_MAX+1]; ErtsAllocatorInfo_t erts_allctrs_info[ERTS_ALC_A_MAX+1]; ErtsAllocatorThrSpec_t erts_allctr_thr_spec[ERTS_ALC_A_MAX+1]; @@ -618,6 +620,8 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) hdbg_init(); #endif + lock_all_physical_memory = 0; + ncpu = eaiop->ncpu; if (ncpu < 1) ncpu = 1; @@ -641,6 +645,20 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) if (argc && argv) handle_args(argc, argv, &init); + if (lock_all_physical_memory) { +#ifdef HAVE_MLOCKALL + errno = 0; + if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) { + int err = errno; + char *errstr = err ? strerror(err) : "unknown"; + erl_exit(-1, "Failed to lock physical memory: %s (%d)\n", + errstr, err); + } +#else + erl_exit(-1, "Failed to lock physical memory: Not supported\n"); +#endif + } + #ifndef ERTS_SMP init.sl_alloc.thr_spec = 0; init.std_alloc.thr_spec = 0; @@ -1630,6 +1648,19 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init) bad_param(param, param+2); } break; + case 'l': + if (has_prefix("pm", param+2)) { + arg = get_value(argv[i]+5, argv, &i); + if (strcmp("all", arg) == 0) + lock_all_physical_memory = 1; + else if (strcmp("no", arg) == 0) + lock_all_physical_memory = 0; + else + bad_value(param, param+4, arg); + break; + } + bad_param(param, param+2); + break; case 'u': if (has_prefix("ycs", argv[i]+3)) { init->alloc_util.ycs @@ -2749,8 +2780,8 @@ erts_allocator_options(void *proc) #endif Uint sz, *szp, *hp, **hpp; Eterm res, features, settings; - Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+6]; - Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+6]; + Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+7]; + Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+7]; int a, length; SysAllocStat sas; Uint *endp = NULL; @@ -2848,6 +2879,11 @@ erts_allocator_options(void *proc) terms[length++] = erts_bld_2tup_list(hpp, szp, 3, o, v); } + atoms[length] = am_atom_put("lock_physical_memory", 20); + terms[length++] = (lock_all_physical_memory + ? am_atom_put("all", 3) + : am_atom_put("no", 2)); + settings = erts_bld_2tup_list(hpp, szp, length, atoms, terms); length = 0; diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index c9908caf20..ffbefce545 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -106,6 +106,7 @@ static char *plusM_other_switches[] = { "im", "is", "it", + "lpm", "Mamcbf", "Mrmcbf", "Mmcs", |