#endif
}
-static void checkLinuxMapCountLimits([[maybe_unused]] Logr::log_t log)
+static void checkOrFixLinuxMapCountLimits([[maybe_unused]] Logr::log_t log)
{
#ifdef __linux__
string line;
auto lim = std::stoull(line);
// mthread stack use 3 maps per stack (2 guard pages + stack itself). Multiple by 4 for extra allowance.
// Also add 2 for handler and task threads.
- auto mapsNeeded = 4ULL * g_maxMThreads * (RecThreadInfo::numTCPWorkers() + RecThreadInfo::numUDPWorkers() + 2);
+ auto workers = RecThreadInfo::numTCPWorkers() + RecThreadInfo::numUDPWorkers() + 2;
+ auto mapsNeeded = 4ULL * g_maxMThreads * workers;
if (lim < mapsNeeded) {
- SLOG(g_log << Logger::Error << "sysctl vm.max_map_count= <" << mapsNeeded << ", this may cause 'bad_alloc' exceptions" << endl,
- log->info(Logr::Error, "sysctl vm.max_map_count < mapsNeeded, this may cause 'bad_alloc' exceptions",
- "kern.max_map_count", Logging::Loggable(lim), "mapsNeeded", Logging::Loggable(mapsNeeded)));
+ g_maxMThreads = lim / (4 * workers);
+ SLOG(g_log << Logger::Error << "sysctl vm.max_map_count= <" << mapsNeeded << ", this may cause 'bad_alloc' exceptions; adjusting max-mthreads to " << g_maxMThreads << endl,
+ log->info(Logr::Error, "sysctl vm.max_map_count < mapsNeeded, this may cause 'bad_alloc' exceptions, adjusting max-mthreads",
+ "kern.max_map_count", Logging::Loggable(lim), "mapsNeeded", Logging::Loggable(mapsNeeded),
+ "max-mthreads", Logging::Loggable(g_maxMThreads)));
}
}
#endif
g_maxMThreads = ::arg().asNum("max-mthreads");
- checkLinuxMapCountLimits(log);
-
int64_t maxInFlight = ::arg().asNum("max-concurrent-requests-per-tcp-connection");
if (maxInFlight < 1 || maxInFlight > USHRT_MAX || maxInFlight >= g_maxMThreads) {
SLOG(g_log << Logger::Warning << "Asked to run with illegal max-concurrent-requests-per-tcp-connection, setting to default (10)" << endl,
auto forks = initForks(log);
checkOrFixFDS(log);
+ checkOrFixLinuxMapCountLimits(log);
#ifdef HAVE_LIBSODIUM
if (sodium_init() == -1) {