[libvirt] [PATCH] Fix PCI host reattach on domain detach.

Chris Lalancette clalance at redhat.com
Wed Jan 27 14:23:51 UTC 2010


Similar to the race fixed by
be34c3c7efbb1ea8999530f98b99c5dde3793f84, make sure
to wait around for KVM to release the resources from
a hot-detached PCI device before attempting to
rebind that device to the host driver.

Signed-off-by: Chris Lalancette <clalance at redhat.com>
---
 src/qemu/qemu_driver.c |   39 +++++++++++++++++++++++----------------
 1 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index bbdbe33..5bf6743 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2240,6 +2240,26 @@ cleanup:
 }
 
 static void
+qemudReattachManagedDevice(pciDevice *dev)
+{
+    int retries = 100;
+
+    if (pciDeviceGetManaged(dev)) {
+        while (pciWaitForDeviceCleanup(dev, "kvm_assigned_device")
+               && retries) {
+            usleep(100*1000);
+            retries--;
+        }
+        if (pciReAttachDevice(NULL, dev) < 0) {
+            virErrorPtr err = virGetLastError();
+            VIR_ERROR(_("Failed to re-attach PCI device: %s"),
+                      err ? err->message : "");
+            virResetError(err);
+        }
+    }
+}
+
+static void
 qemuDomainReAttachHostDevices(virConnectPtr conn,
                               struct qemud_driver *driver,
                               virDomainDefPtr def)
@@ -2279,20 +2299,7 @@ qemuDomainReAttachHostDevices(virConnectPtr conn,
 
     for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
         pciDevice *dev = pciDeviceListGet(pcidevs, i);
-        int retries = 100;
-        if (pciDeviceGetManaged(dev)) {
-            while (pciWaitForDeviceCleanup(dev, "kvm_assigned_device")
-                   && retries) {
-                usleep(100*1000);
-                retries--;
-            }
-            if (pciReAttachDevice(NULL, dev) < 0) {
-                virErrorPtr err = virGetLastError();
-                VIR_ERROR(_("Failed to re-attach PCI device: %s"),
-                          err ? err->message : "");
-                virResetError(err);
-            }
-        }
+        qemudReattachManagedDevice(dev);
     }
 
     pciDeviceListFree(conn, pcidevs);
@@ -6128,11 +6135,11 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
     if (!pci)
         ret = -1;
     else {
+        pciDeviceSetManaged(pci, detach->managed);
         pciDeviceListDel(conn, driver->activePciHostdevs, pci);
         if (pciResetDevice(conn, pci, driver->activePciHostdevs) < 0)
             ret = -1;
-        if (detach->managed && pciReAttachDevice(conn, pci) < 0)
-            ret = -1;
+        qemudReattachManagedDevice(pci);
         pciFreeDevice(conn, pci);
     }
 
-- 
1.6.6




More information about the libvir-list mailing list