diff --git a/src/pool/pool_jemalloc.c b/src/pool/pool_jemalloc.c index bed78ce26..b9d0d07c4 100644 --- a/src/pool/pool_jemalloc.c +++ b/src/pool/pool_jemalloc.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -430,19 +431,26 @@ static umf_result_t op_initialize(umf_memory_provider_handle_t provider, extent_hooks_t *pHooks = &arena_extent_hooks; size_t unsigned_size = sizeof(unsigned); + int n_arenas_set_from_params = 0; int err; const umf_jemalloc_pool_params_t *jemalloc_params = params; size_t n_arenas = 0; if (jemalloc_params) { n_arenas = jemalloc_params->n_arenas; + n_arenas_set_from_params = 1; } if (n_arenas == 0) { n_arenas = utils_get_num_cores() * 4; + if (n_arenas > MALLOCX_ARENA_MAX) { + n_arenas = MALLOCX_ARENA_MAX; + } } + if (n_arenas > MALLOCX_ARENA_MAX) { - LOG_ERR("Number of arenas exceeds the limit."); + LOG_ERR("Number of arenas %zu exceeds the limit (%i).", n_arenas, + MALLOCX_ARENA_MAX); return UMF_RESULT_ERROR_INVALID_ARGUMENT; } @@ -461,8 +469,21 @@ static umf_result_t op_initialize(umf_memory_provider_handle_t provider, err = je_mallctl("arenas.create", (void *)&arena_index, &unsigned_size, NULL, 0); if (err) { - LOG_ERR("Could not create arena."); - goto err_cleanup; + // EAGAIN - means that a memory allocation failure occurred + // (2 * utils_get_num_cores()) is the required minimum number of arenas + if (n_arenas_set_from_params || err != EAGAIN || + (i < (2 * utils_get_num_cores()))) { + LOG_ERR("Could not create a jemalloc arena (n_arenas = %zu, i " + "= %zu, arena_index = %u, unsigned_size = %zu): %s", + n_arenas, i, arena_index, unsigned_size, strerror(err)); + goto err_cleanup; + } + + LOG_WARN("Could not create the #%zu jemalloc arena (%s), setting " + "n_arenas = %zu", + i + 1, strerror(err), i); + n_arenas = i; + break; } pool->arena_index[num_created++] = arena_index;