Hi Matthias, The change looks good to me. Probably it also makes sense to remove method getHostConfiguredCpuCount0() since it is no longer used.
Thanks, Daniil On 6/12/20, 8:25 AM, "Baesken, Matthias" <matthias.baes...@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.vande...@oracle.com> Sent: Freitag, 12. Juni 2020 15:02 To: Baesken, Matthias <matthias.baes...@sap.com> Cc: daniil.x.ti...@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.baes...@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