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 f83eada..45c8e87 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13020,6 +13020,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 =
@@ -16432,6 +16438,15 @@ virDomainVcpuPinDel(virDomainDefPtr def, int vcpu)
}
}
+uint32_t
+virDomainCPUGetFreeApicID(virDomainDefPtr def)
+{
+ int idx;
+ idx = virBitmapNextClearBit(def->apic_id_map, 0);
+
+ return idx;
+}
+
int
virDomainEmulatorPinAdd(virDomainDefPtr def,
unsigned char *cpumap,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 144f79a..ff8e0b9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2074,6 +2074,7 @@ struct _virDomainDef {
unsigned short maxvcpus;
int placement_mode;
virBitmapPtr cpumask;
+ virBitmapPtr apic_id_map;
unsigned int iothreads;
@@ -2551,6 +2552,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 df4f508..b23c45c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -430,6 +430,7 @@ virDomainVcpuPinDefFree;
virDomainVcpuPinDel;
virDomainVcpuPinFindByVcpu;
virDomainVcpuPinIsDuplicate;
+virDomainCPUGetFreeApicID;
virDomainVideoDefaultRAM;
virDomainVideoDefaultType;
virDomainVideoDefFree;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4ec3b3c..c6318bc 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