Skip to content

Commit 850bc20

Browse files
committed
8356868: Not all cgroup parameters are made available
Reviewed-by: sgehwolf, gziemski
1 parent 75ce44a commit 850bc20

10 files changed

+163
-15
lines changed

src/hotspot/os/linux/cgroupSubsystem_linux.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ CgroupSubsystem* CgroupSubsystemFactory::create() {
6262
CgroupV1MemoryController* memory = nullptr;
6363
CgroupV1Controller* cpuset = nullptr;
6464
CgroupV1CpuController* cpu = nullptr;
65-
CgroupV1Controller* cpuacct = nullptr;
65+
CgroupV1CpuacctController* cpuacct = nullptr;
6666
CgroupV1Controller* pids = nullptr;
6767
CgroupInfo cg_infos[CG_INFO_LENGTH];
6868
u1 cg_type_flags = INVALID_CGROUPS_GENERIC;
@@ -105,9 +105,10 @@ CgroupSubsystem* CgroupSubsystemFactory::create() {
105105
CgroupV2CpuController* cpu = new CgroupV2CpuController(CgroupV2Controller(cg_infos[CPU_IDX]._mount_path,
106106
cg_infos[CPU_IDX]._cgroup_path,
107107
cg_infos[CPU_IDX]._read_only));
108+
CgroupV2CpuacctController* cpuacct = new CgroupV2CpuacctController(cpu);
108109
log_debug(os, container)("Detected cgroups v2 unified hierarchy");
109110
cleanup(cg_infos);
110-
return new CgroupV2Subsystem(memory, cpu, mem_other);
111+
return new CgroupV2Subsystem(memory, cpu, cpuacct, mem_other);
111112
}
112113

113114
/*
@@ -150,7 +151,7 @@ CgroupSubsystem* CgroupSubsystemFactory::create() {
150151
cpu = new CgroupV1CpuController(CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only));
151152
cpu->set_subsystem_path(info._cgroup_path);
152153
} else if (strcmp(info._name, "cpuacct") == 0) {
153-
cpuacct = new CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only);
154+
cpuacct = new CgroupV1CpuacctController(CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only));
154155
cpuacct->set_subsystem_path(info._cgroup_path);
155156
} else if (strcmp(info._name, "pids") == 0) {
156157
pids = new CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only);
@@ -856,6 +857,10 @@ jlong CgroupSubsystem::memory_soft_limit_in_bytes() {
856857
return memory_controller()->controller()->memory_soft_limit_in_bytes(phys_mem);
857858
}
858859

860+
jlong CgroupSubsystem::memory_throttle_limit_in_bytes() {
861+
return memory_controller()->controller()->memory_throttle_limit_in_bytes();
862+
}
863+
859864
jlong CgroupSubsystem::memory_usage_in_bytes() {
860865
return memory_controller()->controller()->memory_usage_in_bytes();
861866
}
@@ -884,6 +889,10 @@ int CgroupSubsystem::cpu_shares() {
884889
return cpu_controller()->controller()->cpu_shares();
885890
}
886891

892+
jlong CgroupSubsystem::cpu_usage_in_micros() {
893+
return cpuacct_controller()->cpu_usage_in_micros();
894+
}
895+
887896
void CgroupSubsystem::print_version_specific_info(outputStream* st) {
888897
julong phys_mem = os::Linux::physical_memory();
889898
memory_controller()->controller()->print_version_specific_info(st, phys_mem);

src/hotspot/os/linux/cgroupSubsystem_linux.hpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
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
@@ -216,6 +216,18 @@ class CgroupCpuController: public CHeapObj<mtInternal> {
216216
virtual const char* cgroup_path() = 0;
217217
};
218218

219+
// Pure virtual class representing version agnostic CPU accounting controllers
220+
class CgroupCpuacctController: public CHeapObj<mtInternal> {
221+
public:
222+
virtual jlong cpu_usage_in_micros() = 0;
223+
virtual bool needs_hierarchy_adjustment() = 0;
224+
virtual bool is_read_only() = 0;
225+
virtual const char* subsystem_path() = 0;
226+
virtual void set_subsystem_path(const char* cgroup_path) = 0;
227+
virtual const char* mount_point() = 0;
228+
virtual const char* cgroup_path() = 0;
229+
};
230+
219231
// Pure virtual class representing version agnostic memory controllers
220232
class CgroupMemoryController: public CHeapObj<mtInternal> {
221233
public:
@@ -224,6 +236,7 @@ class CgroupMemoryController: public CHeapObj<mtInternal> {
224236
virtual jlong memory_and_swap_limit_in_bytes(julong host_mem, julong host_swap) = 0;
225237
virtual jlong memory_and_swap_usage_in_bytes(julong host_mem, julong host_swap) = 0;
226238
virtual jlong memory_soft_limit_in_bytes(julong upper_bound) = 0;
239+
virtual jlong memory_throttle_limit_in_bytes() = 0;
227240
virtual jlong memory_max_usage_in_bytes() = 0;
228241
virtual jlong rss_usage_in_bytes() = 0;
229242
virtual jlong cache_usage_in_bytes() = 0;
@@ -250,15 +263,19 @@ class CgroupSubsystem: public CHeapObj<mtInternal> {
250263
virtual const char * container_type() = 0;
251264
virtual CachingCgroupController<CgroupMemoryController>* memory_controller() = 0;
252265
virtual CachingCgroupController<CgroupCpuController>* cpu_controller() = 0;
266+
virtual CgroupCpuacctController* cpuacct_controller() = 0;
253267

254268
int cpu_quota();
255269
int cpu_period();
256270
int cpu_shares();
257271

272+
jlong cpu_usage_in_micros();
273+
258274
jlong memory_usage_in_bytes();
259275
jlong memory_and_swap_limit_in_bytes();
260276
jlong memory_and_swap_usage_in_bytes();
261277
jlong memory_soft_limit_in_bytes();
278+
jlong memory_throttle_limit_in_bytes();
262279
jlong memory_max_usage_in_bytes();
263280
jlong rss_usage_in_bytes();
264281
jlong cache_usage_in_bytes();

src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,16 @@ jlong CgroupV1MemoryController::memory_soft_limit_in_bytes(julong phys_mem) {
248248
}
249249
}
250250

251+
jlong CgroupV1MemoryController::memory_throttle_limit_in_bytes() {
252+
// Log this string at trace level so as to make tests happy.
253+
log_trace(os, container)("Memory Throttle Limit is not supported.");
254+
return OSCONTAINER_ERROR; // not supported
255+
}
256+
251257
// Constructor
252258
CgroupV1Subsystem::CgroupV1Subsystem(CgroupV1Controller* cpuset,
253259
CgroupV1CpuController* cpu,
254-
CgroupV1Controller* cpuacct,
260+
CgroupV1CpuacctController* cpuacct,
255261
CgroupV1Controller* pids,
256262
CgroupV1MemoryController* memory) :
257263
_cpuset(cpuset),
@@ -416,6 +422,13 @@ int CgroupV1CpuController::cpu_shares() {
416422
return shares_int;
417423
}
418424

425+
jlong CgroupV1CpuacctController::cpu_usage_in_micros() {
426+
julong cpu_usage;
427+
CONTAINER_READ_NUMBER_CHECKED(reader(), "/cpuacct.usage", "CPU Usage", cpu_usage);
428+
// Output is in nanoseconds, convert to microseconds.
429+
return (jlong)cpu_usage / 1000;
430+
}
431+
419432
/* pids_max
420433
*
421434
* Return the maximum number of tasks available to the process

src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
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
@@ -82,6 +82,7 @@ class CgroupV1MemoryController final : public CgroupMemoryController {
8282
jlong memory_and_swap_limit_in_bytes(julong host_mem, julong host_swap) override;
8383
jlong memory_and_swap_usage_in_bytes(julong host_mem, julong host_swap) override;
8484
jlong memory_soft_limit_in_bytes(julong upper_bound) override;
85+
jlong memory_throttle_limit_in_bytes() override;
8586
jlong memory_max_usage_in_bytes() override;
8687
jlong rss_usage_in_bytes() override;
8788
jlong cache_usage_in_bytes() override;
@@ -140,12 +141,41 @@ class CgroupV1CpuController final : public CgroupCpuController {
140141
}
141142
};
142143

144+
class CgroupV1CpuacctController final : public CgroupCpuacctController {
145+
146+
private:
147+
CgroupV1Controller _reader;
148+
CgroupV1Controller* reader() { return &_reader; }
149+
public:
150+
jlong cpu_usage_in_micros() override;
151+
void set_subsystem_path(const char *cgroup_path) override {
152+
reader()->set_subsystem_path(cgroup_path);
153+
}
154+
bool is_read_only() override {
155+
return reader()->is_read_only();
156+
}
157+
const char* subsystem_path() override {
158+
return reader()->subsystem_path();
159+
}
160+
const char* mount_point() override {
161+
return reader()->mount_point();
162+
}
163+
bool needs_hierarchy_adjustment() override {
164+
return reader()->needs_hierarchy_adjustment();
165+
}
166+
const char* cgroup_path() override { return reader()->cgroup_path(); }
167+
168+
public:
169+
CgroupV1CpuacctController(const CgroupV1Controller& reader) : _reader(reader) {
170+
}
171+
};
172+
143173
class CgroupV1Subsystem: public CgroupSubsystem {
144174

145175
public:
146176
CgroupV1Subsystem(CgroupV1Controller* cpuset,
147177
CgroupV1CpuController* cpu,
148-
CgroupV1Controller* cpuacct,
178+
CgroupV1CpuacctController* cpuacct,
149179
CgroupV1Controller* pids,
150180
CgroupV1MemoryController* memory);
151181

@@ -165,13 +195,14 @@ class CgroupV1Subsystem: public CgroupSubsystem {
165195
}
166196
CachingCgroupController<CgroupMemoryController>* memory_controller() { return _memory; }
167197
CachingCgroupController<CgroupCpuController>* cpu_controller() { return _cpu; }
198+
CgroupCpuacctController* cpuacct_controller() { return _cpuacct; }
168199

169200
private:
170201
/* controllers */
171202
CachingCgroupController<CgroupMemoryController>* _memory = nullptr;
172203
CgroupV1Controller* _cpuset = nullptr;
173204
CachingCgroupController<CgroupCpuController>* _cpu = nullptr;
174-
CgroupV1Controller* _cpuacct = nullptr;
205+
CgroupV1CpuacctController* _cpuacct = nullptr;
175206
CgroupV1Controller* _pids = nullptr;
176207

177208
};

src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2020, 2025, Red Hat Inc.
3+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -114,12 +115,14 @@ int CgroupV2CpuController::cpu_quota() {
114115
// Constructor
115116
CgroupV2Subsystem::CgroupV2Subsystem(CgroupV2MemoryController * memory,
116117
CgroupV2CpuController* cpu,
118+
CgroupV2CpuacctController* cpuacct,
117119
CgroupV2Controller unified) :
118120
_unified(unified) {
119121
CgroupUtil::adjust_controller(memory);
120122
CgroupUtil::adjust_controller(cpu);
121123
_memory = new CachingCgroupController<CgroupMemoryController>(memory);
122124
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
125+
_cpuacct = cpuacct;
123126
}
124127

125128
bool CgroupV2Subsystem::is_containerized() {
@@ -152,6 +155,17 @@ int CgroupV2CpuController::cpu_period() {
152155
return period;
153156
}
154157

158+
jlong CgroupV2CpuController::cpu_usage_in_micros() {
159+
julong cpu_usage;
160+
bool is_ok = reader()->read_numerical_key_value("/cpu.stat", "usage_usec", &cpu_usage);
161+
if (!is_ok) {
162+
log_trace(os, container)("CPU Usage failed: %d", OSCONTAINER_ERROR);
163+
return OSCONTAINER_ERROR;
164+
}
165+
log_trace(os, container)("CPU Usage is: " JULONG_FORMAT, cpu_usage);
166+
return (jlong)cpu_usage;
167+
}
168+
155169
/* memory_usage_in_bytes
156170
*
157171
* Return the amount of used memory used by this cgroup and descendents
@@ -173,10 +187,16 @@ jlong CgroupV2MemoryController::memory_soft_limit_in_bytes(julong phys_mem) {
173187
return mem_soft_limit;
174188
}
175189

190+
jlong CgroupV2MemoryController::memory_throttle_limit_in_bytes() {
191+
jlong mem_throttle_limit;
192+
CONTAINER_READ_NUMBER_CHECKED_MAX(reader(), "/memory.high", "Memory Throttle Limit", mem_throttle_limit);
193+
return mem_throttle_limit;
194+
}
195+
176196
jlong CgroupV2MemoryController::memory_max_usage_in_bytes() {
177-
// Log this string at trace level so as to make tests happy.
178-
log_trace(os, container)("Maximum Memory Usage is not supported.");
179-
return OSCONTAINER_ERROR; // not supported
197+
julong mem_max_usage;
198+
CONTAINER_READ_NUMBER_CHECKED(reader(), "/memory.peak", "Maximum Memory Usage", mem_max_usage);
199+
return mem_max_usage;
180200
}
181201

182202
jlong CgroupV2MemoryController::rss_usage_in_bytes() {

src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2020, 2024, Red Hat Inc.
3+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -61,6 +62,34 @@ class CgroupV2CpuController: public CgroupCpuController {
6162
int cpu_quota() override;
6263
int cpu_period() override;
6364
int cpu_shares() override;
65+
jlong cpu_usage_in_micros();
66+
bool is_read_only() override {
67+
return reader()->is_read_only();
68+
}
69+
const char* subsystem_path() override {
70+
return reader()->subsystem_path();
71+
}
72+
bool needs_hierarchy_adjustment() override {
73+
return reader()->needs_hierarchy_adjustment();
74+
}
75+
void set_subsystem_path(const char* cgroup_path) override {
76+
reader()->set_subsystem_path(cgroup_path);
77+
}
78+
const char* mount_point() override { return reader()->mount_point(); }
79+
const char* cgroup_path() override { return reader()->cgroup_path(); }
80+
};
81+
82+
class CgroupV2CpuacctController: public CgroupCpuacctController {
83+
private:
84+
CgroupV2CpuController* _reader;
85+
CgroupV2CpuController* reader() { return _reader; }
86+
public:
87+
CgroupV2CpuacctController(CgroupV2CpuController* reader) : _reader(reader) {
88+
}
89+
// In cgroup v2, cpu usage is a part of the cpu controller.
90+
jlong cpu_usage_in_micros() override {
91+
return reader()->cpu_usage_in_micros();
92+
}
6493
bool is_read_only() override {
6594
return reader()->is_read_only();
6695
}
@@ -89,6 +118,7 @@ class CgroupV2MemoryController final: public CgroupMemoryController {
89118
jlong memory_and_swap_limit_in_bytes(julong host_mem, julong host_swp) override;
90119
jlong memory_and_swap_usage_in_bytes(julong host_mem, julong host_swp) override;
91120
jlong memory_soft_limit_in_bytes(julong upper_bound) override;
121+
jlong memory_throttle_limit_in_bytes() override;
92122
jlong memory_usage_in_bytes() override;
93123
jlong memory_max_usage_in_bytes() override;
94124
jlong rss_usage_in_bytes() override;
@@ -118,11 +148,14 @@ class CgroupV2Subsystem: public CgroupSubsystem {
118148
CachingCgroupController<CgroupMemoryController>* _memory = nullptr;
119149
CachingCgroupController<CgroupCpuController>* _cpu = nullptr;
120150

151+
CgroupCpuacctController* _cpuacct = nullptr;
152+
121153
CgroupV2Controller* unified() { return &_unified; }
122154

123155
public:
124156
CgroupV2Subsystem(CgroupV2MemoryController * memory,
125157
CgroupV2CpuController* cpu,
158+
CgroupV2CpuacctController* cpuacct,
126159
CgroupV2Controller unified);
127160

128161
char * cpu_cpuset_cpus() override;
@@ -137,6 +170,7 @@ class CgroupV2Subsystem: public CgroupSubsystem {
137170
}
138171
CachingCgroupController<CgroupMemoryController>* memory_controller() override { return _memory; }
139172
CachingCgroupController<CgroupCpuController>* cpu_controller() override { return _cpu; }
173+
CgroupCpuacctController* cpuacct_controller() override { return _cpuacct; };
140174
};
141175

142176
#endif // CGROUP_V2_SUBSYSTEM_LINUX_HPP

src/hotspot/os/linux/osContainer_linux.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
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
@@ -122,6 +122,11 @@ jlong OSContainer::memory_soft_limit_in_bytes() {
122122
return cgroup_subsystem->memory_soft_limit_in_bytes();
123123
}
124124

125+
jlong OSContainer::memory_throttle_limit_in_bytes() {
126+
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
127+
return cgroup_subsystem->memory_throttle_limit_in_bytes();
128+
}
129+
125130
jlong OSContainer::memory_usage_in_bytes() {
126131
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
127132
return cgroup_subsystem->memory_usage_in_bytes();
@@ -177,6 +182,11 @@ int OSContainer::cpu_shares() {
177182
return cgroup_subsystem->cpu_shares();
178183
}
179184

185+
jlong OSContainer::cpu_usage_in_micros() {
186+
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
187+
return cgroup_subsystem->cpu_usage_in_micros();
188+
}
189+
180190
jlong OSContainer::pids_max() {
181191
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
182192
return cgroup_subsystem->pids_max();

src/hotspot/os/linux/osContainer_linux.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
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
@@ -54,6 +54,7 @@ class OSContainer: AllStatic {
5454
static jlong memory_and_swap_limit_in_bytes();
5555
static jlong memory_and_swap_usage_in_bytes();
5656
static jlong memory_soft_limit_in_bytes();
57+
static jlong memory_throttle_limit_in_bytes();
5758
static jlong memory_usage_in_bytes();
5859
static jlong memory_max_usage_in_bytes();
5960
static jlong rss_usage_in_bytes();
@@ -69,6 +70,8 @@ class OSContainer: AllStatic {
6970

7071
static int cpu_shares();
7172

73+
static jlong cpu_usage_in_micros();
74+
7275
static jlong pids_max();
7376
static jlong pids_current();
7477
};

0 commit comments

Comments
 (0)