mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Correct CPU usage calculation in presence of offline CPUs and newer Linux
In https://github.com/torvalds/linux/commit/5ca3726 (released in v4.7-rc1) the content of the `cpuacct.usage_percpu` file in sysfs was changed to include both online and offline cpus. This broke the arithmetic in the stats helpers used by `docker stats`, since it was using the length of the PerCPUUsage array as a proxy for the number of online CPUs. Add current number of online CPUs to types.StatsJSON and use it in the calculation. Keep a fallback to `len(v.CPUStats.CPUUsage.PercpuUsage)` so this code continues to work when talking to an older daemon. An old client talking to a new daemon will ignore the new field and behave as before. Fixes #28941. Signed-off-by: Ian Campbell <ian.campbell@docker.com>
This commit is contained in:
@@ -80,6 +80,12 @@ func (s *Collector) Run() {
|
||||
continue
|
||||
}
|
||||
|
||||
onlineCPUs, err := s.getNumberOnlineCPUs()
|
||||
if err != nil {
|
||||
logrus.Errorf("collecting system online cpu count: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, pair := range pairs {
|
||||
stats, err := s.supervisor.GetContainerStats(pair.container)
|
||||
if err != nil {
|
||||
@@ -97,6 +103,7 @@ func (s *Collector) Run() {
|
||||
}
|
||||
// FIXME: move to containerd on Linux (not Windows)
|
||||
stats.CPUStats.SystemUsage = systemUsage
|
||||
stats.CPUStats.OnlineCPUs = onlineCPUs
|
||||
|
||||
pair.publisher.Publish(*stats)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
)
|
||||
|
||||
/*
|
||||
#include <unistd.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// platformNewStatsCollector performs platform specific initialisation of the
|
||||
// Collector structure.
|
||||
func platformNewStatsCollector(s *Collector) {
|
||||
@@ -64,3 +69,11 @@ func (s *Collector) getSystemCPUUsage() (uint64, error) {
|
||||
}
|
||||
return 0, fmt.Errorf("invalid stat format. Error trying to parse the '/proc/stat' file")
|
||||
}
|
||||
|
||||
func (s *Collector) getNumberOnlineCPUs() (uint32, error) {
|
||||
i, err := C.sysconf(C._SC_NPROCESSORS_ONLN)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(i), nil
|
||||
}
|
||||
|
||||
@@ -13,3 +13,7 @@ func platformNewStatsCollector(s *Collector) {
|
||||
func (s *Collector) getSystemCPUUsage() (uint64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (s *Collector) getNumberOnlineCPUs() (uint32, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user