[libvirt] [PATCH 3/4] qemu: Assign slots to memory devices prior to usage

Peter Krempa pkrempa at redhat.com
Thu Nov 3 06:12:53 UTC 2016


As with other devices assign the slot number right away when adding the
device. This will make the slot numbers static as we do with other
addressing elements and it will ultimately simplify allocation of the
alias in a static way which does not break with qemu.
---
 src/qemu/qemu_domain_address.c                     | 91 ++++++++++++++++++++++
 src/qemu/qemu_domain_address.h                     |  4 +
 src/qemu/qemu_hotplug.c                            |  3 +
 .../qemuxml2argv-hugepages-numa.args               |  2 +-
 .../qemuxml2argv-memory-hotplug-dimm.args          |  4 +-
 .../qemuxml2argv-memory-hotplug-ppc64-nonuma.args  |  4 +-
 .../qemuxml2xmlout-memory-hotplug-dimm.xml         |  2 +
 7 files changed, 105 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index b35a95f..6ce3b1e 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1748,6 +1748,94 @@ qemuDomainUSBAddressAddHubs(virDomainDefPtr def)
 }


+static virBitmapPtr
+qemuDomainGetMemorySlotMap(const virDomainDef *def)
+{
+    virBitmapPtr ret;
+    virDomainMemoryDefPtr mem;
+    size_t i;
+
+    if (!(ret = virBitmapNew(def->mem.memory_slots)))
+        return NULL;
+
+    for (i = 0; i < def->nmems; i++) {
+        mem = def->mems[i];
+
+        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM)
+            ignore_value(virBitmapSetBit(ret, mem->info.addr.dimm.slot));
+    }
+
+    return ret;
+}
+
+
+static int
+qemuAssignMemoryDeviceSlot(virDomainMemoryDefPtr mem,
+                           virBitmapPtr slotmap)
+{
+    ssize_t nextslot = -1;
+
+    if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM)
+        return 0;
+
+    if ((nextslot = virBitmapNextClearBit(slotmap, -1)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("failed to find a emtpy memory slot"));
+        return -1;
+    }
+
+    ignore_value(virBitmapSetBit(slotmap, nextslot));
+    mem->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM;
+    mem->info.addr.dimm.slot = nextslot;
+
+    return 0;
+}
+
+
+int
+qemuDomainAssignMemoryDeviceSlot(virDomainDefPtr def,
+                                 virDomainMemoryDefPtr mem)
+{
+    virBitmapPtr slotmap = NULL;
+    int ret;
+
+    if (!(slotmap = qemuDomainGetMemorySlotMap(def)))
+        return -1;
+
+    ret = qemuAssignMemoryDeviceSlot(mem, slotmap);
+
+    virBitmapFree(slotmap);
+    return ret;
+}
+
+
+static int
+qemuDomainAssignMemorySlots(virDomainDefPtr def)
+{
+    virBitmapPtr slotmap = NULL;
+    int ret = -1;
+    size_t i;
+
+    if (!virDomainDefHasMemoryHotplug(def))
+        return 0;
+
+    if (!(slotmap = qemuDomainGetMemorySlotMap(def)))
+        return -1;
+
+    for (i = 0; i < def->nmems; i++) {
+        if (qemuAssignMemoryDeviceSlot(def->mems[i], slotmap) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    virBitmapFree(slotmap);
+    return ret;
+
+}
+
+
 static int
 qemuDomainAssignUSBAddresses(virDomainDefPtr def,
                              virDomainObjPtr obj,
@@ -1827,6 +1915,9 @@ qemuDomainAssignAddresses(virDomainDefPtr def,
     if (qemuDomainAssignUSBAddresses(def, obj, newDomain) < 0)
         return -1;

+    if (qemuDomainAssignMemorySlots(def) < 0)
+        return -1;
+
     return 0;
 }

diff --git a/src/qemu/qemu_domain_address.h b/src/qemu/qemu_domain_address.h
index 11d6e92..ecb92b5 100644
--- a/src/qemu/qemu_domain_address.h
+++ b/src/qemu/qemu_domain_address.h
@@ -45,6 +45,10 @@ virDomainCCWAddressSetPtr
 qemuDomainCCWAddrSetCreateFromDomain(virDomainDefPtr def)
     ATTRIBUTE_NONNULL(1);

+int qemuDomainAssignMemoryDeviceSlot(virDomainDefPtr def,
+                                     virDomainMemoryDefPtr mem);
+
+
 # define __QEMU_DOMAIN_ADDRESS_H__

 #endif /* __QEMU_DOMAIN_ADDRESS_H__ */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e06862c..75477cd 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2127,6 +2127,9 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     if (qemuDomainDefValidateMemoryHotplug(vm->def, priv->qemuCaps, mem) < 0)
         goto cleanup;

+    if (qemuDomainAssignMemoryDeviceSlot(vm->def, mem) < 0)
+        goto cleanup;
+
     if (qemuAssignDeviceMemoryAlias(vm->def, mem) < 0)
         goto cleanup;

diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args
index 2eb006e..7b90784 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args
@@ -16,7 +16,7 @@ QEMU_AUDIO_DRV=spice \
 -object memory-backend-file,id=memdimm0,prealloc=yes,\
 mem-path=/dev/hugepages1G/libvirt/qemu,size=1073741824,host-nodes=1-3,\
 policy=bind \
--device pc-dimm,node=0,memdev=memdimm0,id=dimm0 \
+-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \
 -uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
 -nodefaults \
 -monitor unix:/tmp/lib/domain--1-fedora/monitor.sock,server,nowait \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args
index fa64fcf..1587aba 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args
@@ -12,11 +12,11 @@ QEMU_AUDIO_DRV=none \
 -smp 2,sockets=2,cores=1,threads=1 \
 -numa node,nodeid=0,cpus=0-1,mem=214 \
 -object memory-backend-ram,id=memdimm0,size=536870912 \
--device pc-dimm,node=0,memdev=memdimm0,id=dimm0 \
+-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \
 -object memory-backend-file,id=memdimm1,prealloc=yes,\
 mem-path=/dev/hugepages2M/libvirt/qemu,size=536870912,host-nodes=1-3,\
 policy=bind \
--device pc-dimm,node=0,memdev=memdimm1,id=dimm1 \
+-device pc-dimm,node=0,memdev=memdimm1,id=dimm1,slot=1 \
 -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
 -nographic \
 -nodefaults \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args
index 8a85fb1..475b721 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args
@@ -11,9 +11,9 @@ QEMU_AUDIO_DRV=none \
 -m size=1310720k,slots=16,maxmem=4194304k \
 -smp 1,sockets=1,cores=1,threads=1 \
 -object memory-backend-ram,id=memdimm0,size=536870912 \
--device pc-dimm,memdev=memdimm0,id=dimm0 \
+-device pc-dimm,memdev=memdimm0,id=dimm0,slot=0 \
 -object memory-backend-ram,id=memdimm1,size=536870912 \
--device pc-dimm,memdev=memdimm1,id=dimm1 \
+-device pc-dimm,memdev=memdimm1,id=dimm1,slot=1 \
 -uuid 49545eb3-75e1-2d0a-acdd-f0294406c99e \
 -nographic \
 -nodefaults \
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml
index c5b5d75..be97e4e 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml
@@ -47,6 +47,7 @@
         <size unit='KiB'>523264</size>
         <node>0</node>
       </target>
+      <address type='dimm' slot='0'/>
     </memory>
     <memory model='dimm'>
       <source>
@@ -57,6 +58,7 @@
         <size unit='KiB'>524287</size>
         <node>0</node>
       </target>
+      <address type='dimm' slot='1'/>
     </memory>
   </devices>
 </domain>
-- 
2.10.2




More information about the libvir-list mailing list