fix(host): aarch64 cpu info (#14581)

This commit is contained in:
Zexi Li
2022-07-05 16:33:00 +08:00
committed by GitHub
parent c7e22c7b8a
commit 6a590f123e
8 changed files with 114 additions and 81 deletions
+2 -1
View File
@@ -42,7 +42,7 @@ require (
github.com/gosuri/uitable v0.0.0-20160404203958-36ee7e946282
github.com/hako/durafmt v0.0.0-20180520121703-7b7ae1e72ead
github.com/huaweicloud/huaweicloud-sdk-go v1.0.26
github.com/jaypipes/ghw v0.9.0
github.com/jaypipes/ghw v0.9.1
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/lestrrat-go/jwx v1.0.2
@@ -261,5 +261,6 @@ require (
replace (
github.com/go-logr/logr => github.com/go-logr/logr v0.4.0
github.com/jaypipes/ghw => github.com/zexi/ghw v0.9.1
google.golang.org/grpc => google.golang.org/grpc v1.29.0
)
+2 -2
View File
@@ -415,8 +415,6 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jaypipes/ghw v0.9.0 h1:TWF4wNIGtZcgDJaiNcFgby5BR8s2ixcUe0ydxNO2McY=
github.com/jaypipes/ghw v0.9.0/go.mod h1:dXMo19735vXOjpIBDyDYSp31sB2u4hrtRCMxInqQ64k=
github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk=
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0 h1:mzVj8r6fluEwjn8ogqtGfYW2qSIVUaEq0JAsvjCav3A=
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0/go.mod h1:UrKjuULIWLjHFlG6aSPunArE5QX57LftMmStAZJBEX8=
@@ -711,6 +709,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zexi/ghw v0.9.1 h1:3PaJ22kRnqTsTJWpNLminGQcYrIT3FA4nz6h1R4E2mg=
github.com/zexi/ghw v0.9.1/go.mod h1:dXMo19735vXOjpIBDyDYSp31sB2u4hrtRCMxInqQ64k=
go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU=
+28 -9
View File
@@ -4066,21 +4066,40 @@ func (self *SHost) PerformPing(ctx context.Context, userCred mcclient.TokenCrede
}
func (host *SHost) getHostLogicalCores() ([]int, error) {
topoObj, err := host.SysInfo.Get("topology")
cpuObj, err := host.SysInfo.Get("cpu_info")
if err != nil {
return nil, errors.Wrap(err, "get topology from host sys_info")
return nil, errors.Wrap(err, "get cpu info from host sys_info")
}
hostTopo := new(hostapi.HostTopology)
if err := topoObj.Unmarshal(hostTopo); err != nil {
return nil, errors.Wrap(err, "Unmarshal host topology struct")
cpuInfo := new(hostapi.HostCPUInfo)
if err := cpuObj.Unmarshal(cpuInfo); err != nil {
return nil, errors.Wrap(err, "Unmarshal host cpu info struct")
}
// get host logical cores
allCores := []int{}
for _, node := range hostTopo.Nodes {
for _, cores := range node.Cores {
allCores = append(allCores, cores.LogicalProcessors...)
if len(cpuInfo.Processors) != 0 {
for _, p := range cpuInfo.Processors {
for _, core := range p.Cores {
allCores = append(allCores, core.LogicalProcessors...)
}
}
sort.Ints(allCores)
} else {
topoObj, err := host.SysInfo.Get("topology")
if err != nil {
return nil, errors.Wrap(err, "get topology from host sys_info")
}
hostTopo := new(hostapi.HostTopology)
if err := topoObj.Unmarshal(hostTopo); err != nil {
return nil, errors.Wrap(err, "Unmarshal host topology struct")
}
for _, node := range hostTopo.Nodes {
for _, cores := range node.Cores {
allCores = append(allCores, cores.LogicalProcessors...)
}
}
}
return allCores, nil
+5
View File
@@ -482,7 +482,12 @@ func (h *SHostInfo) detectHostInfo() error {
if err != nil {
return errors.Wrap(err, "Get hardware topology")
}
cpuInfo, err := hardware.GetCPU()
if err != nil {
return errors.Wrap(err, "Get CPU info")
}
h.sysinfo.Topology = topoInfo
h.sysinfo.CPUInfo = cpuInfo
system_service.Init()
if options.HostOptions.CheckSystemServices {
+1
View File
@@ -327,6 +327,7 @@ type SSysInfo struct {
HugepageSizeKb int `json:"hugepage_size_kb"`
Topology *hostapi.HostTopology `json:"topology"`
CPUInfo *hostapi.HostCPUInfo `json:"cpu_info"`
}
func StartDetachStorages(hs []jsonutils.JSONObject) {
+72 -68
View File
@@ -11,6 +11,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
@@ -32,6 +33,24 @@ func (i *Info) load() error {
return nil
}
func ProcByID(procs []*Processor, id int) *Processor {
for pid := range procs {
if procs[pid].ID == id {
return procs[pid]
}
}
return nil
}
func CoreByID(cores []*ProcessorCore, id int) *ProcessorCore {
for cid := range cores {
if cores[cid].Index == id {
return cores[cid]
}
}
return nil
}
func processorsGet(ctx *context.Context) []*Processor {
procs := make([]*Processor, 0)
paths := linuxpath.New(ctx)
@@ -46,6 +65,7 @@ func processorsGet(ctx *context.Context) []*Processor {
procAttrs := make([]map[string]string, 0)
curProcAttrs := make(map[string]string)
// Parse /proc/cpuinfo
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
@@ -64,85 +84,69 @@ func processorsGet(ctx *context.Context) []*Processor {
curProcAttrs[key] = value
}
// Build a set of physical processor IDs which represent the physical
// package of the CPU
setPhysicalIDs := make(map[int]bool)
for _, attrs := range procAttrs {
pid, err := strconv.Atoi(attrs["physical id"])
if err != nil {
// Iterate on /sys/devices/system/cpu/cpuN, not on /proc/cpuinfo
Entries, _ := ioutil.ReadDir(paths.SysDevicesSystemCPU)
for _, lcore := range Entries {
reg := regexp.MustCompile("^cpu([0-9]+)$")
if !reg.MatchString(lcore.Name()) {
continue
}
setPhysicalIDs[pid] = true
}
for pid := range setPhysicalIDs {
p := &Processor{
ID: pid,
}
// The indexes into the array of attribute maps for each logical
// processor within the physical processor
lps := make([]int, 0)
for x := range procAttrs {
lppid, err := strconv.Atoi(procAttrs[x]["physical id"])
if err != nil {
continue
}
if pid == lppid {
lps = append(lps, x)
}
}
first := procAttrs[lps[0]]
p.Model = first["model name"]
p.Vendor = first["vendor_id"]
numCores, err := strconv.Atoi(first["cpu cores"])
if err != nil {
lcoreID, error := strconv.Atoi(lcore.Name()[3:]) // get "N" out of "cpuN"
if error != nil {
continue
}
p.NumCores = uint32(numCores)
numThreads, err := strconv.Atoi(first["siblings"])
if err != nil {
continue
}
p.NumThreads = uint32(numThreads)
// The flags field is a space-separated list of CPU capabilities
p.Capabilities = strings.Split(first["flags"], " ")
// Fetch CPU ID
physIdPath := fmt.Sprintf(
"%s/cpu%d/topology/physical_package_id",
paths.SysDevicesSystemCPU,
lcoreID,
)
cpuID := util.SafeIntFromFile(ctx, physIdPath)
cores := make([]*ProcessorCore, 0)
for _, lpidx := range lps {
lpid, err := strconv.Atoi(procAttrs[lpidx]["processor"])
if err != nil {
continue
proc := ProcByID(procs, cpuID)
if proc == nil {
proc = &Processor{ID: cpuID}
// Assumes /proc/cpuinfo is in order of logical cpu id, then
// procAttrs[lcoreID] describes logical cpu `lcoreID`.
// Once got a more robust way of fetching the following info,
// can we drop /proc/cpuinfo.
if len(procAttrs[lcoreID]["flags"]) != 0 { // x86
proc.Capabilities = strings.Split(procAttrs[lcoreID]["flags"], " ")
} else if len(procAttrs[lcoreID]["Features"]) != 0 { // ARM64
proc.Capabilities = strings.Split(procAttrs[lcoreID]["Features"], " ")
}
coreID, err := strconv.Atoi(procAttrs[lpidx]["core id"])
if err != nil {
continue
if len(procAttrs[lcoreID]["model name"]) != 0 {
proc.Model = procAttrs[lcoreID]["model name"]
} else if len(procAttrs[lcoreID]["uarch"]) != 0 { // SiFive
proc.Model = procAttrs[lcoreID]["uarch"]
}
var core *ProcessorCore
for _, c := range cores {
if c.ID == coreID {
c.LogicalProcessors = append(
c.LogicalProcessors,
lpid,
)
c.NumThreads = uint32(len(c.LogicalProcessors))
core = c
}
}
if core == nil {
coreLps := make([]int, 1)
coreLps[0] = lpid
core = &ProcessorCore{
ID: coreID,
Index: len(cores),
NumThreads: 1,
LogicalProcessors: coreLps,
}
cores = append(cores, core)
if len(procAttrs[lcoreID]["vendor_id"]) != 0 {
proc.Vendor = procAttrs[lcoreID]["vendor_id"]
} else if len(procAttrs[lcoreID]["isa"]) != 0 { // RISCV64
proc.Vendor = procAttrs[lcoreID]["isa"]
}
procs = append(procs, proc)
}
p.Cores = cores
procs = append(procs, p)
// Fetch Core ID
coreIdPath := fmt.Sprintf(
"%s/cpu%d/topology/core_id",
paths.SysDevicesSystemCPU,
lcoreID,
)
coreID := util.SafeIntFromFile(ctx, coreIdPath)
core := CoreByID(proc.Cores, coreID)
if core == nil {
core = &ProcessorCore{Index: coreID, NumThreads: 1}
proc.Cores = append(proc.Cores, core)
proc.NumCores += 1
} else {
core.NumThreads += 1
}
proc.NumThreads += 1
core.LogicalProcessors = append(core.LogicalProcessors, lcoreID)
}
return procs
}
+2
View File
@@ -64,6 +64,7 @@ type Paths struct {
SysBlock string
SysDevicesSystemNode string
SysDevicesSystemMemory string
SysDevicesSystemCPU string
SysBusPciDevices string
SysClassDRM string
SysClassDMI string
@@ -84,6 +85,7 @@ func New(ctx *context.Context) *Paths {
SysBlock: filepath.Join(ctx.Chroot, roots.Sys, "block"),
SysDevicesSystemNode: filepath.Join(ctx.Chroot, roots.Sys, "devices", "system", "node"),
SysDevicesSystemMemory: filepath.Join(ctx.Chroot, roots.Sys, "devices", "system", "memory"),
SysDevicesSystemCPU: filepath.Join(ctx.Chroot, roots.Sys, "devices", "system", "cpu"),
SysBusPciDevices: filepath.Join(ctx.Chroot, roots.Sys, "bus", "pci", "devices"),
SysClassDRM: filepath.Join(ctx.Chroot, roots.Sys, "class", "drm"),
SysClassDMI: filepath.Join(ctx.Chroot, roots.Sys, "class", "dmi"),
+2 -1
View File
@@ -549,7 +549,7 @@ github.com/huaweicloud/huaweicloud-sdk-go/auth/aksk
# github.com/imdario/mergo v0.3.6
## explicit
github.com/imdario/mergo
# github.com/jaypipes/ghw v0.9.0
# github.com/jaypipes/ghw v0.9.1 => github.com/zexi/ghw v0.9.1
## explicit; go 1.15
github.com/jaypipes/ghw/pkg/context
github.com/jaypipes/ghw/pkg/cpu
@@ -1494,4 +1494,5 @@ yunion.io/x/sqlchemy/backends/sqlite
## explicit; go 1.12
yunion.io/x/structarg
# github.com/go-logr/logr => github.com/go-logr/logr v0.4.0
# github.com/jaypipes/ghw => github.com/zexi/ghw v0.9.1
# google.golang.org/grpc => google.golang.org/grpc v1.29.0