mirror of
https://github.com/slackhq/nebula.git
synced 2026-08-16 07:37:02 +02:00
crazy core pinning junk
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
//go:build linux
|
||||
|
||||
package cpupick
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// readTopology probes the NUMA node and physical-core layout of cpus from
|
||||
// sysfs. Anything sysfs won't say degrades toward flatTopology: an unknown
|
||||
// node becomes node 0, an unknown core becomes a core of its own — either
|
||||
// way the corresponding arrange rule becomes a no-op instead of a wrong
|
||||
// answer.
|
||||
func readTopology(cpus []int) topology {
|
||||
return readTopologyFrom("/sys/devices/system/node", "/sys/devices/system/cpu", cpus)
|
||||
}
|
||||
|
||||
func readTopologyFrom(nodeDir, cpuDir string, cpus []int) topology {
|
||||
coreOf, zeroCore := coreGroups(cpuDir, cpus)
|
||||
return topology{
|
||||
nodeOf: numaNodes(nodeDir, cpus),
|
||||
coreOf: coreOf,
|
||||
zeroCore: zeroCore,
|
||||
}
|
||||
}
|
||||
|
||||
// numaNodes maps each cpu to its NUMA node via
|
||||
// /sys/devices/system/node/nodeN/cpulist. CPUs no node claims (or no node
|
||||
// dirs at all: VMs, non-NUMA kernels) land on node 0.
|
||||
func numaNodes(nodeDir string, cpus []int) map[int]int {
|
||||
out := make(map[int]int, len(cpus))
|
||||
for _, c := range cpus {
|
||||
out[c] = 0
|
||||
}
|
||||
entries, err := os.ReadDir(nodeDir)
|
||||
if err != nil {
|
||||
return out
|
||||
}
|
||||
want := make(map[int]bool, len(cpus))
|
||||
for _, c := range cpus {
|
||||
want[c] = true
|
||||
}
|
||||
for _, e := range entries {
|
||||
id, ok := strings.CutPrefix(e.Name(), "node")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
n, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
continue // has_cpu, possible, ... share the prefix
|
||||
}
|
||||
b, err := os.ReadFile(filepath.Join(nodeDir, e.Name(), "cpulist"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
list, err := parseCPUList(strings.TrimSpace(string(b)))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, c := range list {
|
||||
if want[c] {
|
||||
out[c] = n
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// coreGroups maps each cpu to a dense physical-core id derived from its
|
||||
// (physical_package_id, core_id) pair — core_id alone repeats across
|
||||
// sockets. CPUs whose topology files are unreadable get a core of their own.
|
||||
// The second return is the group id of the core CPU 0 lives on, or -1 when
|
||||
// that can't be determined; CPU 0's own files are consulted even when 0 is
|
||||
// not a candidate, so its SMT siblings are recognized under cpusets that
|
||||
// exclude CPU 0 itself.
|
||||
func coreGroups(cpuDir string, cpus []int) (map[int]int, int) {
|
||||
type pkgCore struct{ pkg, core int }
|
||||
pairOf := func(cpu int) (pkgCore, bool) {
|
||||
topoDir := filepath.Join(cpuDir, fmt.Sprintf("cpu%d", cpu), "topology")
|
||||
pkg, err1 := readIntFile(filepath.Join(topoDir, "physical_package_id"))
|
||||
core, err2 := readIntFile(filepath.Join(topoDir, "core_id"))
|
||||
if err1 != nil || err2 != nil {
|
||||
return pkgCore{}, false
|
||||
}
|
||||
return pkgCore{pkg, core}, true
|
||||
}
|
||||
|
||||
ids := map[pkgCore]int{}
|
||||
out := make(map[int]int, len(cpus))
|
||||
next := 0
|
||||
for _, cpu := range cpus {
|
||||
k, ok := pairOf(cpu)
|
||||
if !ok {
|
||||
out[cpu] = next
|
||||
next++
|
||||
continue
|
||||
}
|
||||
id, ok := ids[k]
|
||||
if !ok {
|
||||
id = next
|
||||
next++
|
||||
ids[k] = id
|
||||
}
|
||||
out[cpu] = id
|
||||
}
|
||||
|
||||
zeroCore := -1
|
||||
if k, ok := pairOf(0); ok {
|
||||
if id, ok := ids[k]; ok {
|
||||
zeroCore = id
|
||||
}
|
||||
}
|
||||
return out, zeroCore
|
||||
}
|
||||
Reference in New Issue
Block a user