diff options
author | Jason Gunthorpe <jgg@nvidia.com> | 2022-05-17 01:41:22 +0200 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2022-05-17 21:07:09 +0200 |
commit | 3ca5470878ebe9e31d3292391ae5fd63ab625a0b (patch) | |
tree | 3100dc0db4e4f2959d13dcaba51d4a73f12b6b87 /drivers/vfio/vfio.c | |
parent | vfio: Simplify the life cycle of the group FD (diff) | |
download | linux-3ca5470878ebe9e31d3292391ae5fd63ab625a0b.tar.xz linux-3ca5470878ebe9e31d3292391ae5fd63ab625a0b.zip |
vfio: Change struct vfio_group::container_users to a non-atomic int
Now that everything is fully locked there is no need for container_users
to remain as an atomic, change it to an unsigned int.
Use 'if (group->container)' as the test to determine if the container is
present or not instead of using container_users.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Link: https://lore.kernel.org/r/6-v2-d035a1842d81+1bf-vfio_group_locking_jgg@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/vfio.c')
-rw-r--r-- | drivers/vfio/vfio.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 149c25840130..cfcff7764403 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -66,7 +66,7 @@ struct vfio_group { struct device dev; struct cdev cdev; refcount_t users; - atomic_t container_users; + unsigned int container_users; struct iommu_group *iommu_group; struct vfio_container *container; struct list_head device_list; @@ -429,7 +429,7 @@ static void vfio_group_put(struct vfio_group *group) * properly hold the group reference. */ WARN_ON(!list_empty(&group->device_list)); - WARN_ON(atomic_read(&group->container_users)); + WARN_ON(group->container || group->container_users); WARN_ON(group->notifier.head); list_del(&group->vfio_next); @@ -930,6 +930,7 @@ static void __vfio_group_unset_container(struct vfio_group *group) iommu_group_release_dma_owner(group->iommu_group); group->container = NULL; + group->container_users = 0; list_del(&group->container_next); /* Detaching the last group deprivileges a container, remove iommu */ @@ -953,17 +954,13 @@ static void __vfio_group_unset_container(struct vfio_group *group) */ static int vfio_group_unset_container(struct vfio_group *group) { - int users = atomic_cmpxchg(&group->container_users, 1, 0); - lockdep_assert_held_write(&group->group_rwsem); - if (!users) + if (!group->container) return -EINVAL; - if (users != 1) + if (group->container_users != 1) return -EBUSY; - __vfio_group_unset_container(group); - return 0; } @@ -976,7 +973,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) lockdep_assert_held_write(&group->group_rwsem); - if (atomic_read(&group->container_users)) + if (group->container || WARN_ON(group->container_users)) return -EINVAL; if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) @@ -1020,12 +1017,12 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) } group->container = container; + group->container_users = 1; container->noiommu = (group->type == VFIO_NO_IOMMU); list_add(&group->container_next, &container->group_list); /* Get a reference on the container and mark a user within the group */ vfio_container_get(container); - atomic_inc(&group->container_users); unlock_out: up_write(&container->group_lock); @@ -1047,22 +1044,23 @@ static int vfio_device_assign_container(struct vfio_device *device) lockdep_assert_held_write(&group->group_rwsem); - if (0 == atomic_read(&group->container_users) || - !group->container->iommu_driver) + if (!group->container || !group->container->iommu_driver || + WARN_ON(!group->container_users)) return -EINVAL; if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) return -EPERM; get_file(group->opened_file); - atomic_inc(&group->container_users); + group->container_users++; return 0; } static void vfio_device_unassign_container(struct vfio_device *device) { down_write(&device->group->group_rwsem); - atomic_dec(&device->group->container_users); + WARN_ON(device->group->container_users <= 1); + device->group->container_users--; fput(device->group->opened_file); up_write(&device->group->group_rwsem); } @@ -1289,7 +1287,7 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep) */ WARN_ON(group->notifier.head); if (group->container) { - WARN_ON(atomic_read(&group->container_users) != 1); + WARN_ON(group->container_users != 1); __vfio_group_unset_container(group); } group->opened_file = NULL; |