[libvirt] [PATCH v2 4/9] hostdev: Add virHostdevOnlyDetachPCIDevice()

John Ferlan jferlan at redhat.com
Tue Jan 26 23:58:26 UTC 2016



On 01/25/2016 11:20 AM, Andrea Bolognani wrote:
> This function mirrors virHostdevOnlyDetachPCIDevice().
> 
> The handling of active and inactive devices is updated and made more
> explicit, which means virHostdevPreparePCIDevices() has to be
> updated as well.
> ---
>  src/util/virhostdev.c | 87 ++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 61 insertions(+), 26 deletions(-)
> 

I think parts of patch 7 to adjust comments should just be inlined here

> diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
> index f40d636..6f14574 100644
> --- a/src/util/virhostdev.c
> +++ b/src/util/virhostdev.c
> @@ -594,6 +594,56 @@ virHostdevOnlyReattachPCIDevice(virHostdevManagerPtr mgr,
>      return ret;
>  }
>  
> +/**
> + * virHostdevOnlyDetachPCIDevice:

Similar to 1/9 comments, you could drop the "Only"

> + * @mgr: hostdev manager
> + * @pci: PCI device to be detached

... Copy of a 'hostdev' - expected to be added to inactivelist...

> + * @skipUnmanaged: whether to skip unmanaged devices
> + *
> + * Detach a PCI device from the host.
> + *
> + * This function only performs the base detach steps that are required
> + * regardless of whether the device is being attached to a domain or
> + * is simply being detached from the host for later use.
> + *
> + * The PCI related parts of @mgr (inactivePCIHostdevs, activePCIHostdevs)
> + * must have been locked beforehand using virObjectLock().
> + *
> + * Returns: 0 on success, <0 on failure
> + */
> +static int
> +virHostdevOnlyDetachPCIDevice(virHostdevManagerPtr mgr,
> +                              virPCIDevicePtr pci,
> +                              bool skipUnmanaged)
> +{
> +    int ret = -1;
> +
> +    /* Skip unmanaged devices if asked to do so */
> +    if (!virPCIDeviceGetManaged(pci) && skipUnmanaged) {
> +        VIR_DEBUG("Not detaching unmanaged PCI device %s",
> +                  virPCIDeviceGetName(pci));
> +        ret = 0;
> +        goto out;
> +    }
> +
> +    VIR_DEBUG("Detaching PCI device %s", virPCIDeviceGetName(pci));
> +    if (virPCIDeviceDetach(pci,
> +                           mgr->activePCIHostdevs,
> +                           mgr->inactivePCIHostdevs) < 0) {
> +        virErrorPtr err = virGetLastError();
> +        VIR_ERROR(_("Failed to detach PCI device %s: %s"),
> +                  virPCIDeviceGetName(pci),
> +                  err ? err->message : _("unknown error"));
> +        virResetError(err);
> +        goto out;
> +    }
> +
> +    ret = 0;
> +
> + out:
> +    return ret;
> +}
> +
>  int
>  virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
>                              const char *drv_name,
> @@ -664,17 +714,8 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
>      for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
>          virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
>  
> -        if (virPCIDeviceGetManaged(dev)) {
> -            VIR_DEBUG("Detaching managed PCI device %s",
> -                      virPCIDeviceGetName(dev));
> -            if (virPCIDeviceDetach(dev,
> -                                   hostdev_mgr->activePCIHostdevs,
> -                                   hostdev_mgr->inactivePCIHostdevs) < 0)
> -                goto reattachdevs;
> -        } else {
> -            VIR_DEBUG("Not detaching unmanaged PCI device %s",
> -                      virPCIDeviceGetName(dev));
> -        }
> +        if (virHostdevOnlyDetachPCIDevice(hostdev_mgr, dev, true) < 0)
> +            goto reattachdevs;
>      }
>  
>      /* At this point, all devices are attached to the stub driver and have
> @@ -704,23 +745,21 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
>           last_processed_hostdev_vf = i;
>      }
>  
> -    /* Loop 5: Now mark all the devices as active */
> +    /* Step 5: move all devices from the inactive list to the active list */

I know patch 7 adjusts other comments, but things are still described as
loops in other comments - probably should follow... Or of course, make
the comment changes now because [1a & 1b]

>      for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
>          virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
> +        virPCIDevicePtr actual;
>  
> -        VIR_DEBUG("Adding PCI device %s to active list",
> +        VIR_DEBUG("Removing PCI device %s from inactive list",
>                    virPCIDeviceGetName(dev));
> -        if (virPCIDeviceListAdd(hostdev_mgr->activePCIHostdevs, dev) < 0)
> +        if (!(actual = virPCIDeviceListSteal(hostdev_mgr->inactivePCIHostdevs,
> +                                             dev)))
>              goto inactivedevs;
> -    }
> -
> -    /* Loop 6: Now remove the devices from inactive list. */
> -    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {

[1a] This removes Loop 6 (or Step 6), but does not renumber the
following loops/steps nor does it address the comment much earlier "We
have to use 9 loops here."

> -        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
>  
> -        VIR_DEBUG("Removing PCI device %s from inactive list",
> -                  virPCIDeviceGetName(dev));
> -        virPCIDeviceListDel(hostdev_mgr->inactivePCIHostdevs, dev);
> +        VIR_DEBUG("Adding PCI device %s to active list",
> +                  virPCIDeviceGetName(actual));
> +        if (virPCIDeviceListAdd(hostdev_mgr->activePCIHostdevs, actual) < 0)
> +            goto inactivedevs;
>      }

This seems more efficient than the former code (and of course why I also
suggest in 1/9 to not make a second pass).
>  
>      /* Loop 7: Now set the used_by_domain of the device in
> @@ -771,10 +810,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
>          virPCIDeviceFree(dev);
>      }
>  
> -    /* Loop 9: Now steal all the devices from pcidevs */

[1b] Delete another loop/step.

> -    while (virPCIDeviceListCount(pcidevs) > 0)
> -        virPCIDeviceListStealIndex(pcidevs, 0);
> -

Hmmm.. interesting looks like this would have been a memory leak since
the code ignoree the return....  Normal when *Steal is called from
*ListDel, a *DeviceFree is called on the returned stolen device.

John

>      ret = 0;
>      goto cleanup;
>  
> 




More information about the libvir-list mailing list