--- old/src/hotspot/os/linux/osContainer_linux.cpp 2019-10-30 18:25:23.250061049 +0000 +++ new/src/hotspot/os/linux/osContainer_linux.cpp 2019-10-30 18:25:22.994055952 +0000 @@ -54,12 +54,16 @@ bool OSContainer::_is_initialized = false; bool OSContainer::_is_containerized = false; +int OSContainer::_active_processor_count = 1; julong _unlimited_memory; class CgroupSubsystem: CHeapObj { friend class OSContainer; + private: + volatile jlong _next_check_counter; + /* mountinfo contents */ char *_root; char *_mount_point; @@ -72,6 +76,7 @@ _root = os::strdup(root); _mount_point = os::strdup(mountpoint); _path = NULL; + _next_check_counter = min_jlong; } /* @@ -121,6 +126,15 @@ } char *subsystem_path() { return _path; } + + bool check_cache_timeout() { + return os::elapsed_counter() > _next_check_counter; + } + + void set_cache_timeout(jlong timeout) { + _next_check_counter = os::elapsed_counter() + timeout; + } + }; class CgroupMemorySubsystem: CgroupSubsystem { @@ -132,22 +146,17 @@ * file if everything else seems unlimited */ bool _uses_mem_hierarchy; volatile jlong _memory_limit_in_bytes; - volatile jlong _next_check_counter; public: CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) { _uses_mem_hierarchy = false; _memory_limit_in_bytes = -1; - _next_check_counter = min_jlong; } bool is_hierarchical() { return _uses_mem_hierarchy; } void set_hierarchical(bool value) { _uses_mem_hierarchy = value; } - bool should_check_memory_limit() { - return os::elapsed_counter() > _next_check_counter; - } jlong memory_limit_in_bytes() { return _memory_limit_in_bytes; } void set_memory_limit_in_bytes(jlong value) { _memory_limit_in_bytes = value; @@ -156,7 +165,7 @@ // between re-read avoids excessive overhead during startup without // significantly reducing the VMs ability to promptly react to reduced // memory availability - _next_check_counter = os::elapsed_counter() + (NANOSECS_PER_SEC/50); + set_cache_timeout(OSCONTAINER_CACHE_TIMEOUT); } }; @@ -481,7 +490,7 @@ * OSCONTAINER_ERROR for not supported */ jlong OSContainer::memory_limit_in_bytes() { - if (!memory->should_check_memory_limit()) { + if (!memory->check_cache_timeout()) { return memory->memory_limit_in_bytes(); } jlong memory_limit = read_memory_limit_in_bytes(); @@ -617,6 +626,14 @@ int cpu_count, limit_count; int result; + // We use a cache with a timeout to avoid performing expensive + // computations in the event this function is called frequently. + // [See 8227006]. + if (!cpu->check_cache_timeout()) { + log_trace(os, container)("OSContainer::active_processor_count (cached): %d", OSContainer::_active_processor_count); + return OSContainer::_active_processor_count; + } + cpu_count = limit_count = os::Linux::active_processor_count(); int quota = cpu_quota(); int period = cpu_period(); @@ -649,6 +666,11 @@ result = MIN2(cpu_count, limit_count); log_trace(os, container)("OSContainer::active_processor_count: %d", result); + + // Update the value and set the cache timeout to 20ms. + OSContainer::_active_processor_count = result; + cpu->set_cache_timeout(OSCONTAINER_CACHE_TIMEOUT); + return result; } --- old/src/hotspot/os/linux/osContainer_linux.hpp 2019-10-30 18:25:23.858073154 +0000 +++ new/src/hotspot/os/linux/osContainer_linux.hpp 2019-10-30 18:25:23.602068057 +0000 @@ -30,12 +30,15 @@ #include "memory/allocation.hpp" #define OSCONTAINER_ERROR (-2) +#define OSCONTAINER_CACHE_TIMEOUT (NANOSECS_PER_SEC/50) class OSContainer: AllStatic { private: static bool _is_initialized; static bool _is_containerized; + static int _active_processor_count; + static jlong read_memory_limit_in_bytes(); public: