mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
8300645: Handle julong values in logging of GET_CONTAINER_INFO macros
Reviewed-by: iklam
This commit is contained in:
@@ -159,8 +159,10 @@ template <typename T> int subsystem_file_line_contents(CgroupController* c,
|
||||
}
|
||||
PRAGMA_DIAG_POP
|
||||
|
||||
// log_fmt can be different than scan_fmt. For example
|
||||
// cpu_period() for cgv2 uses log_fmt='%d' and scan_fmt='%*s %d'
|
||||
#define GET_CONTAINER_INFO(return_type, subsystem, filename, \
|
||||
logstring, scan_fmt, variable) \
|
||||
logstring, log_fmt, scan_fmt, variable) \
|
||||
return_type variable; \
|
||||
{ \
|
||||
int err; \
|
||||
@@ -170,11 +172,11 @@ PRAGMA_DIAG_POP
|
||||
scan_fmt, \
|
||||
&variable); \
|
||||
if (err != 0) { \
|
||||
log_trace(os, container)(logstring, (return_type) OSCONTAINER_ERROR); \
|
||||
log_trace(os, container)(logstring "%d", OSCONTAINER_ERROR); \
|
||||
return (return_type) OSCONTAINER_ERROR; \
|
||||
} \
|
||||
\
|
||||
log_trace(os, container)(logstring, variable); \
|
||||
log_trace(os, container)(logstring log_fmt, variable); \
|
||||
}
|
||||
|
||||
#define GET_CONTAINER_INFO_CPTR(return_type, subsystem, filename, \
|
||||
|
||||
@@ -76,7 +76,7 @@ void CgroupV1Controller::set_subsystem_path(char *cgroup_path) {
|
||||
*/
|
||||
jlong CgroupV1MemoryController::uses_mem_hierarchy() {
|
||||
GET_CONTAINER_INFO(jlong, this, "/memory.use_hierarchy",
|
||||
"Use Hierarchy is: " JLONG_FORMAT, JLONG_FORMAT, use_hierarchy);
|
||||
"Use Hierarchy is: ", JLONG_FORMAT, JLONG_FORMAT, use_hierarchy);
|
||||
return use_hierarchy;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ void CgroupV1MemoryController::set_subsystem_path(char *cgroup_path) {
|
||||
|
||||
jlong CgroupV1Subsystem::read_memory_limit_in_bytes() {
|
||||
GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.limit_in_bytes",
|
||||
"Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit);
|
||||
"Memory Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memlimit);
|
||||
|
||||
if (memlimit >= os::Linux::physical_memory()) {
|
||||
log_trace(os, container)("Non-Hierarchical Memory Limit is: Unlimited");
|
||||
@@ -114,7 +114,7 @@ jlong CgroupV1Subsystem::read_memory_limit_in_bytes() {
|
||||
jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() {
|
||||
julong host_total_memsw;
|
||||
GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.memsw.limit_in_bytes",
|
||||
"Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit);
|
||||
"Memory and Swap Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memswlimit);
|
||||
host_total_memsw = os::Linux::host_swap() + os::Linux::physical_memory();
|
||||
if (memswlimit >= host_total_memsw) {
|
||||
log_trace(os, container)("Non-Hierarchical Memory and Swap Limit is: Unlimited");
|
||||
@@ -151,13 +151,13 @@ jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() {
|
||||
|
||||
jlong CgroupV1Subsystem::read_mem_swappiness() {
|
||||
GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.swappiness",
|
||||
"Swappiness is: " JULONG_FORMAT, JULONG_FORMAT, swappiness);
|
||||
"Swappiness is: ", JULONG_FORMAT, JULONG_FORMAT, swappiness);
|
||||
return swappiness;
|
||||
}
|
||||
|
||||
jlong CgroupV1Subsystem::memory_soft_limit_in_bytes() {
|
||||
GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.soft_limit_in_bytes",
|
||||
"Memory Soft Limit is: " JULONG_FORMAT, JULONG_FORMAT, memsoftlimit);
|
||||
"Memory Soft Limit is: ", JULONG_FORMAT, JULONG_FORMAT, memsoftlimit);
|
||||
if (memsoftlimit >= os::Linux::physical_memory()) {
|
||||
log_trace(os, container)("Memory Soft Limit is: Unlimited");
|
||||
return (jlong)-1;
|
||||
@@ -177,7 +177,7 @@ jlong CgroupV1Subsystem::memory_soft_limit_in_bytes() {
|
||||
*/
|
||||
jlong CgroupV1Subsystem::memory_usage_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.usage_in_bytes",
|
||||
"Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memusage);
|
||||
"Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, memusage);
|
||||
return memusage;
|
||||
}
|
||||
|
||||
@@ -191,20 +191,20 @@ jlong CgroupV1Subsystem::memory_usage_in_bytes() {
|
||||
*/
|
||||
jlong CgroupV1Subsystem::memory_max_usage_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.max_usage_in_bytes",
|
||||
"Maximum Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memmaxusage);
|
||||
"Maximum Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, memmaxusage);
|
||||
return memmaxusage;
|
||||
}
|
||||
|
||||
|
||||
jlong CgroupV1Subsystem::kernel_memory_usage_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.usage_in_bytes",
|
||||
"Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_usage);
|
||||
"Kernel Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, kmem_usage);
|
||||
return kmem_usage;
|
||||
}
|
||||
|
||||
jlong CgroupV1Subsystem::kernel_memory_limit_in_bytes() {
|
||||
GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.kmem.limit_in_bytes",
|
||||
"Kernel Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, kmem_limit);
|
||||
"Kernel Memory Limit is: ", JULONG_FORMAT, JULONG_FORMAT, kmem_limit);
|
||||
if (kmem_limit >= os::Linux::physical_memory()) {
|
||||
return (jlong)-1;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ jlong CgroupV1Subsystem::kernel_memory_limit_in_bytes() {
|
||||
|
||||
jlong CgroupV1Subsystem::kernel_memory_max_usage_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.max_usage_in_bytes",
|
||||
"Maximum Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_max_usage);
|
||||
"Maximum Kernel Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, kmem_max_usage);
|
||||
return kmem_max_usage;
|
||||
}
|
||||
|
||||
@@ -251,13 +251,13 @@ char * CgroupV1Subsystem::cpu_cpuset_memory_nodes() {
|
||||
*/
|
||||
int CgroupV1Subsystem::cpu_quota() {
|
||||
GET_CONTAINER_INFO(int, _cpu->controller(), "/cpu.cfs_quota_us",
|
||||
"CPU Quota is: %d", "%d", quota);
|
||||
"CPU Quota is: ", "%d", "%d", quota);
|
||||
return quota;
|
||||
}
|
||||
|
||||
int CgroupV1Subsystem::cpu_period() {
|
||||
GET_CONTAINER_INFO(int, _cpu->controller(), "/cpu.cfs_period_us",
|
||||
"CPU Period is: %d", "%d", period);
|
||||
"CPU Period is: ", "%d", "%d", period);
|
||||
return period;
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ int CgroupV1Subsystem::cpu_period() {
|
||||
*/
|
||||
int CgroupV1Subsystem::cpu_shares() {
|
||||
GET_CONTAINER_INFO(int, _cpu->controller(), "/cpu.shares",
|
||||
"CPU Shares is: %d", "%d", shares);
|
||||
"CPU Shares is: ", "%d", "%d", shares);
|
||||
// Convert 1024 to no shares setup
|
||||
if (shares == 1024) return -1;
|
||||
|
||||
@@ -313,6 +313,6 @@ jlong CgroupV1Subsystem::pids_max() {
|
||||
jlong CgroupV1Subsystem::pids_current() {
|
||||
if (_pids == nullptr) return OSCONTAINER_ERROR;
|
||||
GET_CONTAINER_INFO(jlong, _pids, "/pids.current",
|
||||
"Current number of tasks is: " JLONG_FORMAT, JLONG_FORMAT, pids_current);
|
||||
"Current number of tasks is: ", JLONG_FORMAT, JLONG_FORMAT, pids_current);
|
||||
return pids_current;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
int CgroupV2Subsystem::cpu_shares() {
|
||||
GET_CONTAINER_INFO(int, _unified, "/cpu.weight",
|
||||
"Raw value for CPU Shares is: %d", "%d", shares);
|
||||
"Raw value for CPU Shares is: ", "%d", "%d", shares);
|
||||
// Convert default value of 100 to no shares setup
|
||||
if (shares == 100) {
|
||||
log_debug(os, container)("CPU Shares is: %d", -1);
|
||||
@@ -109,7 +109,7 @@ char * CgroupV2Subsystem::cpu_cpuset_memory_nodes() {
|
||||
|
||||
int CgroupV2Subsystem::cpu_period() {
|
||||
GET_CONTAINER_INFO(int, _unified, "/cpu.max",
|
||||
"CPU Period is: %d", "%*s %d", period);
|
||||
"CPU Period is: ", "%d", "%*s %d", period);
|
||||
return period;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ int CgroupV2Subsystem::cpu_period() {
|
||||
*/
|
||||
jlong CgroupV2Subsystem::memory_usage_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, _unified, "/memory.current",
|
||||
"Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, memusage);
|
||||
"Memory Usage is: ", JLONG_FORMAT, JLONG_FORMAT, memusage);
|
||||
return memusage;
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ jlong CgroupV2Subsystem::memory_and_swap_limit_in_bytes() {
|
||||
assert(memory_limit >= 0, "swap limit without memory limit?");
|
||||
return memory_limit + swap_limit;
|
||||
}
|
||||
log_trace(os, container)("Memory and Swap Limit is: " JLONG_FORMAT, swap_limit);
|
||||
return swap_limit;
|
||||
}
|
||||
|
||||
@@ -251,6 +252,6 @@ jlong CgroupV2Subsystem::pids_max() {
|
||||
*/
|
||||
jlong CgroupV2Subsystem::pids_current() {
|
||||
GET_CONTAINER_INFO(jlong, _unified, "/pids.current",
|
||||
"Current number of tasks is: " JLONG_FORMAT, JLONG_FORMAT, pids_current);
|
||||
"Current number of tasks is: ", JLONG_FORMAT, JLONG_FORMAT, pids_current);
|
||||
return pids_current;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ public class TestMemoryAwareness {
|
||||
|
||||
testMemorySoftLimit("500m", "524288000");
|
||||
testMemorySoftLimit("1g", "1073741824");
|
||||
testMemorySwapLimitSanity();
|
||||
|
||||
// Add extra 10 Mb to allocator limit, to be sure to cause OOM
|
||||
testOOM("256m", 256 + 10);
|
||||
@@ -153,6 +154,31 @@ public class TestMemoryAwareness {
|
||||
.shouldMatch("Memory Soft Limit.*" + expectedTraceValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* This test verifies that no confusingly large positive numbers get printed on
|
||||
* systems with swapaccount=0 kernel option. On some systems -2 were converted
|
||||
* to unsigned long and printed that way. Ensure this oddity doesn't occur.
|
||||
*/
|
||||
private static void testMemorySwapLimitSanity() throws Exception {
|
||||
String valueToSet = "500m";
|
||||
String expectedTraceValue = "524288000";
|
||||
Common.logNewTestCase("memory swap sanity: " + valueToSet);
|
||||
|
||||
DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo");
|
||||
Common.addWhiteBoxOpts(opts);
|
||||
opts.addDockerOpts("--memory=" + valueToSet);
|
||||
opts.addDockerOpts("--memory-swap=" + valueToSet);
|
||||
|
||||
String neg2InUnsignedLong = "18446744073709551614";
|
||||
|
||||
Common.run(opts)
|
||||
.shouldMatch("Memory Limit is:.*" + expectedTraceValue)
|
||||
// Either for cgroup v1: a_1) same as memory limit, or b_1) -2 on systems with swapaccount=0
|
||||
// Either for cgroup v2: a_2) 0, or b_2) -2 on systems with swapaccount=0
|
||||
.shouldMatch("Memory and Swap Limit is:.*(" + expectedTraceValue + "|-2|0)")
|
||||
.shouldNotMatch("Memory and Swap Limit is:.*" + neg2InUnsignedLong);
|
||||
}
|
||||
|
||||
|
||||
// provoke OOM inside the container, see how VM reacts
|
||||
private static void testOOM(String dockerMemLimit, int sizeToAllocInMb) throws Exception {
|
||||
|
||||
@@ -83,7 +83,7 @@ public class TestMemoryWithCgroupV1 {
|
||||
OutputAnalyzer out = Common.run(opts);
|
||||
// in case of warnings like : "Your kernel does not support swap limit
|
||||
// capabilities or the cgroup is not mounted. Memory limited without swap."
|
||||
// we only have Memory and Swap Limit is: <huge integer> in the output
|
||||
// we only have 'Memory and Swap Limit is: -2' in the output
|
||||
try {
|
||||
if (out.getOutput().contains("memory_and_swap_limit_in_bytes: not supported")) {
|
||||
System.out.println("memory_and_swap_limit_in_bytes not supported, avoiding Memory and Swap Limit check");
|
||||
|
||||
Reference in New Issue
Block a user