From ae8c4c265600e20d2e95b024bf7a30896152d4fa Mon Sep 17 00:00:00 2001 From: hwdef Date: Fri, 18 Dec 2020 11:50:40 +0800 Subject: [PATCH] kubelet: fix the bug that the number of cpu cannot be obtained normally under Windows --- pkg/kubelet/winstats/perfcounter_nodestats.go | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/pkg/kubelet/winstats/perfcounter_nodestats.go b/pkg/kubelet/winstats/perfcounter_nodestats.go index 265debf096c..ced182551cf 100644 --- a/pkg/kubelet/winstats/perfcounter_nodestats.go +++ b/pkg/kubelet/winstats/perfcounter_nodestats.go @@ -26,6 +26,7 @@ import ( "runtime" "strings" "sync" + "syscall" "time" "unsafe" @@ -50,10 +51,13 @@ type MemoryStatusEx struct { } var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") + modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") + procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount") ) +const allProcessorGroups = 0xFFFF + // NewPerfCounterClient creates a client using perf counters func NewPerfCounterClient() (Client, error) { // Initialize the cache @@ -140,13 +144,33 @@ func (p *perfCounterNodeStatsClient) getMachineInfo() (*cadvisorapi.MachineInfo, } return &cadvisorapi.MachineInfo{ - NumCores: runtime.NumCPU(), + NumCores: processorCount(), MemoryCapacity: p.nodeInfo.memoryPhysicalCapacityBytes, MachineID: hostname, SystemUUID: systemUUID, }, nil } +// runtime.NumCPU() will only return the information for a single Processor Group. +// Since a single group can only hold 64 logical processors, this +// means when there are more they will be divided into multiple groups. +// For the above reason, procGetActiveProcessorCount is used to get the +// cpu count for all processor groups of the windows node. +// more notes for this issue: +// same issue in moby: https://github.com/moby/moby/issues/38935#issuecomment-744638345 +// solution in hcsshim: https://github.com/microsoft/hcsshim/blob/master/internal/processorinfo/processor_count.go +func processorCount() int { + if amount := getActiveProcessorCount(allProcessorGroups); amount != 0 { + return int(amount) + } + return runtime.NumCPU() +} + +func getActiveProcessorCount(groupNumber uint16) int { + r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) + return int(r0) +} + func (p *perfCounterNodeStatsClient) getVersionInfo() (*cadvisorapi.VersionInfo, error) { return &cadvisorapi.VersionInfo{ KernelVersion: p.nodeInfo.kernelVersion,