[PATCH v2 19/21] qemu_hotplug.c: tune unplugTimeout for multifunction detach

Daniel Henrique Barboza danielhb413 at gmail.com
Thu Jan 30 16:44:31 UTC 2020


In a multifunction hot-unplug, QEMU will unplug all the
functions in a single detach operation, sequentially, triggered
by the detach of function zero for Pseries guests or any
function for x86 guests. This impacts the amount of timeout
we're supposed to wait - an unplug operation with 4
hostdevs will naturally take longer than a single
hostdev unplug.

The previous existing timeout wasn't enough to handle this
multifunction detach case, timing out the detach operation
needlessly. This patch handles it by adding a new
qemuDomainWaitForMultipleDeviceRemoval function that
considers the number of naliases to be unplugged when
calculating unplugTimeout.

Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
---
 src/qemu/qemu_hotplug.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index deeb94fe79..fe823bb910 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -5216,15 +5216,21 @@ qemuDomainGetUnplugTimeout(virDomainObjPtr vm)
  *      - we failed to reliably wait for the event and thus use fallback behavior
  */
 static int
-qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
+qemuDomainWaitForMultipleDeviceRemoval(virDomainObjPtr vm,
+                                       bool isMultiFunctionDevice)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    unsigned long long until;
+    unsigned long long until, waitTime;
     int rc;
 
     if (virTimeMillisNow(&until) < 0)
         return 1;
-    until += qemuDomainGetUnplugTimeout(vm);
+
+    waitTime = qemuDomainGetUnplugTimeout(vm);
+    if (isMultiFunctionDevice)
+        waitTime *= priv->unplug.naliases;
+
+    until += waitTime;
 
     /* All devices should get released around same time*/
     while (priv->unplug.naliases) {
@@ -5247,6 +5253,17 @@ qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
     return 1;
 }
 
+/* For a single device, call qemuDomainWaitForMultipleDeviceRemoval with
+ * isMultiFunctionDevice = false.
+ *
+ * Returns: same values as qemuDomainWaitForMultipleDeviceRemoval.
+ */
+static int
+qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
+{
+    return qemuDomainWaitForMultipleDeviceRemoval(vm, false);
+}
+
 /* Returns:
  *  true    there was a thread waiting for devAlias to be removed and this
  *          thread will take care of finishing the removal
@@ -6098,7 +6115,7 @@ qemuDomainDetachMultifunctionDevice(virDomainObjPtr vm,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         ret = -1;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) {
+    if ((ret = qemuDomainWaitForMultipleDeviceRemoval(vm, true)) == 1) {
         FOR_EACH_DEV_IN_DEVLIST()
              ret = qemuDomainRemoveHostDevice(driver, vm, detach);
         }
-- 
2.24.1





More information about the libvir-list mailing list