vfio: Simplify vfio_create_group()
authorJason Gunthorpe <jgg@nvidia.com>
Thu, 8 Sep 2022 18:44:58 +0000 (15:44 -0300)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 5 Dec 2022 12:56:01 +0000 (08:56 -0400)
The vfio.group_lock is now only used to serialize vfio_group creation and
destruction, we don't need a micro-optimization of searching, unlocking,
then allocating and searching again. Just hold the lock the whole time.

Grabbed from:
https://lore.kernel.org/kvm/20220922152338.2a2238fe.alex.williamson@redhat.com/

Link: https://lore.kernel.org/r/20221201145535.589687-2-yi.l.liu@intel.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Lixiao Yang <lixiao.yang@intel.com>
Tested-by: Yu He <yu.he@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
drivers/vfio/vfio_main.c

index 6d51b700764e50fc1d7682bbd9e5b8aae65a9695..f913d862a38689f26b9f7db6951fa50b748f2c31 100644 (file)
@@ -143,10 +143,12 @@ EXPORT_SYMBOL_GPL(vfio_device_set_open_count);
  * Group objects - create, release, get, put, search
  */
 static struct vfio_group *
-__vfio_group_get_from_iommu(struct iommu_group *iommu_group)
+vfio_group_get_from_iommu(struct iommu_group *iommu_group)
 {
        struct vfio_group *group;
 
+       lockdep_assert_held(&vfio.group_lock);
+
        /*
         * group->iommu_group from the vfio.group_list cannot be NULL
         * under the vfio.group_lock.
@@ -160,17 +162,6 @@ __vfio_group_get_from_iommu(struct iommu_group *iommu_group)
        return NULL;
 }
 
-static struct vfio_group *
-vfio_group_get_from_iommu(struct iommu_group *iommu_group)
-{
-       struct vfio_group *group;
-
-       mutex_lock(&vfio.group_lock);
-       group = __vfio_group_get_from_iommu(iommu_group);
-       mutex_unlock(&vfio.group_lock);
-       return group;
-}
-
 static void vfio_group_release(struct device *dev)
 {
        struct vfio_group *group = container_of(dev, struct vfio_group, dev);
@@ -225,6 +216,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
        struct vfio_group *ret;
        int err;
 
+       lockdep_assert_held(&vfio.group_lock);
+
        group = vfio_group_alloc(iommu_group, type);
        if (IS_ERR(group))
                return group;
@@ -237,26 +230,16 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
                goto err_put;
        }
 
-       mutex_lock(&vfio.group_lock);
-
-       /* Did we race creating this group? */
-       ret = __vfio_group_get_from_iommu(iommu_group);
-       if (ret)
-               goto err_unlock;
-
        err = cdev_device_add(&group->cdev, &group->dev);
        if (err) {
                ret = ERR_PTR(err);
-               goto err_unlock;
+               goto err_put;
        }
 
        list_add(&group->vfio_next, &vfio.group_list);
 
-       mutex_unlock(&vfio.group_lock);
        return group;
 
-err_unlock:
-       mutex_unlock(&vfio.group_lock);
 err_put:
        put_device(&group->dev);
        return ret;
@@ -467,7 +450,9 @@ static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev,
        if (ret)
                goto out_put_group;
 
+       mutex_lock(&vfio.group_lock);
        group = vfio_create_group(iommu_group, type);
+       mutex_unlock(&vfio.group_lock);
        if (IS_ERR(group)) {
                ret = PTR_ERR(group);
                goto out_remove_device;
@@ -516,9 +501,11 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev)
                return ERR_PTR(-EINVAL);
        }
 
+       mutex_lock(&vfio.group_lock);
        group = vfio_group_get_from_iommu(iommu_group);
        if (!group)
                group = vfio_create_group(iommu_group, VFIO_IOMMU);
+       mutex_unlock(&vfio.group_lock);
 
        /* The vfio_group holds a reference to the iommu_group */
        iommu_group_put(iommu_group);