11/*
2- * Copyright (c) 2024, Red Hat, Inc.
2+ * Copyright (c) 2024, 2025, Red Hat, Inc.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -49,20 +49,27 @@ int CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int host_cpus) {
4949}
5050
5151void CgroupUtil::adjust_controller (CgroupMemoryController* mem) {
52+ assert (mem->cgroup_path () != nullptr , " invariant" );
53+ if (strstr (mem->cgroup_path (), " ../" ) != nullptr ) {
54+ log_warning (os, container)(" Cgroup memory controller path at '%s' seems to have moved to '%s', detected limits won't be accurate" ,
55+ mem->mount_point (), mem->cgroup_path ());
56+ mem->set_subsystem_path (" /" );
57+ return ;
58+ }
5259 if (!mem->needs_hierarchy_adjustment ()) {
5360 // nothing to do
5461 return ;
5562 }
5663 log_trace (os, container)(" Adjusting controller path for memory: %s" , mem->subsystem_path ());
57- assert (mem->cgroup_path () != nullptr , " invariant" );
5864 char * orig = os::strdup (mem->cgroup_path ());
5965 char * cg_path = os::strdup (orig);
6066 char * last_slash;
6167 assert (cg_path[0 ] == ' /' , " cgroup path must start with '/'" );
6268 julong phys_mem = os::Linux::physical_memory ();
6369 char * limit_cg_path = nullptr ;
6470 jlong limit = mem->read_memory_limit_in_bytes (phys_mem);
65- jlong lowest_limit = phys_mem;
71+ jlong lowest_limit = limit < 0 ? phys_mem : limit;
72+ julong orig_limit = ((julong)lowest_limit) != phys_mem ? lowest_limit : phys_mem;
6673 while ((last_slash = strrchr (cg_path, ' /' )) != cg_path) {
6774 *last_slash = ' \0 ' ; // strip path
6875 // update to shortened path and try again
@@ -83,7 +90,7 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) {
8390 limit_cg_path = os::strdup (" /" );
8491 }
8592 assert (lowest_limit >= 0 , " limit must be positive" );
86- if ((julong)lowest_limit != phys_mem ) {
93+ if ((julong)lowest_limit != orig_limit ) {
8794 // we've found a lower limit anywhere in the hierarchy,
8895 // set the path to the limit path
8996 assert (limit_cg_path != nullptr , " limit path must be set" );
@@ -93,6 +100,7 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) {
93100 mem->subsystem_path (),
94101 lowest_limit);
95102 } else {
103+ log_trace (os, container)(" Lowest limit was: " JLONG_FORMAT, lowest_limit);
96104 log_trace (os, container)(" No lower limit found for memory in hierarchy %s, "
97105 " adjusting to original path %s" ,
98106 mem->mount_point (), orig);
@@ -104,19 +112,26 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) {
104112}
105113
106114void CgroupUtil::adjust_controller (CgroupCpuController* cpu) {
115+ assert (cpu->cgroup_path () != nullptr , " invariant" );
116+ if (strstr (cpu->cgroup_path (), " ../" ) != nullptr ) {
117+ log_warning (os, container)(" Cgroup cpu controller path at '%s' seems to have moved to '%s', detected limits won't be accurate" ,
118+ cpu->mount_point (), cpu->cgroup_path ());
119+ cpu->set_subsystem_path (" /" );
120+ return ;
121+ }
107122 if (!cpu->needs_hierarchy_adjustment ()) {
108123 // nothing to do
109124 return ;
110125 }
111126 log_trace (os, container)(" Adjusting controller path for cpu: %s" , cpu->subsystem_path ());
112- assert (cpu->cgroup_path () != nullptr , " invariant" );
113127 char * orig = os::strdup (cpu->cgroup_path ());
114128 char * cg_path = os::strdup (orig);
115129 char * last_slash;
116130 assert (cg_path[0 ] == ' /' , " cgroup path must start with '/'" );
117131 int host_cpus = os::Linux::active_processor_count ();
118132 int cpus = CgroupUtil::processor_count (cpu, host_cpus);
119- int lowest_limit = host_cpus;
133+ int lowest_limit = cpus < host_cpus ? cpus: host_cpus;
134+ int orig_limit = lowest_limit != host_cpus ? lowest_limit : host_cpus;
120135 char * limit_cg_path = nullptr ;
121136 while ((last_slash = strrchr (cg_path, ' /' )) != cg_path) {
122137 *last_slash = ' \0 ' ; // strip path
@@ -138,7 +153,7 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) {
138153 limit_cg_path = os::strdup (cg_path);
139154 }
140155 assert (lowest_limit >= 0 , " limit must be positive" );
141- if (lowest_limit != host_cpus ) {
156+ if (lowest_limit != orig_limit ) {
142157 // we've found a lower limit anywhere in the hierarchy,
143158 // set the path to the limit path
144159 assert (limit_cg_path != nullptr , " limit path must be set" );
@@ -148,6 +163,7 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) {
148163 cpu->subsystem_path (),
149164 lowest_limit);
150165 } else {
166+ log_trace (os, container)(" Lowest limit was: %d" , lowest_limit);
151167 log_trace (os, container)(" No lower limit found for cpu in hierarchy %s, "
152168 " adjusting to original path %s" ,
153169 cpu->mount_point (), orig);
0 commit comments