RFR: 8247469: getSystemCpuLoad() returns -1 on linux when some offline cpus are present and cpusets.effective_cpus is not available
Bob Vandette
bob.vandette at oracle.com
Fri Jun 12 18:49:00 UTC 2020
Look good to me.
Bob.
> On Jun 12, 2020, at 11:01 AM, Baesken, Matthias <matthias.baesken at sap.com> wrote:
>
> Hello, please review the following change .
> We have a Linux machine where
> OperatingSystemMXBean mbean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
> double load = mbean.getSystemCpuLoad();
> returns -1 ;
>
> Reason is that there are offline CPUs (48 configured , 32 online ). Additionally cpusets.effective_cpus is not available on that Linux system .
>
>
> Bug/webrev :
>
> https://bugs.openjdk.java.net/browse/JDK-8247466
>
> http://cr.openjdk.java.net/~mbaesken/webrevs/8247469.0/
>
>
> Thanks,
> Matthias
>
>
> -----Original Message-----
> From: Bob Vandette <bob.vandette at oracle.com>
> Sent: Freitag, 12. Juni 2020 15:02
> To: Baesken, Matthias <matthias.baesken at sap.com>
> Cc: daniil.x.titov at oracle.com
> Subject: Re: getCpuLoad() / getSystemCpuLoad() returns -1 on linux when some offline cpus are present and cpusets.effective_cpus is not available
>
> I looks like there are two problems here:
>
> 1. containerMetrics.getCpuSetCpus().length returns the online CPUs but getHostConfiguredCpuCount0() returns the total number of CPUs including offline ones.
>
> One solution might be to add a getHostOnlineCpuCount0() function.
>
> 2. If getEffectiveCpuSetCpus is not available then we should use getCpuSetCpus.
>
> Bob.
>
>
>> On Jun 12, 2020, at 6:43 AM, Baesken, Matthias <matthias.baesken at sap.com> wrote:
>>
>> Hello, I noticed the following on one of our Linux machines :
>>
>> OperatingSystemMXBean mbean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
>> double load = mbean.getSystemCpuLoad();
>>
>> returns -1 ; this seems to be related to “8226575: OperatingSystemMXBean should be made container aware” .
>>
>> This machine has the following “special features”
>>
>> - a few CPUs are offline (means the configured cpus are 48 but the online cpus are 32) so
>>
>>
>> private boolean isCpuSetSameAsHostCpuSet() {
>> if (containerMetrics != null && containerMetrics.getCpuSetCpus() != null) {
>> return containerMetrics.getCpuSetCpus().length == getHostConfiguredCpuCount0();
>> }
>> return false;
>> }
>>
>> Returns false
>>
>> - the machine does not have cpusets.effective_cpus (not all Linux machines have it )
>>
>> In this case getSystemCpuLoad() / getCpuLoad() returns -1 (because it checks that 48 != 32, and next it checks for cpusets.effective_cpus which is not present ).
>>
>> See the coding at :
>> https://hg.openjdk.java.net/jdk/jdk/file/bdc14b8d31ff/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java#l136
>>
>> // If the cpuset is the same as the host's one there is no need to iterate over each CPU
>> if (isCpuSetSameAsHostCpuSet()) {
>> return getCpuLoad0();
>> } else {
>> int[] cpuSet = containerMetrics.getEffectiveCpuSetCpus();
>> if (cpuSet != null && cpuSet.length > 0) {
>> double systemLoad = 0.0;
>> for (int cpu : cpuSet) {
>> double cpuLoad = getSingleCpuLoad0(cpu);
>> if (cpuLoad < 0) {
>> return -1;
>> }
>> systemLoad += cpuLoad;
>> }
>> return systemLoad / cpuSet.length;
>> }
>> return -1;
>> }
>>
>>
>> Could we better a) return the native getCpuLoad0(); in this case or b) use the available containerMetrics.getCpuSetCpus(); when getEffectiveCpuSetCpus();
>> Gives an empty array (btw. getCpuSetCpus() returns on this machine the online cpus = 0,31 = 32 ) ?
>>
>> I opened
>>
>> https://bugs.openjdk.java.net/browse/JDK-8247469
>>
>> to track this (I see the issue in jdk/jdk but it seems it came also to oracle jdk8u261, which the July update ).
>>
>> Best regards, Matthias
>
More information about the core-libs-dev
mailing list