[libvirt] [PATCH 2/2] qemu: allow multiple buses in PCI address alocation

Ján Tomko jtomko at redhat.com
Fri Feb 15 08:22:43 UTC 2013


Allow allocating addresses with non-zero bus numbers.
---
 src/qemu/qemu_command.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b50e779..f747cfb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -954,17 +954,25 @@ cleanup:
 struct _qemuDomainPCIAddressSet {
     virHashTablePtr used;
     virDevicePCIAddress lastaddr;
+    unsigned int maxbus;
 };
 
 
-static char *qemuPCIAddressAsString(virDevicePCIAddressPtr addr)
+static char *qemuPCIAddressAsString(qemuDomainPCIAddressSetPtr addrs,
+                                    virDevicePCIAddressPtr addr)
 {
     char *str;
 
-    if (addr->domain != 0 ||
-        addr->bus != 0) {
+    if (addr->domain != 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Only PCI domain 0 and bus 0 are available"));
+                       _("Only PCI domain 0 is available"));
+        return NULL;
+    }
+
+    if (addr->bus > addrs->maxbus) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Only PCI buses up to %u are available"),
+                       addrs->maxbus);
         return NULL;
     }
 
@@ -999,7 +1007,7 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
         return 0;
     }
 
-    addr = qemuPCIAddressAsString(&info->addr.pci);
+    addr = qemuPCIAddressAsString(addrs, &info->addr.pci);
     if (!addr)
         goto cleanup;
 
@@ -1028,7 +1036,7 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
         unsigned int *func = &tmp_addr.function;
 
         for (*func = 1; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-            addr = qemuPCIAddressAsString(&tmp_addr);
+            addr = qemuPCIAddressAsString(addrs, &tmp_addr);
             if (!addr)
                 goto cleanup;
 
@@ -1148,7 +1156,7 @@ static int qemuDomainPCIAddressCheckSlot(qemuDomainPCIAddressSetPtr addrs,
     unsigned int *func = &(tmp_addr.function);
 
     for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-        str = qemuPCIAddressAsString(&tmp_addr);
+        str = qemuPCIAddressAsString(addrs, &tmp_addr);
         if (!str)
             return -1;
 
@@ -1168,7 +1176,7 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
 {
     char *str;
 
-    str = qemuPCIAddressAsString(addr);
+    str = qemuPCIAddressAsString(addrs, addr);
     if (!str)
         return -1;
 
@@ -1243,7 +1251,7 @@ int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
     char *str;
     int ret;
 
-    str = qemuPCIAddressAsString(addr);
+    str = qemuPCIAddressAsString(addrs, addr);
     if (!str)
         return -1;
 
@@ -1263,7 +1271,7 @@ int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
     unsigned int *func = &tmp_addr.function;
 
     for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
-        str = qemuPCIAddressAsString(&tmp_addr);
+        str = qemuPCIAddressAsString(addrs, &tmp_addr);
         if (!str)
             return -1;
 
@@ -1298,19 +1306,30 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
     virDevicePCIAddress tmp_addr = addrs->lastaddr;
     int i;
     char *addr;
+    bool next_bus = false;
 
     tmp_addr.slot++;
     for (i = 0; i <= QEMU_PCI_ADDRESS_LAST_SLOT; i++, tmp_addr.slot++) {
         if (QEMU_PCI_ADDRESS_LAST_SLOT < tmp_addr.slot) {
+            /* Check all the slots in this bus first */
             tmp_addr.slot = 0;
+            next_bus = !next_bus;
         }
 
-        if (!(addr = qemuPCIAddressAsString(&tmp_addr)))
+        if (!(addr = qemuPCIAddressAsString(addrs, &tmp_addr)))
             return -1;
 
         if (qemuDomainPCIAddressCheckSlot(addrs, &tmp_addr) < 0) {
             VIR_DEBUG("PCI addr %s already in use", addr);
             VIR_FREE(addr);
+            if (i == QEMU_PCI_ADDRESS_LAST_SLOT && next_bus &&
+                tmp_addr.bus < addrs->maxbus) {
+                /* Move on to the next bus if this one's full */
+                i = 0;
+                tmp_addr.bus++;
+                tmp_addr.slot = 0;
+                next_bus = !next_bus;
+            }
             continue;
         }
 
-- 
1.7.12.4




More information about the libvir-list mailing list