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 <[email protected]>
Sent: Freitag, 12. Juni 2020 15:02
To: Baesken, Matthias <[email protected]>
Cc: [email protected]
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 <[email protected]>
> 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