[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 3/7] qemu: switch PCI address set from hash table to an array



Each bus (just one so far) is represented by an array
with 32 slots where each slot is stored as an 8-bit integer
where each bit represents a function.

This makes operations with whole slots easier.
---
 src/qemu/qemu_command.c | 152 +++++++++++++++---------------------------------
 1 file changed, 48 insertions(+), 104 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a16d5f1..e221c82 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1187,8 +1187,14 @@ cleanup:
 
 #define QEMU_PCI_ADDRESS_LAST_SLOT 32
 #define QEMU_PCI_ADDRESS_LAST_FUNCTION 8
+
+/*
+ * Each bit represents a function
+ * Each byte represents a slot
+ */
+typedef uint8_t _qemuDomainPCIAddressBus[QEMU_PCI_ADDRESS_LAST_SLOT];
 struct _qemuDomainPCIAddressSet {
-    virHashTablePtr used;
+    _qemuDomainPCIAddressBus *used;
     virDevicePCIAddress lastaddr;
 };
 
@@ -1269,7 +1275,7 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
     if (!str)
         goto cleanup;
 
-    if (virHashLookup(addrs->used, str)) {
+    if (qemuDomainPCIAddressReserveAddr(addrs, addr) < 0) {
         if (info->addr.pci.function != 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("Attempted double use of PCI Address '%s' "
@@ -1282,36 +1288,21 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
         goto cleanup;
     }
 
-    VIR_DEBUG("Remembering PCI addr %s", str);
-    if (virHashAddEntry(addrs->used, str, str) < 0)
-        goto cleanup;
-    str = NULL;
-
     if ((info->addr.pci.function == 0) &&
         (info->addr.pci.multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON)) {
         /* a function 0 w/o multifunction=on must reserve the entire slot */
-        virDevicePCIAddress tmp_addr = *addr;
-        unsigned int *func = &tmp_addr.function;
-
-        for (*func = 1; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-            str = qemuPCIAddressAsString(&tmp_addr);
-            if (!str)
-                goto cleanup;
-
-            if (virHashLookup(addrs->used, str)) {
-                virReportError(VIR_ERR_XML_ERROR,
-                               _("Attempted double use of PCI Address '%s' "
-                                 "(need \"multifunction='off'\" for device "
-                                 "on function 0)"),
-                               str);
-                goto cleanup;
-            }
-
-            VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", str);
-            if (virHashAddEntry(addrs->used, str, str))
-                goto cleanup;
-            str = NULL;
+        ignore_value(qemuDomainPCIAddressReleaseAddr(addrs, addr));
+        if (qemuDomainPCIAddressReserveSlot(addrs, addr) < 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("Attempted double use of PCI Address '%s' "
+                             "(need \"multifunction='off'\" for device "
+                             "on function 0)"),
+                           str);
+            goto cleanup;
         }
+        VIR_DEBUG("Remembering PCI slot: %s (multifunction=off)", str);
+    } else {
+        VIR_DEBUG("Remembering PCI addr: %s", str);
     }
     ret = 0;
 cleanup:
@@ -1375,13 +1366,6 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
     return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
 }
 
-static void
-qemuDomainPCIAddressSetFreeEntry(void *payload,
-                                 const void *name ATTRIBUTE_UNUSED)
-{
-    VIR_FREE(payload);
-}
-
 qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def)
 {
     qemuDomainPCIAddressSetPtr addrs;
@@ -1389,8 +1373,8 @@ qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def)
     if (VIR_ALLOC(addrs) < 0)
         goto no_memory;
 
-    if (!(addrs->used = virHashCreate(10, qemuDomainPCIAddressSetFreeEntry)))
-        goto error;
+    if (VIR_ALLOC_N(addrs->used, 1) < 0)
+        goto no_memory;
 
     if (virDomainDeviceInfoIterate(def, qemuCollectPCIAddress, addrs) < 0)
         goto error;
@@ -1411,25 +1395,11 @@ error:
 static int qemuDomainPCIAddressCheckSlot(qemuDomainPCIAddressSetPtr addrs,
                                          virDevicePCIAddressPtr addr)
 {
-    char *str;
-    virDevicePCIAddress tmp_addr = *addr;
-    unsigned int *func = &(tmp_addr.function);
-
     if (qemuPCIAddressCheck(addrs, addr) < 0)
         return -1;
 
-    for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-        str = qemuPCIAddressAsString(&tmp_addr);
-        if (!str)
-            return -1;
-
-        if (virHashLookup(addrs->used, str)) {
-            VIR_FREE(str);
-            return -1;
-        }
-
-        VIR_FREE(str);
-    }
+    if (addrs->used[addr->bus][addr->slot])
+        return -1;
 
     return 0;
 }
@@ -1448,42 +1418,46 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
 
     VIR_DEBUG("Reserving PCI addr %s", str);
 
-    if (virHashLookup(addrs->used, str)) {
+    if (addrs->used[addr->bus][addr->slot] & 1 << addr->function) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unable to reserve PCI address %s"), str);
         VIR_FREE(str);
         return -1;
     }
 
-    if (virHashAddEntry(addrs->used, str, str)) {
-        VIR_FREE(str);
-        return -1;
-    }
+    VIR_FREE(str);
 
     addrs->lastaddr = *addr;
     addrs->lastaddr.function = 0;
     addrs->lastaddr.multi = 0;
+    addrs->used[addr->bus][addr->slot] |= 1 << addr->function;
     return 0;
 }
 
 int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
                                     virDevicePCIAddressPtr addr)
 {
-    virDevicePCIAddress tmp_addr = *addr;
-    unsigned int *func = &tmp_addr.function;
-    unsigned int last;
+    char *str;
 
-    for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-        if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr) < 0)
-            goto cleanup;
+    if (qemuPCIAddressCheck(addrs, addr) < 0)
+        return -1;
+
+    str = qemuPCIAddressAsString(addr);
+    if (!str)
+        return -1;
+
+    VIR_DEBUG("Reserving PCI slot %s", str);
+
+    if (addrs->used[addr->bus][addr->slot]) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unable to reserve PCI slot %s"), str);
+        VIR_FREE(str);
+        return -1;
     }
 
+    VIR_FREE(str);
+    addrs->used[addr->bus][addr->slot] = 0xFF;
     return 0;
-
-cleanup:
-    for (last = *func, *func = 0; *func < last; (*func)++)
-        qemuDomainPCIAddressReleaseAddr(addrs, &tmp_addr);
-    return -1;
 }
 
 int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
@@ -1512,51 +1486,21 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
 int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
                                     virDevicePCIAddressPtr addr)
 {
-    char *str;
-    int ret;
-
     if (qemuPCIAddressCheck(addrs, addr) < 0)
         return -1;
 
-    str = qemuPCIAddressAsString(addr);
-    if (!str)
-        return -1;
-
-    ret = virHashRemoveEntry(addrs->used, str);
-
-    VIR_FREE(str);
-
-    return ret;
+    addrs->used[addr->bus][addr->slot] &= ~(1 << addr->function);
+    return 0;
 }
 
 int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
                                     virDevicePCIAddressPtr addr)
 {
-    char *str;
-    int ret = 0;
-    virDevicePCIAddress tmp_addr = *addr;
-    unsigned int *func = &tmp_addr.function;
-
     if (qemuPCIAddressCheck(addrs, addr) < 0)
         return -1;
 
-    for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-        str = qemuPCIAddressAsString(&tmp_addr);
-        if (!str)
-            return -1;
-
-        if (!virHashLookup(addrs->used, str)) {
-            VIR_FREE(str);
-            continue;
-        }
-
-        VIR_FREE(str);
-
-        if (qemuDomainPCIAddressReleaseAddr(addrs, &tmp_addr) < 0)
-            ret = -1;
-    }
-
-    return ret;
+    addrs->used[addr->bus][addr->slot] = 0;
+    return 0;
 }
 
 void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
@@ -1564,7 +1508,7 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
     if (!addrs)
         return;
 
-    virHashFree(addrs->used);
+    VIR_FREE(addrs->used);
     VIR_FREE(addrs);
 }
 
-- 
1.8.1.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]