8282684: Obsolete UseContainerCpuShares and PreferContainerQuotaForCPUCount flags

Reviewed-by: dholmes, iklam, sgehwolf
This commit is contained in:
Harold Seigel 2022-08-22 14:35:44 +00:00
parent 256b52387b
commit db77227684
4 changed files with 12 additions and 117 deletions

View File

@ -463,28 +463,19 @@ void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) {
* If user specified a quota (quota != -1), calculate the number of
* required CPUs by dividing quota by period.
*
* If shares are in effect (shares != -1), calculate the number
* of CPUs required for the shares by dividing the share value
* by PER_CPU_SHARES.
*
* All results of division are rounded up to the next whole number.
*
* If neither shares or quotas have been specified, return the
* If quotas have not been specified, return the
* number of active processors in the system.
*
* If both shares and quotas have been specified, the results are
* based on the flag PreferContainerQuotaForCPUCount. If true,
* return the quota value. If false return the smallest value
* between shares or quotas.
*
* If shares and/or quotas have been specified, the resulting number
* If quotas have been specified, the resulting number
* returned will never exceed the number of active processors.
*
* return:
* number of CPUs
*/
int CgroupSubsystem::active_processor_count() {
int quota_count = 0, share_count = 0;
int quota_count = 0;
int cpu_count, limit_count;
int result;
@ -503,35 +494,14 @@ int CgroupSubsystem::active_processor_count() {
int quota = cpu_quota();
int period = cpu_period();
// It's not a good idea to use cpu_shares() to limit the number
// of CPUs used by the JVM. See JDK-8281181.
// UseContainerCpuShares and PreferContainerQuotaForCPUCount are
// deprecated and will be removed in the next JDK release.
int share = UseContainerCpuShares ? cpu_shares() : -1;
if (quota > -1 && period > 0) {
quota_count = ceilf((float)quota / (float)period);
log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
}
if (share > -1) {
share_count = ceilf((float)share / (float)PER_CPU_SHARES);
log_trace(os, container)("CPU Share count based on shares: %d", share_count);
}
// If both shares and quotas are setup results depend
// on flag PreferContainerQuotaForCPUCount.
// If true, limit CPU count to quota
// If false, use minimum of shares and quotas
if (quota_count !=0 && share_count != 0) {
if (PreferContainerQuotaForCPUCount) {
limit_count = quota_count;
} else {
limit_count = MIN2(quota_count, share_count);
}
} else if (quota_count != 0) {
// Use quotas
if (quota_count != 0) {
limit_count = quota_count;
} else if (share_count != 0) {
limit_count = share_count;
}
result = MIN2(cpu_count, limit_count);

View File

@ -59,15 +59,6 @@
product(bool, UseContainerSupport, true, \
"Enable detection and runtime container configuration support") \
\
product(bool, UseContainerCpuShares, false, \
"(Deprecated) Include CPU shares in the CPU availability" \
" calculation.") \
\
product(bool, PreferContainerQuotaForCPUCount, true, \
"(Deprecated) Calculate the container CPU availability based" \
" on the value of quotas (if set), when true. Otherwise, use" \
" the CPU shares value, provided it is less than quota.") \
\
product(bool, AdjustStackSizeForTLS, false, \
"Increase the thread stack size to include space for glibc " \
"static thread-local storage (TLS) if true") \

View File

@ -88,16 +88,8 @@ class OperatingSystemImpl extends BaseOperatingSystemImpl
long numPeriods = containerMetrics.getCpuNumPeriods();
long quotaNanos = TimeUnit.MICROSECONDS.toNanos(quota * numPeriods);
return getUsageDividesTotal(cpuUsageSupplier().getAsLong(), quotaNanos);
} else if (share > 0) {
long hostTicks = getHostTotalCpuTicks0();
int totalCPUs = getHostOnlineCpuCount0();
int containerCPUs = getAvailableProcessors();
// scale the total host load to the actual container cpus
double scaleFactor = ((double) containerCPUs) / totalCPUs;
hostTicks = (long) (hostTicks * scaleFactor);
return getUsageDividesTotal(cpuUsageSupplier().getAsLong(), hostTicks);
} else {
// If CPU quotas and shares are not active then find the average load for
// If CPU quotas are not active then find the average load for
// all online CPUs that are allowed to run this container.
// If the cpuset is the same as the host's one there is no need to iterate over each CPU

View File

@ -58,11 +58,6 @@ public class TestCPUAwareness {
// cpuset, period, shares, expected Active Processor Count
testComboWithCpuSets();
// cpu shares - it should be safe to use CPU shares exceeding available CPUs
testCpuShares(256, 1);
testCpuShares(2048, 2);
testCpuShares(4096, 4);
// leave one CPU for system and tools, otherwise this test may be unstable
int maxNrOfAvailableCpus = availableCPUs - 1;
for (int i=1; i < maxNrOfAvailableCpus; i = i * 2) {
@ -100,11 +95,6 @@ public class TestCPUAwareness {
String cpuSetStr = CPUSetsReader.readFromProcStatus("Cpus_allowed_list");
System.out.println("cpuSetStr = " + cpuSetStr);
// OLD = use the deprecated -XX:+UseContainerCpuShares flag, which
// will be removed in the next JDK release. See JDK-8281181.
boolean OLD = true;
boolean NEW = false;
if (cpuSetStr == null) {
System.out.printf("The cpuset test cases are skipped");
} else {
@ -113,32 +103,21 @@ public class TestCPUAwareness {
// Test subset of cpuset with one element
if (cpuSet.size() >= 1) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
testAPCCombo(OLD, testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);
testAPCCombo(NEW, testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 1);
}
// Test subset of cpuset with two elements
if (cpuSet.size() >= 2) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
testAPCCombo(OLD, testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
testAPCCombo(OLD, testCpuSet, 200*1000, 100*1000, 1023, true, 2);
testAPCCombo(OLD, testCpuSet, 200*1000, 100*1000, 1023, false,1);
testAPCCombo(NEW, testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
testAPCCombo(NEW, testCpuSet, 200*1000, 100*1000, 1023, true, 2);
testAPCCombo(NEW, testCpuSet, 200*1000, 100*1000, 1023, false,2);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 2);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, 2);
}
// Test subset of cpuset with three elements
if (cpuSet.size() >= 3) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);
testAPCCombo(OLD, testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
testAPCCombo(OLD, testCpuSet, 200*1000, 100*1000, 1023, true, 2);
testAPCCombo(OLD, testCpuSet, 200*1000, 100*1000, 1023, false,1);
testAPCCombo(NEW, testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
testAPCCombo(NEW, testCpuSet, 200*1000, 100*1000, 1023, true, 2);
testAPCCombo(NEW, testCpuSet, 200*1000, 100*1000, 1023, false,2);
testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, 1);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, 2);
}
}
}
@ -195,20 +174,13 @@ public class TestCPUAwareness {
}
// Test correctess of automatically selected active processor count
// Note: when -XX:+UseContainerCpuShares is removed,
// useContainerCpuShares, shares, and usePreferContainerQuotaForCPUCount
// should also be removed.
private static void testAPCCombo(boolean useContainerCpuShares, String cpuset, int quota, int period, int shares,
boolean usePreferContainerQuotaForCPUCount,
private static void testAPCCombo(String cpuset, int quota, int period, int shares,
int expectedAPC) throws Exception {
Common.logNewTestCase("test APC Combo");
System.out.println("cpuset = " + cpuset);
System.out.println("quota = " + quota);
System.out.println("period = " + period);
System.out.println("shares = " + shares);
System.out.println("useContainerCpuShares = " + useContainerCpuShares);
System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);
System.out.println("expectedAPC = " + expectedAPC);
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
@ -219,41 +191,11 @@ public class TestCPUAwareness {
.addDockerOpts("--cpu-quota=" + quota)
.addDockerOpts("--cpu-shares=" + shares);
if (useContainerCpuShares) opts.addJavaOpts("-XX:+UseContainerCpuShares"); // deprecated
if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount"); // deprecated
Common.run(opts)
.shouldMatch("active_processor_count.*" + expectedAPC);
}
// Note: when -XX:+UseContainerCpuShares is removed, this test should also be removed.
private static void testCpuShares(int shares, int expectedAPC) throws Exception {
Common.logNewTestCase("test cpu shares, shares = " + shares);
System.out.println("expectedAPC = " + expectedAPC);
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
DockerRunOptions opts = Common.newOpts(imageName)
.addDockerOpts("--cpu-shares=" + shares);
opts.addJavaOpts("-XX:+UseContainerCpuShares"); // deprecated
OutputAnalyzer out = Common.run(opts);
// Cgroups v2 needs to do some scaling of raw shares values. Hence,
// 256 CPU shares come back as 264. Raw value written to cpu.weight
// is 10. The reason this works for >= 1024 shares value is because
// post-scaling the closest multiple of 1024 is found and returned.
//
// For values < 1024, this doesn't happen so loosen the match to a
// 3-digit number and ensure the active_processor_count is as
// expected.
if (shares < 1024) {
out.shouldMatch("CPU Shares is.*\\d{3}");
} else {
out.shouldMatch("CPU Shares is.*" + shares);
}
out.shouldMatch("active_processor_count.*" + expectedAPC);
}
private static void testOperatingSystemMXBeanAwareness(String cpuAllocation, String expectedCpus) throws Exception {
Common.logNewTestCase("Check OperatingSystemMXBean");