1
1
/*
2
- * Copyright (c) 2024, Red Hat, Inc.
2
+ * Copyright (c) 2024, 2025, Red Hat, Inc.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* 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) {
49
49
}
50
50
51
51
void 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
+ }
52
59
if (!mem->needs_hierarchy_adjustment ()) {
53
60
// nothing to do
54
61
return ;
55
62
}
56
63
log_trace (os, container)(" Adjusting controller path for memory: %s" , mem->subsystem_path ());
57
- assert (mem->cgroup_path () != nullptr , " invariant" );
58
64
char * orig = os::strdup (mem->cgroup_path ());
59
65
char * cg_path = os::strdup (orig);
60
66
char * last_slash;
61
67
assert (cg_path[0 ] == ' /' , " cgroup path must start with '/'" );
62
68
julong phys_mem = os::Linux::physical_memory ();
63
69
char * limit_cg_path = nullptr ;
64
70
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;
66
73
while ((last_slash = strrchr (cg_path, ' /' )) != cg_path) {
67
74
*last_slash = ' \0 ' ; // strip path
68
75
// update to shortened path and try again
@@ -83,7 +90,7 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) {
83
90
limit_cg_path = os::strdup (" /" );
84
91
}
85
92
assert (lowest_limit >= 0 , " limit must be positive" );
86
- if ((julong)lowest_limit != phys_mem ) {
93
+ if ((julong)lowest_limit != orig_limit ) {
87
94
// we've found a lower limit anywhere in the hierarchy,
88
95
// set the path to the limit path
89
96
assert (limit_cg_path != nullptr , " limit path must be set" );
@@ -93,6 +100,7 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) {
93
100
mem->subsystem_path (),
94
101
lowest_limit);
95
102
} else {
103
+ log_trace (os, container)(" Lowest limit was: " JLONG_FORMAT, lowest_limit);
96
104
log_trace (os, container)(" No lower limit found for memory in hierarchy %s, "
97
105
" adjusting to original path %s" ,
98
106
mem->mount_point (), orig);
@@ -104,19 +112,26 @@ void CgroupUtil::adjust_controller(CgroupMemoryController* mem) {
104
112
}
105
113
106
114
void 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
+ }
107
122
if (!cpu->needs_hierarchy_adjustment ()) {
108
123
// nothing to do
109
124
return ;
110
125
}
111
126
log_trace (os, container)(" Adjusting controller path for cpu: %s" , cpu->subsystem_path ());
112
- assert (cpu->cgroup_path () != nullptr , " invariant" );
113
127
char * orig = os::strdup (cpu->cgroup_path ());
114
128
char * cg_path = os::strdup (orig);
115
129
char * last_slash;
116
130
assert (cg_path[0 ] == ' /' , " cgroup path must start with '/'" );
117
131
int host_cpus = os::Linux::active_processor_count ();
118
132
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;
120
135
char * limit_cg_path = nullptr ;
121
136
while ((last_slash = strrchr (cg_path, ' /' )) != cg_path) {
122
137
*last_slash = ' \0 ' ; // strip path
@@ -138,7 +153,7 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) {
138
153
limit_cg_path = os::strdup (cg_path);
139
154
}
140
155
assert (lowest_limit >= 0 , " limit must be positive" );
141
- if (lowest_limit != host_cpus ) {
156
+ if (lowest_limit != orig_limit ) {
142
157
// we've found a lower limit anywhere in the hierarchy,
143
158
// set the path to the limit path
144
159
assert (limit_cg_path != nullptr , " limit path must be set" );
@@ -148,6 +163,7 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) {
148
163
cpu->subsystem_path (),
149
164
lowest_limit);
150
165
} else {
166
+ log_trace (os, container)(" Lowest limit was: %d" , lowest_limit);
151
167
log_trace (os, container)(" No lower limit found for cpu in hierarchy %s, "
152
168
" adjusting to original path %s" ,
153
169
cpu->mount_point (), orig);
0 commit comments