From 7ce7be13aefd4e1c10ecbfb7f3be7c15c4220cee Mon Sep 17 00:00:00 2001 From: Muhammad Adeel Date: Thu, 21 Mar 2024 11:26:13 +0100 Subject: [PATCH] Add s390/s390x CPU topology --- info/v1/machine.go | 2 ++ machine/machine.go | 18 -------------- utils/sysfs/fakesysfs/fake.go | 14 +++++++++++ utils/sysfs/sysfs.go | 45 ++++++++++++++++++++++++++++------- utils/sysinfo/sysinfo.go | 28 +++++++++++++++++++++- 5 files changed, 79 insertions(+), 28 deletions(-) diff --git a/info/v1/machine.go b/info/v1/machine.go index cb3bb0e16f7..4fa4b0e554f 100644 --- a/info/v1/machine.go +++ b/info/v1/machine.go @@ -53,6 +53,8 @@ type Core struct { Caches []Cache `json:"caches"` UncoreCaches []Cache `json:"uncore_caches"` SocketID int `json:"socket_id"` + BookID string `json:"book_id,omitempty"` + DrawerID string `json:"drawer_id,omitempty"` } type Cache struct { diff --git a/machine/machine.go b/machine/machine.go index 61b70cb317c..0ba161614f5 100644 --- a/machine/machine.go +++ b/machine/machine.go @@ -21,8 +21,6 @@ import ( "path" "regexp" - // s390/s390x changes - "runtime" "strconv" "strings" @@ -223,10 +221,6 @@ func GetMachineSwapCapacity() (uint64, error) { // GetTopology returns CPU topology reading information from sysfs func GetTopology(sysFs sysfs.SysFs) ([]info.Node, int, error) { - // s390/s390x changes - if isSystemZ() { - return nil, getNumCores(), nil - } return sysinfo.GetNodesInfo(sysFs) } @@ -290,15 +284,3 @@ func isRiscv64() bool { func isMips64() bool { return strings.Contains(machineArch, "mips64") } - -// s390/s390x changes -func getNumCores() int { - maxProcs := runtime.GOMAXPROCS(0) - numCPU := runtime.NumCPU() - - if maxProcs < numCPU { - return maxProcs - } - - return numCPU -} diff --git a/utils/sysfs/fakesysfs/fake.go b/utils/sysfs/fakesysfs/fake.go index c3e5389fd8d..1f004a11139 100644 --- a/utils/sysfs/fakesysfs/fake.go +++ b/utils/sysfs/fakesysfs/fake.go @@ -67,6 +67,12 @@ type FakeSysFs struct { physicalPackageIDs map[string]string physicalPackageIDErr map[string]error + bookIDs map[string]string + bookIDErr map[string]error + + drawerIDs map[string]string + drawerIDErr map[string]error + memTotal string memErr error @@ -98,6 +104,14 @@ func (fs *FakeSysFs) GetCPUPhysicalPackageID(cpuPath string) (string, error) { return fs.physicalPackageIDs[cpuPath], fs.physicalPackageIDErr[cpuPath] } +func (fs *FakeSysFs) GetBookID(coreIDPath string) (string, error) { + return fs.bookIDs[coreIDPath], fs.bookIDErr[coreIDPath] +} + +func (fs *FakeSysFs) GetDrawerID(coreIDPath string) (string, error) { + return fs.drawerIDs[coreIDPath], fs.drawerIDErr[coreIDPath] +} + func (fs *FakeSysFs) GetMemInfo(nodePath string) (string, error) { return fs.memTotal, fs.memErr } diff --git a/utils/sysfs/sysfs.go b/utils/sysfs/sysfs.go index e3466c08e4b..47ce5eb1ab4 100644 --- a/utils/sysfs/sysfs.go +++ b/utils/sysfs/sysfs.go @@ -21,6 +21,7 @@ import ( "path" "path/filepath" "regexp" + "runtime" "strconv" "strings" @@ -50,6 +51,8 @@ const ( coreIDFilePath = "/" + sysFsCPUTopology + "/core_id" packageIDFilePath = "/" + sysFsCPUTopology + "/physical_package_id" + bookIDFilePath = "/" + sysFsCPUTopology + "/book_id" + drawerIDFilePath = "/" + sysFsCPUTopology + "/drawer_id" // memory size calculations @@ -87,6 +90,10 @@ type SysFs interface { GetCoreID(coreIDFilePath string) (string, error) // Get physical package id for specified CPU GetCPUPhysicalPackageID(cpuPath string) (string, error) + // Get book id for specified CPU + GetBookID(cpuPath string) (string, error) + // Get drawer id for specified CPU + GetDrawerID(cpuPath string) (string, error) // Get total memory for specified NUMA node GetMemInfo(nodeDir string) (string, error) // Get hugepages from specified directory @@ -164,6 +171,24 @@ func (fs *realSysFs) GetCPUPhysicalPackageID(cpuPath string) (string, error) { return strings.TrimSpace(string(packageID)), err } +func (fs *realSysFs) GetBookID(cpuPath string) (string, error) { + bookIDFilePath := fmt.Sprintf("%s%s", cpuPath, bookIDFilePath) + bookID, err := os.ReadFile(bookIDFilePath) + if err != nil { + return "", err + } + return strings.TrimSpace(string(bookID)), err +} + +func (fs *realSysFs) GetDrawerID(cpuPath string) (string, error) { + drawerIDFilePath := fmt.Sprintf("%s%s", cpuPath, drawerIDFilePath) + drawerID, err := os.ReadFile(drawerIDFilePath) + if err != nil { + return "", err + } + return strings.TrimSpace(string(drawerID)), err +} + func (fs *realSysFs) GetMemInfo(nodePath string) (string, error) { meminfoPath := fmt.Sprintf("%s/%s", nodePath, meminfoFile) meminfo, err := os.ReadFile(meminfoPath) @@ -365,22 +390,24 @@ func getCPUCount(cache string) (count int, err error) { func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) { cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, cpu, name) - out, err := os.ReadFile(path.Join(cachePath, "/id")) - if err != nil { - return CacheInfo{}, err - } var id int - n, err := fmt.Sscanf(string(out), "%d", &id) - if err != nil || n != 1 { - return CacheInfo{}, err + if runtime.GOARCH != "s390x" { + out, err := os.ReadFile(path.Join(cachePath, "/id")) + if err != nil { + return CacheInfo{}, err + } + n, err := fmt.Sscanf(string(out), "%d", &id) + if err != nil || n != 1 { + return CacheInfo{}, err + } } - out, err = os.ReadFile(path.Join(cachePath, "/size")) + out, err := os.ReadFile(path.Join(cachePath, "/size")) if err != nil { return CacheInfo{}, err } var size uint64 - n, err = fmt.Sscanf(string(out), "%dK", &size) + n, err := fmt.Sscanf(string(out), "%dK", &size) if err != nil || n != 1 { return CacheInfo{}, err } diff --git a/utils/sysinfo/sysinfo.go b/utils/sysinfo/sysinfo.go index 90336179654..4084da1a5b4 100644 --- a/utils/sysinfo/sysinfo.go +++ b/utils/sysinfo/sysinfo.go @@ -18,6 +18,7 @@ import ( "fmt" "os" "regexp" + "runtime" "strconv" "strings" @@ -464,12 +465,35 @@ func getCoresInfo(sysFs sysfs.SysFs, cpuDirs []string) ([]info.Core, error) { return nil, err } + var bookID, drawerID string + // s390/s390x additional cpu topology levels + if runtime.GOARCH == "s390x" { + bookID, err = sysFs.GetBookID(cpuDir) + if os.IsNotExist(err) { + klog.Warningf("Cannot read book id for %s, book_id file does not exist, err: %s", cpuDir, err) + continue + } else if err != nil { + return nil, err + } + drawerID, err = sysFs.GetDrawerID(cpuDir) + if os.IsNotExist(err) { + klog.Warningf("Cannot read drawer id for %s, drawer_id file does not exist, err: %s", cpuDir, err) + continue + } else if err != nil { + return nil, err + } + } + coreIDx := -1 for id, core := range cores { if core.Id == physicalID && core.SocketID == physicalPackageID { - coreIDx = id + // For s390x, we need to check the BookID and DrawerID match as well. + if runtime.GOARCH != "s390x" || (core.BookID == bookID && core.DrawerID == drawerID) { + coreIDx = id + } } } + if coreIDx == -1 { cores = append(cores, info.Core{}) coreIDx = len(cores) - 1 @@ -478,6 +502,8 @@ func getCoresInfo(sysFs sysfs.SysFs, cpuDirs []string) ([]info.Core, error) { desiredCore.Id = physicalID desiredCore.SocketID = physicalPackageID + desiredCore.BookID = bookID + desiredCore.DrawerID = drawerID if len(desiredCore.Threads) == 0 { desiredCore.Threads = []int{cpuID}