[libvirt] [RFC PATCH 01/12] domain_conf: allocate cpu's apic id dynamically

Zhu Guihua zhugh.fnst at cn.fujitsu.com
Wed Jan 21 08:00:53 UTC 2015


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 at 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




More information about the libvir-list mailing list