Skip to content

Commit 3ca5470

Browse files
jgunthorpeawilliam
authored andcommitted
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>
1 parent b76c0ee commit 3ca5470

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

drivers/vfio/vfio.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct vfio_group {
6666
struct device dev;
6767
struct cdev cdev;
6868
refcount_t users;
69-
atomic_t container_users;
69+
unsigned int container_users;
7070
struct iommu_group *iommu_group;
7171
struct vfio_container *container;
7272
struct list_head device_list;
@@ -429,7 +429,7 @@ static void vfio_group_put(struct vfio_group *group)
429429
* properly hold the group reference.
430430
*/
431431
WARN_ON(!list_empty(&group->device_list));
432-
WARN_ON(atomic_read(&group->container_users));
432+
WARN_ON(group->container || group->container_users);
433433
WARN_ON(group->notifier.head);
434434

435435
list_del(&group->vfio_next);
@@ -930,6 +930,7 @@ static void __vfio_group_unset_container(struct vfio_group *group)
930930
iommu_group_release_dma_owner(group->iommu_group);
931931

932932
group->container = NULL;
933+
group->container_users = 0;
933934
list_del(&group->container_next);
934935

935936
/* Detaching the last group deprivileges a container, remove iommu */
@@ -953,17 +954,13 @@ static void __vfio_group_unset_container(struct vfio_group *group)
953954
*/
954955
static int vfio_group_unset_container(struct vfio_group *group)
955956
{
956-
int users = atomic_cmpxchg(&group->container_users, 1, 0);
957-
958957
lockdep_assert_held_write(&group->group_rwsem);
959958

960-
if (!users)
959+
if (!group->container)
961960
return -EINVAL;
962-
if (users != 1)
961+
if (group->container_users != 1)
963962
return -EBUSY;
964-
965963
__vfio_group_unset_container(group);
966-
967964
return 0;
968965
}
969966

@@ -976,7 +973,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
976973

977974
lockdep_assert_held_write(&group->group_rwsem);
978975

979-
if (atomic_read(&group->container_users))
976+
if (group->container || WARN_ON(group->container_users))
980977
return -EINVAL;
981978

982979
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)
10201017
}
10211018

10221019
group->container = container;
1020+
group->container_users = 1;
10231021
container->noiommu = (group->type == VFIO_NO_IOMMU);
10241022
list_add(&group->container_next, &container->group_list);
10251023

10261024
/* Get a reference on the container and mark a user within the group */
10271025
vfio_container_get(container);
1028-
atomic_inc(&group->container_users);
10291026

10301027
unlock_out:
10311028
up_write(&container->group_lock);
@@ -1047,22 +1044,23 @@ static int vfio_device_assign_container(struct vfio_device *device)
10471044

10481045
lockdep_assert_held_write(&group->group_rwsem);
10491046

1050-
if (0 == atomic_read(&group->container_users) ||
1051-
!group->container->iommu_driver)
1047+
if (!group->container || !group->container->iommu_driver ||
1048+
WARN_ON(!group->container_users))
10521049
return -EINVAL;
10531050

10541051
if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))
10551052
return -EPERM;
10561053

10571054
get_file(group->opened_file);
1058-
atomic_inc(&group->container_users);
1055+
group->container_users++;
10591056
return 0;
10601057
}
10611058

10621059
static void vfio_device_unassign_container(struct vfio_device *device)
10631060
{
10641061
down_write(&device->group->group_rwsem);
1065-
atomic_dec(&device->group->container_users);
1062+
WARN_ON(device->group->container_users <= 1);
1063+
device->group->container_users--;
10661064
fput(device->group->opened_file);
10671065
up_write(&device->group->group_rwsem);
10681066
}
@@ -1289,7 +1287,7 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep)
12891287
*/
12901288
WARN_ON(group->notifier.head);
12911289
if (group->container) {
1292-
WARN_ON(atomic_read(&group->container_users) != 1);
1290+
WARN_ON(group->container_users != 1);
12931291
__vfio_group_unset_container(group);
12941292
}
12951293
group->opened_file = NULL;

0 commit comments

Comments
 (0)