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. Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> --- drivers/vfio/vfio.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 94ab415190011d..5c9f56d05f9dfa 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; @@ -431,7 +431,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); @@ -949,6 +949,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; wake_up(&group->container_q); list_del(&group->container_next); @@ -973,17 +974,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; } @@ -996,7 +993,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)) @@ -1040,12 +1037,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); @@ -1067,8 +1064,8 @@ 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) { @@ -1080,14 +1077,15 @@ static int vfio_device_assign_container(struct vfio_device *device) } get_file(group->singleton_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->singleton_file); up_write(&device->group->group_rwsem); } @@ -1308,7 +1306,7 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep) /* All device FDs must be released before the group fd releases. */ 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->singleton_file = NULL; -- 2.36.0