mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-06 13:42:10 +08:00
fix(host): cpu hotplug compatible with high qemu version (#24759)
This commit is contained in:
@@ -2606,6 +2606,7 @@ type SGuestHotplugCpuMemTask struct {
|
||||
addedCpuCount int
|
||||
addedVcpuIds []int
|
||||
cpuNumaPin []*desc.SCpuNumaPin
|
||||
cpuList []monitor.HotpluggableCPU
|
||||
|
||||
addedMemSize int
|
||||
memSlotNewIndex *int
|
||||
@@ -2643,6 +2644,12 @@ func NewGuestHotplugCpuMemTask(
|
||||
// First at all add cpu count, second add mem size
|
||||
func (task *SGuestHotplugCpuMemTask) Start() {
|
||||
if task.addCpuCount > 0 {
|
||||
res, err := task.getHotpluggableCPUList()
|
||||
if err != nil {
|
||||
task.onFail(err.Error())
|
||||
return
|
||||
}
|
||||
task.cpuList = res
|
||||
task.startAddCpu()
|
||||
} else if task.addMemSize > 0 {
|
||||
task.startAddMem()
|
||||
@@ -2682,16 +2689,12 @@ func (task *SGuestHotplugCpuMemTask) buildVcpusMap() {
|
||||
}
|
||||
|
||||
func (task *SGuestHotplugCpuMemTask) startAddCpusWithFreeVcpuSet(vcpuSet []int) {
|
||||
if task.addedCpuCount >= task.addCpuCount {
|
||||
task.startAddMem()
|
||||
return
|
||||
}
|
||||
|
||||
vcpuId := vcpuSet[0]
|
||||
cb := func(reason string) {
|
||||
if len(reason) > 0 {
|
||||
log.Errorln(reason)
|
||||
task.onFail(reason)
|
||||
for i := range vcpuSet {
|
||||
vcpuId := vcpuSet[i]
|
||||
err := task.AddCpu(task.cpuList, vcpuSet[i])
|
||||
if err != nil {
|
||||
log.Errorf("failed add cpu %d: %s", vcpuSet[i], err)
|
||||
task.onFail(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2726,9 +2729,9 @@ func (task *SGuestHotplugCpuMemTask) startAddCpusWithFreeVcpuSet(vcpuSet []int)
|
||||
}
|
||||
|
||||
task.addedCpuCount += 1
|
||||
task.startAddCpusWithFreeVcpuSet(vcpuSet[1:])
|
||||
}
|
||||
task.Monitor.AddCpu(vcpuId, cb)
|
||||
|
||||
task.startAddMem()
|
||||
}
|
||||
|
||||
func (task *SGuestHotplugCpuMemTask) onGetCpuCount(count int) {
|
||||
@@ -2738,7 +2741,12 @@ func (task *SGuestHotplugCpuMemTask) onGetCpuCount(count int) {
|
||||
|
||||
func (task *SGuestHotplugCpuMemTask) doAddCpu() {
|
||||
if task.addedCpuCount < task.addCpuCount {
|
||||
task.Monitor.AddCpu(task.originalCpuCount+task.addedCpuCount, task.onAddCpu)
|
||||
err := task.AddCpu(task.cpuList, task.originalCpuCount+task.addedCpuCount)
|
||||
ret := ""
|
||||
if err != nil {
|
||||
ret = err.Error()
|
||||
}
|
||||
task.onAddCpu(ret)
|
||||
} else {
|
||||
task.startAddMem()
|
||||
}
|
||||
|
||||
@@ -3061,8 +3061,57 @@ func (s *SKVMGuestInstance) doBlockIoThrottle() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) startHotPlugVcpus(vcpuSet []int) error {
|
||||
func (s *SKVMGuestInstance) AddCpu(cpuList []monitor.HotpluggableCPU, cpu int) error {
|
||||
var c = make(chan error)
|
||||
cb := func(res string) {
|
||||
var e error = nil
|
||||
if len(res) > 0 {
|
||||
e = errors.Errorf("failed add cpu %d: %s", cpu, res)
|
||||
}
|
||||
c <- e
|
||||
}
|
||||
if version.GT(s.QemuVersion, "4.0.2") {
|
||||
var found = false
|
||||
for i := range cpuList {
|
||||
if cpuList[i].Props.SocketID == nil || cpuList[i].Props.CoreID == nil {
|
||||
continue
|
||||
}
|
||||
if cpuList[i].QomPath != nil {
|
||||
// cpu present
|
||||
continue
|
||||
}
|
||||
cpusPerSocket := int(s.Desc.CpuDesc.MaxCpus / s.Desc.CpuDesc.Sockets)
|
||||
coreId := int(*cpuList[i].Props.CoreID) + cpusPerSocket*int(*cpuList[i].Props.SocketID)
|
||||
if coreId == cpu {
|
||||
found = true
|
||||
params := map[string]interface{}{
|
||||
"id": fmt.Sprintf("cpu-%d", cpu),
|
||||
"core-id": cpu % cpusPerSocket,
|
||||
"socket-id": *cpuList[i].Props.SocketID,
|
||||
}
|
||||
if cpuList[i].Props.ThreadID != nil {
|
||||
params["thread-id"] = *cpuList[i].Props.ThreadID
|
||||
}
|
||||
s.Monitor.DeviceAddCpu(cpuList[i].Type, params, cb)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return errors.Errorf("hot pluggable cpu %d not found", cpu)
|
||||
}
|
||||
} else {
|
||||
s.Monitor.AddCpu(cpu, cb)
|
||||
}
|
||||
err, _ := <-c
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) startHotPlugVcpus(vcpuSet []int) error {
|
||||
cpuList, err := s.getHotpluggableCPUList()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getHotpluggableCPUList")
|
||||
}
|
||||
|
||||
for i := range vcpuSet {
|
||||
if vcpuSet[i] == 0 {
|
||||
@@ -3070,14 +3119,8 @@ func (s *SKVMGuestInstance) startHotPlugVcpus(vcpuSet []int) error {
|
||||
continue
|
||||
}
|
||||
|
||||
s.Monitor.AddCpu(vcpuSet[i], func(res string) {
|
||||
var e error = nil
|
||||
if len(res) > 0 {
|
||||
e = errors.Errorf("failed add cpu %d: %s", vcpuSet[i], res)
|
||||
}
|
||||
c <- e
|
||||
})
|
||||
if err, _ := <-c; err != nil {
|
||||
err = s.AddCpu(cpuList, vcpuSet[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,7 @@ type Monitor interface {
|
||||
ObjectAdd(objectType string, params map[string]string, callback StringCallback)
|
||||
DriveAdd(bus, node string, params map[string]string, callback StringCallback)
|
||||
DeviceAdd(dev string, params map[string]string, callback StringCallback)
|
||||
DeviceAddCpu(dev string, params map[string]interface{}, callback StringCallback)
|
||||
|
||||
XBlockdevChange(parent, node, child string, callback StringCallback)
|
||||
BlockStream(drive string, callback StringCallback)
|
||||
|
||||
@@ -553,6 +553,27 @@ func (m *QmpMonitor) DeviceAdd(dev string, params map[string]string, callback St
|
||||
m.Query(cmd, cb)
|
||||
}
|
||||
|
||||
func (m *QmpMonitor) DeviceAddCpu(dev string, params map[string]interface{}, callback StringCallback) {
|
||||
args := map[string]interface{}{
|
||||
"driver": dev,
|
||||
}
|
||||
|
||||
for k, v := range params {
|
||||
args[k] = v
|
||||
}
|
||||
|
||||
cmd := &Command{
|
||||
Execute: "device_add",
|
||||
Args: args,
|
||||
}
|
||||
|
||||
cb := func(res *Response) {
|
||||
callback(m.actionResult(res))
|
||||
}
|
||||
|
||||
m.Query(cmd, cb)
|
||||
}
|
||||
|
||||
func (m *QmpMonitor) MigrateSetDowntime(dtSec float64, callback StringCallback) {
|
||||
m.HumanMonitorCommand(fmt.Sprintf("migrate_set_downtime %f", dtSec), callback)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user