Skip to content

Commit 55ab19d

Browse files
authored
fix(scheduler,host): sort numa node by numa distance check memsize (#23923)
1 parent 9f534e0 commit 55ab19d

File tree

17 files changed

+127
-41
lines changed

17 files changed

+127
-41
lines changed

cmd/climc/shell/compute/servers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ func init() {
149149
cmd.Get("qemu-info", new(options.ServerIdOptions))
150150
cmd.Get("hardware-info", new(options.ServerIdOptions))
151151
cmd.Get("screen-dump-show", new(options.ServerScreenDumpOptions))
152+
cmd.Get("numa-info", new(options.ServerIdOptions))
152153
cmd.BatchPerform("screen-dump", new(options.ServerIdsOptions))
153154

154155
cmd.GetProperty(&options.ServerStatusStatisticsOptions{})

pkg/apis/compute/guest_const.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ const (
256256
CPU_MODE_HOST = "host"
257257
)
258258

259+
const (
260+
VM_CPU_NUMA_PIN_SCHEDULER = "scheduler"
261+
VM_CPU_NUMA_PIN_HOST = "host"
262+
)
263+
259264
const (
260265
VM_MACHINE_TYPE_PC = "pc"
261266
VM_MACHINE_TYPE_Q35 = "q35"
@@ -345,7 +350,9 @@ const (
345350

346351
VM_METADATA_RELEASED_DEVICES = "released_devices"
347352

348-
VM_METADATA_CPU_NUMA_PIN = "__cpu_numa_pin"
353+
VM_METADATA_CPU_NUMA_PIN = "__cpu_numa_pin"
354+
VM_METADATA_CPU_NUMA_PIN_TYPE = "__cpu_numa_pin_type"
355+
349356
VM_METADATA_VIRTUAL_ISOLATED_DEVICE_CONFIG = "__virtual_isolated_device_config"
350357
// Kickstart相关metadata常量
351358
VM_METADATA_KICKSTART_CONFIG = "kickstart_config"

pkg/apis/compute/guests.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,13 @@ type ServerGetCPUSetCoresResp struct {
11111111
HostUsedCores []int `json:"host_used_cores"`
11121112
}
11131113

1114+
type ServerGetNumaInfoInput struct{}
1115+
1116+
type ServerGetNumaInfoResp struct {
1117+
CpuNumaPin jsonutils.JSONObject
1118+
IsolatedDevicesNumaNode []int8
1119+
}
1120+
11141121
type ServerGetHardwareInfoInput struct{}
11151122

11161123
type ServerHardwareInfoMotherboard struct {

pkg/compute/models/guest_actions.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ func (self *SGuest) GetSchedMigrateParams(
560560
schedDesc.SkipKernelCheck = &input.SkipKernelCheck
561561
schedDesc.HostMemPageSizeKB = host.PageSizeKB
562562
}
563-
if self.CpuNumaPin != nil {
563+
if self.IsSchedulerNumaAllocate() {
564564
cpuNumaPin := make([]schedapi.SCpuNumaPin, 0)
565565
self.CpuNumaPin.Unmarshal(&cpuNumaPin)
566566
schedDesc.CpuNumaPin = cpuNumaPin
@@ -1738,7 +1738,7 @@ func (self *SGuest) StartGueststartTask(
17381738
}
17391739
}
17401740

1741-
if !startFromCreate && self.CpuNumaPin != nil {
1741+
if !startFromCreate && self.IsSchedulerNumaAllocate() {
17421742
// clean cpu numa pin
17431743
err := self.SetCpuNumaPin(ctx, userCred, nil, nil)
17441744
if err != nil {
@@ -1783,7 +1783,7 @@ func (self *SGuest) GuestNonSchedStartTask(
17831783
if self.BackupHostId != "" {
17841784
taskName = "HAGuestStartTask"
17851785
}
1786-
if self.CpuNumaPin != nil {
1786+
if self.IsSchedulerNumaAllocate() {
17871787
srcSchedCpuNumaPin := make([]schedapi.SCpuNumaPin, 0)
17881788
err := self.CpuNumaPin.Unmarshal(&srcSchedCpuNumaPin)
17891789
if err != nil {
@@ -6788,6 +6788,22 @@ func (self *SGuest) GetDetailsCpusetCores(ctx context.Context, userCred mcclient
67886788
return resp, nil
67896789
}
67906790

6791+
func (self *SGuest) GetDetailsNumaInfo(ctx context.Context, userCred mcclient.TokenCredential, _ *api.ServerGetNumaInfoInput) (*api.ServerGetNumaInfoResp, error) {
6792+
ret := new(api.ServerGetNumaInfoResp)
6793+
devs, _ := self.GetIsolatedDevices()
6794+
if len(devs) > 0 {
6795+
ret.IsolatedDevicesNumaNode = make([]int8, 0)
6796+
for i := range devs {
6797+
if devs[i].NumaNode > 0 {
6798+
ret.IsolatedDevicesNumaNode = append(ret.IsolatedDevicesNumaNode, devs[i].NumaNode)
6799+
}
6800+
}
6801+
}
6802+
6803+
ret.CpuNumaPin = self.CpuNumaPin
6804+
return ret, nil
6805+
}
6806+
67916807
func (self *SGuest) GetDetailsHardwareInfo(ctx context.Context, userCred mcclient.TokenCredential, _ *api.ServerGetHardwareInfoInput) (*api.ServerGetHardwareInfoResp, error) {
67926808
host, err := self.GetHost()
67936809
if err != nil {

pkg/compute/models/guests.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,9 +1394,13 @@ func (guest *SGuest) SetCpuNumaPin(
13941394
}
13951395
}
13961396

1397+
var cpuNumaPinType string
13971398
var schedCpuNumaPinJ jsonutils.JSONObject
13981399
if schedCpuNumaPin != nil {
13991400
schedCpuNumaPinJ = jsonutils.Marshal(schedCpuNumaPin)
1401+
cpuNumaPinType = api.VM_CPU_NUMA_PIN_SCHEDULER
1402+
} else if cpuNumaPin != nil {
1403+
schedCpuNumaPinJ = jsonutils.Marshal(cpuNumaPin)
14001404
}
14011405
diff, err := db.Update(guest, func() error {
14021406
guest.CpuNumaPin = schedCpuNumaPinJ
@@ -1410,7 +1414,11 @@ func (guest *SGuest) SetCpuNumaPin(
14101414
if cpuNumaPin != nil {
14111415
jcpuNumaPin = jsonutils.Marshal(cpuNumaPin)
14121416
}
1413-
err = guest.SetMetadata(ctx, api.VM_METADATA_CPU_NUMA_PIN, jcpuNumaPin, userCred)
1417+
metadataMap := map[string]interface{}{
1418+
api.VM_METADATA_CPU_NUMA_PIN: jcpuNumaPin,
1419+
api.VM_METADATA_CPU_NUMA_PIN_TYPE: cpuNumaPinType,
1420+
}
1421+
err = guest.SetAllMetadata(ctx, metadataMap, userCred)
14141422
if err != nil {
14151423
return err
14161424
}
@@ -5003,7 +5011,7 @@ func (self *SGuest) createDiskOnHost(
50035011

50045012
func (self *SGuest) CreateIsolatedDeviceOnHost(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, devs []*api.IsolatedDeviceConfig, pendingUsage quotas.IQuota) error {
50055013
var numaNodes []int
5006-
if self.CpuNumaPin != nil {
5014+
if self.IsSchedulerNumaAllocate() {
50075015
numaNodes = make([]int, 0)
50085016
cpuNumaPin := make([]schedapi.SCpuNumaPin, 0)
50095017
self.CpuNumaPin.Unmarshal(&cpuNumaPin)
@@ -5296,6 +5304,11 @@ func (self *SGuest) isNeedDoResetPasswd() bool {
52965304
return true
52975305
}
52985306

5307+
func (self *SGuest) IsSchedulerNumaAllocate() bool {
5308+
cpuNumaPinType := self.GetMetadata(context.Background(), api.VM_METADATA_CPU_NUMA_PIN_TYPE, nil)
5309+
return cpuNumaPinType == api.VM_CPU_NUMA_PIN_SCHEDULER && self.CpuNumaPin != nil
5310+
}
5311+
52995312
func (self *SGuest) GetDeployConfigOnHost(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, params *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
53005313
config := jsonutils.NewDict()
53015314

@@ -5563,7 +5576,7 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *a
55635576
desc.IsolatedDevices = append(desc.IsolatedDevices, dev.getDesc())
55645577
}
55655578

5566-
if self.CpuNumaPin != nil {
5579+
if self.IsSchedulerNumaAllocate() {
55675580
cpuNumaPin := make([]api.SCpuNumaPin, 0)
55685581
cpuNumaPinStr := self.GetMetadata(ctx, api.VM_METADATA_CPU_NUMA_PIN, nil)
55695582
cpuNumaPinJson, err := jsonutils.ParseString(cpuNumaPinStr)

pkg/compute/models/hosts.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ type SHost struct {
156156
// 内存超分比
157157
MemCmtbound float32 `nullable:"true" list:"domain" create:"domain_optional"`
158158
// 页大小
159-
PageSizeKB int `nullable:"false" default:"4" list:"domain" update:"domain" create:"domain_optional"`
159+
PageSizeKB int `nullable:"false" default:"4" list:"domain" update:"domain" create:"domain_optional"`
160+
// scheduler cpu-node/numa allocate
160161
EnableNumaAllocate bool `nullable:"true" default:"false" list:"domain" update:"domain" create:"domain_optional"`
161162

162163
// 存储大小,单位Mb

pkg/compute/tasks/guest/guest_start_task.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,19 @@ func (task *GuestStartTask) OnStartComplete(ctx context.Context, obj db.IStandal
112112
guest.SetMetadata(ctx, api.VM_METADATA_START_VMEM_MB, guest.VmemSize, task.UserCred)
113113
// save start time
114114
guest.SaveLastStartAt()
115+
116+
if data.Contains("cpu_numa_pin") {
117+
cpuNumaPin := make([]api.SCpuNumaPin, 0)
118+
err := data.Unmarshal(&cpuNumaPin, "cpu_numa_pin")
119+
if err != nil {
120+
log.Errorf("failed unmarshal cpu numa pin %s", err)
121+
} else {
122+
if err = guest.SetCpuNumaPin(ctx, task.UserCred, nil, cpuNumaPin); err != nil {
123+
log.Errorf("failed set cpu numa pin %s", err)
124+
}
125+
}
126+
}
127+
115128
// sync Vpc Topology
116129
isVpc, err := guest.IsOneCloudVpcNetwork()
117130
if err != nil {

pkg/hostman/guestman/guesthelper.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ func (pq *CpuSetCounter) AllocCpuset(vcpuCount int, memSizeKB int64, preferNumaN
374374
pq.GuestIds[guestId] = struct{}{}
375375

376376
if pq.NumaEnabled && len(preferNumaNodes) > 0 {
377-
sortedNumaDistance := pq.getDistancesSeqByPreferNodes(preferNumaNodes)
377+
sortedNumaDistance := pq.getDistancesSeqByPreferNodes(preferNumaNodes, int(memSizeKB))
378378
for nodeCount := 1; nodeCount <= len(pq.Nodes); nodeCount *= 2 {
379379
ret := pq.allocCpuNumaNodesByPreferNodes(vcpuCount, int(memSizeKB), nodeCount, sortedNumaDistance)
380380
if ret != nil {
@@ -459,7 +459,7 @@ type SSortedNumaDistance struct {
459459
CpuReserved bool
460460
}
461461

462-
func (pq *CpuSetCounter) getDistancesSeqByPreferNodes(preferNumaNodes []int8) []SSortedNumaDistance {
462+
func (pq *CpuSetCounter) getDistancesSeqByPreferNodes(preferNumaNodes []int8, memSizeKB int) []SSortedNumaDistance {
463463
sortedNumaDistance := make([]SSortedNumaDistance, len(pq.Nodes))
464464
for i := range pq.Nodes {
465465
distance := 0
@@ -496,7 +496,11 @@ func (pq *CpuSetCounter) getDistancesSeqByPreferNodes(preferNumaNodes []int8) []
496496
if sortedNumaDistance[i].CpuReserved {
497497
return sortedNumaDistance[i].UsedRate < sortedNumaDistance[j].UsedRate
498498
}
499-
return sortedNumaDistance[i].FreeMemSize > sortedNumaDistance[j].FreeMemSize
499+
if sortedNumaDistance[i].Distance < sortedNumaDistance[j].Distance {
500+
return sortedNumaDistance[i].FreeMemSize > memSizeKB && sortedNumaDistance[j].FreeMemSize-sortedNumaDistance[i].FreeMemSize <= 2*memSizeKB
501+
} else {
502+
return sortedNumaDistance[j].FreeMemSize > memSizeKB && sortedNumaDistance[i].FreeMemSize-sortedNumaDistance[j].FreeMemSize >= 2*memSizeKB
503+
}
500504
})
501505
return sortedNumaDistance
502506
}

pkg/hostman/guestman/guestman.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ type SGuestManager struct {
113113
qemuMachineCpuMax map[string]uint
114114
qemuMaxMem int
115115

116-
numaAllocate bool
117-
cpuSet *CpuSetCounter
118-
pythonPath string
116+
hostagentNumaAllocate bool
117+
cpuSet *CpuSetCounter
118+
pythonPath string
119119

120120
// container related members
121121
containerProbeManager prober.Manager
@@ -344,7 +344,7 @@ func (m *SGuestManager) Bootstrap() (chan struct{}, error) {
344344

345345
if options.HostOptions.EnableHostAgentNumaAllocate {
346346
enableMemAlloc := m.host.IsContainerHost() || m.host.IsHugepagesEnabled()
347-
m.numaAllocate = !m.host.IsNumaAllocateEnabled() && enableMemAlloc && (len(hostTypo.Nodes) > 1)
347+
m.hostagentNumaAllocate = !m.host.IsSchedulerNumaAllocateEnabled() && enableMemAlloc && (len(hostTypo.Nodes) > 1)
348348
}
349349

350350
var reserveCpus = cpuset.NewCPUSet()
@@ -357,7 +357,7 @@ func (m *SGuestManager) Bootstrap() (chan struct{}, error) {
357357
}
358358

359359
cpuSet, err := NewGuestCpuSetCounter(
360-
hostTypo, reserveCpus, m.numaAllocate, m.host.IsContainerHost(),
360+
hostTypo, reserveCpus, m.hostagentNumaAllocate, m.host.IsContainerHost(),
361361
m.host.HugepageSizeKb(), m.host.CpuCmtBound(), m.host.MemCmtBound(), m.host.GetReservedMemMb(),
362362
)
363363
if err != nil {

pkg/hostman/guestman/guesttasks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2841,7 +2841,7 @@ func (task *SGuestHotplugCpuMemTask) updateGuestDesc() {
28412841
}
28422842
task.Desc.MemDesc.MemSlots = append(task.Desc.MemDesc.MemSlots, task.memSlots...)
28432843

2844-
if task.manager.numaAllocate {
2844+
if task.manager.hostagentNumaAllocate {
28452845
for i := range task.memSlotNewIndexs {
28462846
hugepageId := fmt.Sprintf("%s-%d", task.getOriginId(), task.memSlotNewIndexs[i])
28472847
task.validateNumaAllocated(hugepageId, false, true, nil)

0 commit comments

Comments
 (0)