move os::linux calls out of cgroups

This commit is contained in:
Casper Norrbin 2026-01-13 10:45:17 +00:00
parent 8402891889
commit b635c7a7db
8 changed files with 37 additions and 33 deletions

View File

@ -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;
}

View File

@ -277,7 +277,7 @@ class CgroupMemoryController: public CHeapObj<mtInternal> {
class CgroupSubsystem: public CHeapObj<mtInternal> {
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<mtInternal> {
virtual CachingCgroupController<CgroupCpuController>* 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);

View File

@ -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);

View File

@ -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,

View File

@ -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<CgroupMemoryController>(memory);
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
}

View File

@ -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<CgroupMemoryController>(memory);
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
_cpuacct = cpuacct;

View File

@ -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) {

View File

@ -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());
}