Skip to content

Commit

Permalink
kubelet: fix the bug that the number of cpu cannot be obtained normal…
Browse files Browse the repository at this point in the history
…ly under Windows
  • Loading branch information
hwdef committed Mar 12, 2021
1 parent e7d2304 commit ae8c4c2
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions pkg/kubelet/winstats/perfcounter_nodestats.go
Expand Up @@ -26,6 +26,7 @@ import (
"runtime"
"strings"
"sync"
"syscall"
"time"
"unsafe"

Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit ae8c4c2

Please sign in to comment.