diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp index f9c6f794ebd..bed12d0ef74 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp @@ -28,7 +28,6 @@ #include "cgroupV2Subsystem_linux.hpp" #include "logging/log.hpp" #include "memory/allocation.hpp" -#include "os_linux.hpp" #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" @@ -605,6 +604,11 @@ void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) { } } +void CgroupSubsystem::adjust_controllers(physical_memory_size_type upper_mem_bound, int upper_cpu_bound) { + CgroupUtil::adjust_controller(memory_controller()->controller(), upper_mem_bound); + CgroupUtil::adjust_controller(cpu_controller()->controller(), upper_cpu_bound); +} + /* active_processor_count * * Calculate an appropriate number of active processors for the @@ -631,7 +635,7 @@ void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) { * return: * true if there were no errors. false otherwise. */ -bool CgroupSubsystem::active_processor_count(int& value) { +bool CgroupSubsystem::active_processor_count(int (*cpu_bound_func)(), int& value) { int cpu_count; int result = -1; @@ -646,7 +650,7 @@ bool CgroupSubsystem::active_processor_count(int& value) { return true; } - cpu_count = os::Linux::active_processor_count(); + cpu_count = cpu_bound_func(); if (!CgroupUtil::processor_count(contrl->controller(), cpu_count, result)) { return false; } diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp index 522b64f8816..6d238869c6e 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.hpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.hpp @@ -277,7 +277,7 @@ class CgroupMemoryController: public CHeapObj { class CgroupSubsystem: public CHeapObj { public: bool memory_limit_in_bytes(physical_memory_size_type upper_bound, physical_memory_size_type& value); - bool active_processor_count(int& value); + bool active_processor_count(int (*cpu_bound_func)(), int& value); virtual bool pids_max(uint64_t& value) = 0; virtual bool pids_current(uint64_t& value) = 0; @@ -290,6 +290,8 @@ class CgroupSubsystem: public CHeapObj { virtual CachingCgroupController* cpu_controller() = 0; virtual CgroupCpuacctController* cpuacct_controller() = 0; + void adjust_controllers(physical_memory_size_type upper_mem_bound, int upper_cpu_bound); + bool cpu_quota(int& value); bool cpu_period(int& value); bool cpu_shares(int& value); diff --git a/src/hotspot/os/linux/cgroupUtil_linux.cpp b/src/hotspot/os/linux/cgroupUtil_linux.cpp index 7aa07d53148..d1436a65e23 100644 --- a/src/hotspot/os/linux/cgroupUtil_linux.cpp +++ b/src/hotspot/os/linux/cgroupUtil_linux.cpp @@ -23,7 +23,6 @@ */ #include "cgroupUtil_linux.hpp" -#include "os_linux.hpp" bool CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int upper_bound, int& value) { assert(upper_bound > 0, "upper bound of cpus must be positive"); @@ -87,7 +86,7 @@ int CgroupUtil::get_updated_cpu_limit(CgroupCpuController* cpu, return lowest; } -void CgroupUtil::adjust_controller(CgroupMemoryController* mem) { +void CgroupUtil::adjust_controller(CgroupMemoryController* mem, physical_memory_size_type upper_bound) { assert(mem->cgroup_path() != nullptr, "invariant"); if (strstr(mem->cgroup_path(), "../") != nullptr) { log_warning(os, container)("Cgroup memory controller path at '%s' seems to have moved " @@ -105,17 +104,16 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) { char* cg_path = os::strdup(orig); char* last_slash; assert(cg_path[0] == '/', "cgroup path must start with '/'"); - physical_memory_size_type phys_mem = os::Linux::physical_memory(); char* limit_cg_path = nullptr; physical_memory_size_type limit = value_unlimited; - physical_memory_size_type lowest_limit = phys_mem; - lowest_limit = get_updated_mem_limit(mem, lowest_limit, phys_mem); - physical_memory_size_type orig_limit = lowest_limit != phys_mem ? lowest_limit : phys_mem; + physical_memory_size_type lowest_limit = upper_bound; + lowest_limit = get_updated_mem_limit(mem, lowest_limit, upper_bound); + physical_memory_size_type orig_limit = lowest_limit != upper_bound ? lowest_limit : upper_bound; while ((last_slash = strrchr(cg_path, '/')) != cg_path) { *last_slash = '\0'; // strip path // update to shortened path and try again mem->set_subsystem_path(cg_path); - limit = get_updated_mem_limit(mem, lowest_limit, phys_mem); + limit = get_updated_mem_limit(mem, lowest_limit, upper_bound); if (limit < lowest_limit) { lowest_limit = limit; os::free(limit_cg_path); // handles nullptr @@ -124,13 +122,13 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) { } // need to check limit at mount point mem->set_subsystem_path("/"); - limit = get_updated_mem_limit(mem, lowest_limit, phys_mem); + limit = get_updated_mem_limit(mem, lowest_limit, upper_bound); if (limit < lowest_limit) { lowest_limit = limit; os::free(limit_cg_path); // handles nullptr limit_cg_path = os::strdup("/"); } - assert(lowest_limit <= phys_mem, "limit must not exceed host memory"); + assert(lowest_limit <= upper_bound, "limit must not exceed upper bound"); if (lowest_limit != orig_limit) { // we've found a lower limit anywhere in the hierarchy, // set the path to the limit path @@ -152,7 +150,7 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) { os::free(limit_cg_path); } -void CgroupUtil::adjust_controller(CgroupCpuController* cpu) { +void CgroupUtil::adjust_controller(CgroupCpuController* cpu, int upper_bound) { assert(cpu->cgroup_path() != nullptr, "invariant"); if (strstr(cpu->cgroup_path(), "../") != nullptr) { log_warning(os, container)("Cgroup cpu controller path at '%s' seems to have moved " @@ -170,17 +168,16 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) { char* cg_path = os::strdup(orig); char* last_slash; assert(cg_path[0] == '/', "cgroup path must start with '/'"); - int host_cpus = os::Linux::active_processor_count(); - int lowest_limit = host_cpus; - int cpus = get_updated_cpu_limit(cpu, lowest_limit, host_cpus); - int orig_limit = lowest_limit != host_cpus ? lowest_limit : host_cpus; + int lowest_limit = upper_bound; + int cpus = get_updated_cpu_limit(cpu, lowest_limit, upper_bound); + int orig_limit = lowest_limit != upper_bound ? lowest_limit : upper_bound; char* limit_cg_path = nullptr; while ((last_slash = strrchr(cg_path, '/')) != cg_path) { *last_slash = '\0'; // strip path // update to shortened path and try again cpu->set_subsystem_path(cg_path); - cpus = get_updated_cpu_limit(cpu, lowest_limit, host_cpus); - if (cpus != host_cpus && cpus < lowest_limit) { + cpus = get_updated_cpu_limit(cpu, lowest_limit, upper_bound); + if (cpus != upper_bound && cpus < lowest_limit) { lowest_limit = cpus; os::free(limit_cg_path); // handles nullptr limit_cg_path = os::strdup(cg_path); @@ -188,8 +185,8 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) { } // need to check limit at mount point cpu->set_subsystem_path("/"); - cpus = get_updated_cpu_limit(cpu, lowest_limit, host_cpus); - if (cpus != host_cpus && cpus < lowest_limit) { + cpus = get_updated_cpu_limit(cpu, lowest_limit, upper_bound); + if (cpus != upper_bound && cpus < lowest_limit) { lowest_limit = cpus; os::free(limit_cg_path); // handles nullptr limit_cg_path = os::strdup(cg_path); diff --git a/src/hotspot/os/linux/cgroupUtil_linux.hpp b/src/hotspot/os/linux/cgroupUtil_linux.hpp index d72bbd1cf1e..9a2e609c68c 100644 --- a/src/hotspot/os/linux/cgroupUtil_linux.hpp +++ b/src/hotspot/os/linux/cgroupUtil_linux.hpp @@ -34,10 +34,10 @@ class CgroupUtil: AllStatic { static bool processor_count(CgroupCpuController* cpu, int upper_bound, int& value); // Given a memory controller, adjust its path to a point in the hierarchy // that represents the closest memory limit. - static void adjust_controller(CgroupMemoryController* m); + static void adjust_controller(CgroupMemoryController* m, physical_memory_size_type upper_bound); // Given a cpu controller, adjust its path to a point in the hierarchy // that represents the closest cpu limit. - static void adjust_controller(CgroupCpuController* c); + static void adjust_controller(CgroupCpuController* c, int upper_bound); private: static physical_memory_size_type get_updated_mem_limit(CgroupMemoryController* m, physical_memory_size_type lowest, diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp index 2df604083d2..95f295dd64e 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp @@ -326,8 +326,6 @@ CgroupV1Subsystem::CgroupV1Subsystem(CgroupV1Controller* cpuset, _cpuset(cpuset), _cpuacct(cpuacct), _pids(pids) { - CgroupUtil::adjust_controller(memory); - CgroupUtil::adjust_controller(cpu); _memory = new CachingCgroupController(memory); _cpu = new CachingCgroupController(cpu); } diff --git a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp index c61d30e9236..f884eeee79d 100644 --- a/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp @@ -154,8 +154,6 @@ CgroupV2Subsystem::CgroupV2Subsystem(CgroupV2MemoryController * memory, CgroupV2CpuacctController* cpuacct, CgroupV2Controller unified) : _unified(unified) { - CgroupUtil::adjust_controller(memory); - CgroupUtil::adjust_controller(cpu); _memory = new CachingCgroupController(memory); _cpu = new CachingCgroupController(cpu); _cpuacct = cpuacct; diff --git a/src/hotspot/os/linux/osContainer_linux.cpp b/src/hotspot/os/linux/osContainer_linux.cpp index 15a6403d07f..6869ce947dc 100644 --- a/src/hotspot/os/linux/osContainer_linux.cpp +++ b/src/hotspot/os/linux/osContainer_linux.cpp @@ -59,6 +59,11 @@ void OSContainer::init() { if (cgroup_subsystem == nullptr) { return; // Required subsystem files not found or other error } + // Adjust controller paths once subsystem is initialized + physical_memory_size_type phys_mem = os::Linux::physical_memory(); + int host_cpus = os::Linux::active_processor_count(); + cgroup_subsystem->adjust_controllers(phys_mem, host_cpus); + /* * In order to avoid a false positive on is_containerized() on * Linux systems outside a container *and* to ensure compatibility @@ -254,7 +259,7 @@ char * OSContainer::cpu_cpuset_memory_nodes() { bool OSContainer::active_processor_count(int& value) { assert(cgroup_subsystem != nullptr, "cgroup subsystem not available"); - return cgroup_subsystem->active_processor_count(value); + return cgroup_subsystem->active_processor_count(&os::Linux::active_processor_count, value); } bool OSContainer::cpu_quota(int& value) { diff --git a/test/hotspot/gtest/runtime/test_cgroupSubsystem_linux.cpp b/test/hotspot/gtest/runtime/test_cgroupSubsystem_linux.cpp index 7a4f7bcb99e..69d04ae8883 100644 --- a/test/hotspot/gtest/runtime/test_cgroupSubsystem_linux.cpp +++ b/test/hotspot/gtest/runtime/test_cgroupSubsystem_linux.cpp @@ -479,7 +479,7 @@ TEST(cgroupTest, set_cgroupv1_subsystem_path_adjusted) { ccc->set_subsystem_path((char*)cpu.cgroup_path); EXPECT_TRUE(ccc->needs_hierarchy_adjustment()); - CgroupUtil::adjust_controller(ccc); + CgroupUtil::adjust_controller(ccc, 1); ASSERT_STREQ(cpu.expected_path, ccc->subsystem_path()); EXPECT_FALSE(ccc->needs_hierarchy_adjustment()); @@ -489,7 +489,7 @@ TEST(cgroupTest, set_cgroupv1_subsystem_path_adjusted) { cmc->set_subsystem_path((char*)memory.cgroup_path); EXPECT_TRUE(cmc->needs_hierarchy_adjustment()); - CgroupUtil::adjust_controller(cmc); + CgroupUtil::adjust_controller(cmc, (physical_memory_size_type)1024); ASSERT_STREQ(memory.expected_path, cmc->subsystem_path()); EXPECT_FALSE(cmc->needs_hierarchy_adjustment()); } @@ -512,7 +512,7 @@ TEST(cgroupTest, set_cgroupv2_subsystem_path_adjusted) { true /* read-only mount */)); EXPECT_TRUE(ccc->needs_hierarchy_adjustment()); - CgroupUtil::adjust_controller(ccc); + CgroupUtil::adjust_controller(ccc, 1); ASSERT_STREQ(cpu.expected_path, ccc->subsystem_path()); EXPECT_FALSE(ccc->needs_hierarchy_adjustment()); @@ -521,7 +521,7 @@ TEST(cgroupTest, set_cgroupv2_subsystem_path_adjusted) { true /* read-only mount */)); EXPECT_TRUE(cmc->needs_hierarchy_adjustment()); - CgroupUtil::adjust_controller(cmc); + CgroupUtil::adjust_controller(cmc, (physical_memory_size_type)1024); ASSERT_STREQ(memory.expected_path, cmc->subsystem_path()); EXPECT_FALSE(cmc->needs_hierarchy_adjustment()); }