[libvirt] [PATCH v4 03/10] Refuse to reattach from vfio if the iommu group is in use by any domain

Laine Stump laine at laine.org
Fri Nov 20 15:21:39 UTC 2015


On 11/14/2015 03:36 AM, Shivaprasad G Bhat wrote:

 > Refuse to reattach from vfio if the iommu group is in use by any domain

util: refuse to reattach device if any device in the same group is in 
use by any domain

> It is incorrect to attempt the device reattach of a function,

s/function/device/

> when some other domain is using some functions belonging to the same iommu
> group.

s/some other domain/any other domain/
s/some functions/any device/

>
> Signed-off-by: Shivaprasad G Bhat <sbhat at linux.vnet.ibm.com>
> ---
>   src/util/virhostdev.c |   21 ++++++++++++++++++++-
>   1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
> index de029a0..f24ccd8 100644
> --- a/src/util/virhostdev.c
> +++ b/src/util/virhostdev.c
> @@ -1590,18 +1590,35 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
>                                   virPCIDevicePtr pci)
>   {
>       virPCIDeviceAddressPtr devAddr = NULL;
> +    bool usesVfio = false;
> +    char *drvPath = NULL;
> +    char *drvName = NULL;
>       struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, NULL,
>                                                        false};
>       int ret = -1;
>   
> +    if (virPCIDeviceGetDriverPathAndName(pci, &drvPath, &drvName) < 0)
> +        goto out;
> +
> +    if (STREQ_NULLABLE(drvName, "vfio-pci"))
> +        usesVfio = true;
> +
>       virObjectLock(hostdev_mgr->activePCIHostdevs);
>       virObjectLock(hostdev_mgr->inactivePCIHostdevs);
>   
>       if (!(devAddr = virPCIDeviceGetAddress(pci)))
>           goto out;
>   
> -    if (virHostdevIsPCINodeDeviceUsed(devAddr, &data))
> +    if (usesVfio) {
> +    /* Doesn't matter which device. If any domain is actively using the
> +     * iommu group, refuse to reattach */
> +        if (virPCIDeviceAddressIOMMUGroupIterate(devAddr,
> +                                                 virHostdevIsPCINodeDeviceUsed,
> +                                                 &data) < 0)
> +            goto out;

Calling the iterator seems very inefficient to me (which is why I 
suggested in the original BZ comments that we save the iommuGroup of 
each device to the activelist):

1) you know the iommu group of the current PCI device (it is in 
pci->iommuGroup)

2) all that virHostdevIsPCINodeDeviceUsed does is check through 
activePCIHostdevs for the device, and this iterator is just calling 
virHostdevIsPCINodeDeviceUsed for each device in the same iommuGroup as 
the current device.

Therefore, all you really need to do is look for any devices in 
acticePCIHostdevs that have dev->iommuGroup == pci->iommuGroup.

Calling the iterator results in a lot of accesses to sysfs, opening and 
closing files, printfs, etc. Unless that is necessary to catch some 
extra case (and I don't see that), it's much better to do it the simpler 
way - more efficient and easier to understand a year from now when we 
come back to this.

> +    } else if (virHostdevIsPCINodeDeviceUsed(devAddr, &data)) {
>           goto out;
> +    }
>   
>       virPCIDeviceReattachInit(pci);
>   
> @@ -1614,6 +1631,8 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
>       virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
>       virObjectUnlock(hostdev_mgr->activePCIHostdevs);
>       VIR_FREE(devAddr);
> +    VIR_FREE(drvPath);
> +    VIR_FREE(drvName);
>       return ret;
>   }
>   
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>




More information about the libvir-list mailing list