[libvirt] [PATCH] qemu: Hack around asynchronous device_del

Daniel Veillard veillard at redhat.com
Tue Aug 10 09:20:43 UTC 2010


On Mon, Aug 09, 2010 at 02:46:07PM +0200, Jiri Denemark wrote:
> device_del command is not synchronous for PCI devices, it merely asks
> the guest to release the device and returns. If the host wants to use
> that device before the guest actually releases it, we are in big
> trouble. To avoid this, we already added a loop which waits up to 10
> seconds until the device is actually released before we do anything else
> with that device. But we only added this loop for managed PCI devices
> before we try reattach them back to the host.
> 
> However, we need to wait even for non-managed devices. We don't reattach
> them automatically, but we still want to prevent the host from using it.
> This was revealed thanks to sVirt: when we relabel sysfs files
> corresponding to the PCI device before the guest finished releasing the
> device, qemu is no longer allowed to access those files and if it wants
> (as a result of guest's request) to write anything to them, it just
> exits, which kills the guest.
> 
> This is not a proper fix and needs some further work both on libvirt and
> qemu side in the future.
> ---
> 
> I was thinking about another possibility to implement this since the
> wait loop doesn't have to be connected to the reattach action. We could
> move that loop into a separate function and let qemudReattach function
> do just what its name suggest. But in that case, we would need to add
> the call to such function before every call to qemudReattach, which
> doesn't look any better to me.
> 
> Jirka
> 
>  src/qemu/qemu_driver.c |   17 +++++++++--------
>  1 files changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 57b8271..e4f47d4 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -3209,16 +3209,17 @@ qemuPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
>  
>  
>  static void
> -qemudReattachManagedDevice(pciDevice *dev, struct qemud_driver *driver)
> +qemudReattachPciDevice(pciDevice *dev, struct qemud_driver *driver)
>  {
>      int retries = 100;
>  
> +    while (pciWaitForDeviceCleanup(dev, "kvm_assigned_device")
> +           && retries) {
> +        usleep(100*1000);
> +        retries--;
> +    }
> +
>      if (pciDeviceGetManaged(dev)) {
> -        while (pciWaitForDeviceCleanup(dev, "kvm_assigned_device")
> -               && retries) {
> -            usleep(100*1000);
> -            retries--;
> -        }
>          if (pciReAttachDevice(dev, driver->activePciHostdevs) < 0) {
>              virErrorPtr err = virGetLastError();
>              VIR_ERROR(_("Failed to re-attach PCI device: %s"),
> @@ -3264,7 +3265,7 @@ qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
>  
>      for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
>          pciDevice *dev = pciDeviceListGet(pcidevs, i);
> -        qemudReattachManagedDevice(dev, driver);
> +        qemudReattachPciDevice(dev, driver);
>      }
>  
>      pciDeviceListFree(pcidevs);
> @@ -8997,7 +8998,7 @@ static int qemudDomainDetachHostPciDevice(struct qemud_driver *driver,
>          pciDeviceListDel(driver->activePciHostdevs, pci);
>          if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0)
>              ret = -1;
> -        qemudReattachManagedDevice(pci, driver);
> +        qemudReattachPciDevice(pci, driver);
>          pciFreeDevice(pci);
>      }
>  

  ACK, this is not perfect as you pointed out but without QEmu support
we can't do any better I think.

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list