]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix PCI host reattach on domain detach.
authorChris Lalancette <clalance@redhat.com>
Tue, 26 Jan 2010 15:01:23 +0000 (10:01 -0500)
committerChris Lalancette <clalance@redhat.com>
Mon, 1 Feb 2010 15:14:39 +0000 (10:14 -0500)
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@redhat.com>
src/qemu/qemu_driver.c

index adf962a842a92e13b27c56259597336717b1d149..22593bf8ea105250af38973c35e0698a27667651 100644 (file)
@@ -2239,6 +2239,26 @@ cleanup:
     return ret;
 }
 
+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,
@@ -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);
     }