Add a bitmap apic_idmap to store status of APIC IDs. If you want to use an APIC
ID, you can find a minimum value which has not been used in the bitmap.
Signed-off-by: Zhu Guihua <zhugh.fnst(a)cn.fujitsu.com>
---
src/conf/domain_conf.c | 15 +++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 5 ++++-
4 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8792f5e..1631421 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12895,6 +12895,12 @@ virDomainDefParseXML(xmlDocPtr xml,
}
}
+ if (!(def->apic_id_map = virBitmapNew(def->maxvcpus)))
+ goto error;
+
+ for (i = 0; i < def->vcpus; i++)
+ ignore_value(virBitmapSetBit(def->apic_id_map, i));
+
tmp = virXPathString("string(./vcpu[1]/@placement)", ctxt);
if (tmp) {
if ((def->placement_mode =
@@ -16288,6 +16294,15 @@ virDomainVcpuPinDel(virDomainDefPtr def, int vcpu)
}
}
+uint32_t
+virDomainCPUGetFreeApicID(virDomainDefPtr def)
+{
+ int i;
+ i = virBitmapNextClearBit(def->apic_id_map, 0);
+
+ return i;
+}
+
int
virDomainEmulatorPinAdd(virDomainDefPtr def,
unsigned char *cpumap,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 09ab194..8869d26 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2062,6 +2062,7 @@ struct _virDomainDef {
unsigned short maxvcpus;
int placement_mode;
virBitmapPtr cpumask;
+ virBitmapPtr apic_id_map;
unsigned int iothreads;
@@ -2530,6 +2531,8 @@ int virDomainVcpuPinAdd(virDomainVcpuPinDefPtr **vcpupin_list,
void virDomainVcpuPinDel(virDomainDefPtr def, int vcpu);
+uint32_t virDomainCPUGetFreeApicID(virDomainDefPtr def);
+
int virDomainEmulatorPinAdd(virDomainDefPtr def,
unsigned char *cpumap,
int maplen);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a2eec83..d08e400 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -426,6 +426,7 @@ virDomainVcpuPinDefFree;
virDomainVcpuPinDel;
virDomainVcpuPinFindByVcpu;
virDomainVcpuPinIsDuplicate;
+virDomainCPUGetFreeApicID;
virDomainVideoDefaultRAM;
virDomainVideoDefaultType;
virDomainVideoDefFree;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5994558..6bc7d8d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4371,6 +4371,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
int ncpupids;
virCgroupPtr cgroup_vcpu = NULL;
char *mem_mask = NULL;
+ uint32_t apic_id;
qemuDomainObjEnterMonitor(driver, vm);
@@ -4380,13 +4381,15 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
if (nvcpus > vcpus) {
for (i = vcpus; i < nvcpus; i++) {
/* Online new CPU */
- rc = qemuMonitorSetCPU(priv->mon, i, true);
+ apic_id = virDomainCPUGetFreeApicID(vm->def);
+ rc = qemuMonitorSetCPU(priv->mon, apic_id, true);
if (rc == 0)
goto unsupported;
if (rc < 0)
goto exit_monitor;
vcpus++;
+ ignore_value(virBitmapSetBit(vm->def->apic_id_map, apic_id));
}
} else {
for (i = vcpus - 1; i >= nvcpus; i--) {
--
1.9.3