8253797: [cgroups v2] Account for the fact that swap accounting is disabled on some systems

Reviewed-by: hseigel
This commit is contained in:
Severin Gehwolf 2020-12-10 16:47:02 +00:00
parent 6be1f5671e
commit 669361117d
2 changed files with 44 additions and 21 deletions

View File

@ -48,16 +48,21 @@ public class CgroupV2Subsystem implements CgroupSubsystem {
private static final int PER_CPU_SHARES = 1024;
private static final String MAX_VAL = "max";
private static final Object EMPTY_STR = "";
private static final long NO_SWAP = 0;
private CgroupV2Subsystem(CgroupSubsystemController unified) {
this.unified = unified;
}
private long getLongVal(String file) {
private long getLongVal(String file, long defaultValue) {
return CgroupSubsystemController.getLongValue(unified,
file,
CgroupV2SubsystemController::convertStringToLong,
CgroupSubsystem.LONG_RETVAL_UNLIMITED);
defaultValue);
}
private long getLongVal(String file) {
return getLongVal(file, CgroupSubsystem.LONG_RETVAL_UNLIMITED);
}
private static CgroupV2Subsystem initSubsystem() {
@ -289,6 +294,11 @@ public class CgroupV2Subsystem implements CgroupSubsystem {
@Override
public long getMemoryAndSwapLimit() {
String strVal = CgroupSubsystemController.getStringValue(unified, "memory.swap.max");
// We only get a null string when file memory.swap.max doesn't exist.
// In that case we return the memory limit without any swap.
if (strVal == null) {
return getMemoryLimit();
}
long swapLimit = limitFromString(strVal);
if (swapLimit >= 0) {
long memoryLimit = getMemoryLimit();
@ -307,9 +317,14 @@ public class CgroupV2Subsystem implements CgroupSubsystem {
*/
@Override
public long getMemoryAndSwapUsage() {
long swapUsage = getLongVal("memory.swap.current");
long memoryUsage = getMemoryUsage();
return memoryUsage + swapUsage;
if (memoryUsage >= 0) {
// If file memory.swap.current doesn't exist, only return the regular
// memory usage (without swap). Thus, use default value of NO_SWAP.
long swapUsage = getLongVal("memory.swap.current", NO_SWAP);
return memoryUsage + swapUsage;
}
return memoryUsage; // case of no memory limits
}
@Override

View File

@ -239,25 +239,33 @@ public class MetricsTesterCgroupV2 implements CgroupMetricsTester {
fail("memory.stat[sock]", oldVal, newVal);
}
oldVal = metrics.getMemoryAndSwapLimit();
long valSwap = getLongLimitValueFromFile("memory.swap.max");
long valMemory = getLongLimitValueFromFile("memory.max");
if (valSwap == UNLIMITED) {
newVal = valSwap;
long memAndSwapLimit = metrics.getMemoryAndSwapLimit();
long memLimit = metrics.getMemoryLimit();
// Only test swap memory limits if we can. On systems with swapaccount=0
// we cannot, as swap limits are disabled.
if (memAndSwapLimit <= memLimit) {
System.out.println("No swap memory limits, test case(s) skipped");
} else {
assert valMemory >= 0;
newVal = valSwap + valMemory;
}
if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
fail("memory.swap.max", oldVal, newVal);
}
oldVal = memAndSwapLimit;
long valSwap = getLongLimitValueFromFile("memory.swap.max");
long valMemory = getLongLimitValueFromFile("memory.max");
if (valSwap == UNLIMITED) {
newVal = valSwap;
} else {
assert valMemory >= 0;
newVal = valSwap + valMemory;
}
if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
fail("memory.swap.max", oldVal, newVal);
}
oldVal = metrics.getMemoryAndSwapUsage();
long swapUsage = getLongValueFromFile("memory.swap.current");
long memUsage = getLongValueFromFile("memory.current");
newVal = swapUsage + memUsage;
if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
fail("memory.swap.current", oldVal, newVal);
oldVal = metrics.getMemoryAndSwapUsage();
long swapUsage = getLongValueFromFile("memory.swap.current");
long memUsage = getLongValueFromFile("memory.current");
newVal = swapUsage + memUsage;
if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
fail("memory.swap.current", oldVal, newVal);
}
}
oldVal = metrics.getMemorySoftLimit();