mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8197589: Update CPU count algorithm when both cpu shares and quotas are used
Reviewed-by: dholmes, mseledtsov
This commit is contained in:
parent
809315bdd1
commit
c1359ec107
3 changed files with 69 additions and 31 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -62,6 +62,11 @@
|
||||||
product(bool, UseContainerSupport, true, \
|
product(bool, UseContainerSupport, true, \
|
||||||
"Enable detection and runtime container configuration support") \
|
"Enable detection and runtime container configuration support") \
|
||||||
\
|
\
|
||||||
|
product(bool, PreferContainerQuotaForCPUCount, true, \
|
||||||
|
"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.") \
|
||||||
|
\
|
||||||
diagnostic(bool, UseCpuAllocPath, false, \
|
diagnostic(bool, UseCpuAllocPath, false, \
|
||||||
"Use CPU_ALLOC code path in os::active_processor_count ")
|
"Use CPU_ALLOC code path in os::active_processor_count ")
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -499,11 +499,11 @@ jlong OSContainer::memory_max_usage_in_bytes() {
|
||||||
/* active_processor_count
|
/* active_processor_count
|
||||||
*
|
*
|
||||||
* Calculate an appropriate number of active processors for the
|
* Calculate an appropriate number of active processors for the
|
||||||
* VM to use based on these three cgroup options.
|
* VM to use based on these three inputs.
|
||||||
*
|
*
|
||||||
* cpu affinity
|
* cpu affinity
|
||||||
* cpu quota & cpu period
|
* cgroup cpu quota & cpu period
|
||||||
* cpu shares
|
* cgroup cpu shares
|
||||||
*
|
*
|
||||||
* Algorithm:
|
* Algorithm:
|
||||||
*
|
*
|
||||||
|
@ -513,42 +513,61 @@ jlong OSContainer::memory_max_usage_in_bytes() {
|
||||||
* required CPUs by dividing quota by period.
|
* required CPUs by dividing quota by period.
|
||||||
*
|
*
|
||||||
* If shares are in effect (shares != -1), calculate the number
|
* If shares are in effect (shares != -1), calculate the number
|
||||||
* of cpus required for the shares by dividing the share value
|
* of CPUs required for the shares by dividing the share value
|
||||||
* by PER_CPU_SHARES.
|
* by PER_CPU_SHARES.
|
||||||
*
|
*
|
||||||
* All results of division are rounded up to the next whole number.
|
* All results of division are rounded up to the next whole number.
|
||||||
*
|
*
|
||||||
* Return the smaller number from the three different settings.
|
* If neither shares or quotas have 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
|
||||||
|
* returned will never exceed the number of active processors.
|
||||||
*
|
*
|
||||||
* return:
|
* return:
|
||||||
* number of cpus
|
* number of CPUs
|
||||||
* OSCONTAINER_ERROR if failure occured during extract of cpuset info
|
|
||||||
*/
|
*/
|
||||||
int OSContainer::active_processor_count() {
|
int OSContainer::active_processor_count() {
|
||||||
int cpu_count, share_count, quota_count;
|
int quota_count = 0, share_count = 0;
|
||||||
int share, quota, period;
|
int cpu_count, limit_count;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
cpu_count = os::Linux::active_processor_count();
|
cpu_count = limit_count = os::Linux::active_processor_count();
|
||||||
|
int quota = cpu_quota();
|
||||||
|
int period = cpu_period();
|
||||||
|
int share = cpu_shares();
|
||||||
|
|
||||||
share = cpu_shares();
|
|
||||||
if (share > -1) {
|
|
||||||
share_count = ceilf((float)share / (float)PER_CPU_SHARES);
|
|
||||||
log_trace(os, container)("cpu_share count: %d", share_count);
|
|
||||||
} else {
|
|
||||||
share_count = cpu_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
quota = cpu_quota();
|
|
||||||
period = cpu_period();
|
|
||||||
if (quota > -1 && period > 0) {
|
if (quota > -1 && period > 0) {
|
||||||
quota_count = ceilf((float)quota / (float)period);
|
quota_count = ceilf((float)quota / (float)period);
|
||||||
log_trace(os, container)("quota_count: %d", quota_count);
|
log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
|
||||||
} else {
|
}
|
||||||
quota_count = cpu_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = MIN2(cpu_count, MIN2(share_count, quota_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) {
|
||||||
|
limit_count = quota_count;
|
||||||
|
} else if (share_count != 0) {
|
||||||
|
limit_count = share_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = MIN2(cpu_count, limit_count);
|
||||||
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
|
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -94,14 +94,23 @@ public class TestCPUAwareness {
|
||||||
// Test subset of cpuset with one element
|
// Test subset of cpuset with one element
|
||||||
if (cpuSet.size() >= 1) {
|
if (cpuSet.size() >= 1) {
|
||||||
String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
|
String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
|
||||||
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 1);
|
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test subset of cpuset with two elements
|
// Test subset of cpuset with two elements
|
||||||
if (cpuSet.size() >= 2) {
|
if (cpuSet.size() >= 2) {
|
||||||
String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
|
String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
|
||||||
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 2);
|
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
|
||||||
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1*1024, 2);
|
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
|
||||||
|
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test subset of cpuset with three elements
|
||||||
|
if (cpuSet.size() >= 3) {
|
||||||
|
String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);
|
||||||
|
testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
|
||||||
|
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
|
||||||
|
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,12 +168,14 @@ public class TestCPUAwareness {
|
||||||
|
|
||||||
// Test correctess of automatically selected active processor cound
|
// Test correctess of automatically selected active processor cound
|
||||||
private static void testAPCCombo(String cpuset, int quota, int period, int shares,
|
private static void testAPCCombo(String cpuset, int quota, int period, int shares,
|
||||||
int expectedAPC) throws Exception {
|
boolean usePreferContainerQuotaForCPUCount,
|
||||||
|
int expectedAPC) throws Exception {
|
||||||
Common.logNewTestCase("test APC Combo");
|
Common.logNewTestCase("test APC Combo");
|
||||||
System.out.println("cpuset = " + cpuset);
|
System.out.println("cpuset = " + cpuset);
|
||||||
System.out.println("quota = " + quota);
|
System.out.println("quota = " + quota);
|
||||||
System.out.println("period = " + period);
|
System.out.println("period = " + period);
|
||||||
System.out.println("shares = " + period);
|
System.out.println("shares = " + period);
|
||||||
|
System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);
|
||||||
System.out.println("expectedAPC = " + expectedAPC);
|
System.out.println("expectedAPC = " + expectedAPC);
|
||||||
|
|
||||||
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
|
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
|
||||||
|
@ -174,6 +185,9 @@ public class TestCPUAwareness {
|
||||||
.addDockerOpts("--cpu-period=" + period)
|
.addDockerOpts("--cpu-period=" + period)
|
||||||
.addDockerOpts("--cpu-quota=" + quota)
|
.addDockerOpts("--cpu-quota=" + quota)
|
||||||
.addDockerOpts("--cpu-shares=" + shares);
|
.addDockerOpts("--cpu-shares=" + shares);
|
||||||
|
|
||||||
|
if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount");
|
||||||
|
|
||||||
Common.run(opts)
|
Common.run(opts)
|
||||||
.shouldMatch("active_processor_count.*" + expectedAPC);
|
.shouldMatch("active_processor_count.*" + expectedAPC);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue