Skip to content

Commit 10551b0

Browse files
bobpengxieDamonFool
authored andcommitted
8284950: CgroupV1 detection code should consider memory.swappiness
Backport-of: 46d208fb1ce9a3d45bee2afda824f15c84a5e4d2
1 parent 52b3b14 commit 10551b0

File tree

2 files changed

+117
-2
lines changed

2 files changed

+117
-2
lines changed

src/java.base/linux/classes/jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ private static CgroupV1Subsystem initSubSystem(Map<String, CgroupInfo> infos) {
150150
}
151151

152152
private static boolean getSwapEnabled(CgroupV1MemorySubSystemController controller) {
153-
long retval = getLongValue(controller, "memory.memsw.limit_in_bytes");
154-
return retval > 0;
153+
long memswBytes = getLongValue(controller, "memory.memsw.limit_in_bytes");
154+
long swappiness = getLongValue(controller, "memory.swappiness");
155+
return (memswBytes > 0 && swappiness > 0);
155156
}
156157

157158

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import jdk.test.lib.containers.docker.Common;
25+
import jdk.test.lib.containers.docker.DockerTestUtils;
26+
import jdk.test.lib.containers.docker.DockerRunOptions;
27+
import jdk.test.lib.process.OutputAnalyzer;
28+
import jdk.test.lib.process.ProcessTools;
29+
import jdk.internal.platform.Metrics;
30+
31+
/*
32+
* @test
33+
* @key cgroups
34+
* @requires os.family == "linux"
35+
* @modules java.base/jdk.internal.platform
36+
* @library /test/lib
37+
* @build sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean
38+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox
39+
* @run main TestMemoryWithCgroupV1
40+
*/
41+
public class TestMemoryWithCgroupV1 {
42+
43+
private static final String imageName = Common.imageName("memory");
44+
45+
public static void main(String[] args) throws Exception {
46+
// If cgroups is not configured, report success.
47+
Metrics metrics = Metrics.systemMetrics();
48+
if (metrics == null) {
49+
System.out.println("TEST PASSED!!!");
50+
return;
51+
}
52+
if ("cgroupv1".equals(metrics.getProvider())) {
53+
if (!DockerTestUtils.canTestDocker()) {
54+
return;
55+
}
56+
57+
Common.prepareWhiteBox();
58+
DockerTestUtils.buildJdkContainerImage(imageName);
59+
60+
try {
61+
testMemoryLimitWithSwappiness("100M", "150M", "100.00M",
62+
Integer.toString(((int) Math.pow(2, 20)) * 150),
63+
Integer.toString(((int) Math.pow(2, 20)) * 100));
64+
testOSBeanSwappinessMemory("200m", "250m", "0", "0");
65+
} finally {
66+
DockerTestUtils.removeDockerImage(imageName);
67+
}
68+
} else {
69+
System.out.println("Memory swappiness not supported with cgroups v2. Test skipped.");
70+
}
71+
System.out.println("TEST PASSED!!!");
72+
}
73+
74+
private static void testMemoryLimitWithSwappiness(String dockerMemLimit, String dockerSwapMemLimit,
75+
String expectedLimit, String expectedReadLimit, String expectedResetLimit)
76+
throws Exception {
77+
Common.logNewTestCase("Test print_container_info()");
78+
79+
DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo").addJavaOpts("-XshowSettings:system");
80+
opts.addDockerOpts("--memory", dockerMemLimit, "--memory-swappiness", "0", "--memory-swap", dockerSwapMemLimit);
81+
Common.addWhiteBoxOpts(opts);
82+
83+
OutputAnalyzer out = Common.run(opts);
84+
out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit)
85+
.shouldContain(
86+
"Memory and Swap Limit has been reset to " + expectedResetLimit + " because swappiness is 0")
87+
.shouldContain("Memory & Swap Limit: " + expectedLimit);
88+
}
89+
90+
private static void testOSBeanSwappinessMemory(String memoryAllocation, String swapAllocation,
91+
String swappiness, String expectedSwap) throws Exception {
92+
Common.logNewTestCase("Check OperatingSystemMXBean");
93+
DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")
94+
.addDockerOpts(
95+
"--memory", memoryAllocation,
96+
"--memory-swappiness", swappiness,
97+
"--memory-swap", swapAllocation)
98+
// CheckOperatingSystemMXBean uses Metrics (jdk.internal.platform) for
99+
// diagnostics
100+
.addJavaOpts("--add-exports")
101+
.addJavaOpts("java.base/jdk.internal.platform=ALL-UNNAMED");
102+
OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts);
103+
// in case of warnings like : "Your kernel does not support swap limit
104+
// capabilities or the cgroup is not mounted. Memory limited without swap."
105+
// the getTotalSwapSpaceSize and getFreeSwapSpaceSize return the system
106+
// values as the container setup isn't supported in that case.
107+
try {
108+
out.shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap);
109+
} catch (RuntimeException ex) {
110+
out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: [0-9]+");
111+
}
112+
}
113+
114+
}

0 commit comments

Comments
 (0)