mirror of
https://github.com/kemko/nomad.git
synced 2026-01-05 18:05:42 +03:00
The NUMA topology struct field `NodeIDs` is a `idset.Set`, which has no public members. As a result, this field is never serialized via msgpack and persisted in state. When `numa.affinity = "prefer"`, the scheduler dereferences this nil field and panics the scheduler worker. Ideally we would fix this by adding a msgpack serialization extension, but because the field already exists and is just always empty, this breaks RPC wire compatibility across upgrades. Instead, create a new field that's populated at the same time we populate the more useful `idset.Set`, and repopulate the set on demand. Fixes: https://hashicorp.atlassian.net/browse/NET-9924
77 lines
1.7 KiB
Go
77 lines
1.7 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
//go:build darwin
|
|
|
|
package numalib
|
|
|
|
import (
|
|
"github.com/hashicorp/nomad/client/lib/idset"
|
|
"github.com/hashicorp/nomad/client/lib/numalib/hw"
|
|
"github.com/shoenig/go-m1cpu"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// PlatformScanners returns the set of SystemScanner for macOS.
|
|
func PlatformScanners() []SystemScanner {
|
|
return []SystemScanner{
|
|
new(MacOS),
|
|
}
|
|
}
|
|
|
|
const (
|
|
nodeID = hw.NodeID(0)
|
|
socketID = hw.SocketID(0)
|
|
maxSpeed = hw.KHz(0)
|
|
)
|
|
|
|
// MacOS implements SystemScanner for macOS systems (both arm64 and x86).
|
|
type MacOS struct{}
|
|
|
|
func (m *MacOS) ScanSystem(top *Topology) {
|
|
// all apple hardware is non-numa; just assume as much
|
|
top.nodeIDs = idset.Empty[hw.NodeID]()
|
|
top.nodeIDs.Insert(nodeID)
|
|
|
|
// arch specific detection
|
|
switch m1cpu.IsAppleSilicon() {
|
|
case true:
|
|
m.scanAppleSilicon(top)
|
|
case false:
|
|
m.scanLegacyX86(top)
|
|
}
|
|
}
|
|
|
|
func (m *MacOS) scanAppleSilicon(top *Topology) {
|
|
pCoreCount := m1cpu.PCoreCount()
|
|
pCoreSpeed := hw.KHz(m1cpu.PCoreHz() / 1000)
|
|
|
|
eCoreCount := m1cpu.ECoreCount()
|
|
eCoreSpeed := hw.KHz(m1cpu.ECoreHz() / 1000)
|
|
|
|
top.Cores = make([]Core, pCoreCount+eCoreCount)
|
|
nthCore := hw.CoreID(0)
|
|
|
|
for i := 0; i < pCoreCount; i++ {
|
|
top.insert(nodeID, socketID, nthCore, Performance, maxSpeed, pCoreSpeed)
|
|
nthCore++
|
|
}
|
|
|
|
for i := 0; i < eCoreCount; i++ {
|
|
top.insert(nodeID, socketID, nthCore, Efficiency, maxSpeed, eCoreSpeed)
|
|
nthCore++
|
|
}
|
|
}
|
|
|
|
func (m *MacOS) scanLegacyX86(top *Topology) {
|
|
coreCount, _ := unix.SysctlUint32("hw.ncpu")
|
|
hz, _ := unix.SysctlUint64("hw.cpufrequency")
|
|
|
|
coreSpeed := hw.KHz(hz / 1_000)
|
|
|
|
top.Cores = make([]Core, coreCount)
|
|
for i := 0; i < int(coreCount); i++ {
|
|
top.insert(nodeID, socketID, hw.CoreID(i), Performance, maxSpeed, coreSpeed)
|
|
}
|
|
}
|