diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2013-04-25 18:12:38 -0400 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2013-04-25 18:12:38 -0400 |
commit | 9587f44aa69a4cfb13701b31a633852684bed701 (patch) | |
tree | ec0fa35e8156ab868ff5ca3581ec54ed1ad63f5d /drivers/vfio | |
parent | aa2cba51a0a85dfbd5be58239e59bc5e8b5fb7cf (diff) |
vfio: Convert container->group_lock to rwsem
All current users are writers, maintaining current mutual exclusion.
This lets us add read users next.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r-- | drivers/vfio/vfio.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 21eddd9e0f26..073788e50e4b 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/rwsem.h> | ||
27 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
@@ -57,7 +58,7 @@ struct vfio_iommu_driver { | |||
57 | struct vfio_container { | 58 | struct vfio_container { |
58 | struct kref kref; | 59 | struct kref kref; |
59 | struct list_head group_list; | 60 | struct list_head group_list; |
60 | struct mutex group_lock; | 61 | struct rw_semaphore group_lock; |
61 | struct vfio_iommu_driver *iommu_driver; | 62 | struct vfio_iommu_driver *iommu_driver; |
62 | void *iommu_data; | 63 | void *iommu_data; |
63 | }; | 64 | }; |
@@ -738,7 +739,7 @@ static long vfio_ioctl_check_extension(struct vfio_container *container, | |||
738 | return ret; | 739 | return ret; |
739 | } | 740 | } |
740 | 741 | ||
741 | /* hold container->group_lock */ | 742 | /* hold write lock on container->group_lock */ |
742 | static int __vfio_container_attach_groups(struct vfio_container *container, | 743 | static int __vfio_container_attach_groups(struct vfio_container *container, |
743 | struct vfio_iommu_driver *driver, | 744 | struct vfio_iommu_driver *driver, |
744 | void *data) | 745 | void *data) |
@@ -769,7 +770,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container, | |||
769 | struct vfio_iommu_driver *driver; | 770 | struct vfio_iommu_driver *driver; |
770 | long ret = -ENODEV; | 771 | long ret = -ENODEV; |
771 | 772 | ||
772 | mutex_lock(&container->group_lock); | 773 | down_write(&container->group_lock); |
773 | 774 | ||
774 | /* | 775 | /* |
775 | * The container is designed to be an unprivileged interface while | 776 | * The container is designed to be an unprivileged interface while |
@@ -780,7 +781,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container, | |||
780 | * the container is deprivileged and returns to an unset state. | 781 | * the container is deprivileged and returns to an unset state. |
781 | */ | 782 | */ |
782 | if (list_empty(&container->group_list) || container->iommu_driver) { | 783 | if (list_empty(&container->group_list) || container->iommu_driver) { |
783 | mutex_unlock(&container->group_lock); | 784 | up_write(&container->group_lock); |
784 | return -EINVAL; | 785 | return -EINVAL; |
785 | } | 786 | } |
786 | 787 | ||
@@ -827,7 +828,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container, | |||
827 | 828 | ||
828 | mutex_unlock(&vfio.iommu_drivers_lock); | 829 | mutex_unlock(&vfio.iommu_drivers_lock); |
829 | skip_drivers_unlock: | 830 | skip_drivers_unlock: |
830 | mutex_unlock(&container->group_lock); | 831 | up_write(&container->group_lock); |
831 | 832 | ||
832 | return ret; | 833 | return ret; |
833 | } | 834 | } |
@@ -882,7 +883,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep) | |||
882 | return -ENOMEM; | 883 | return -ENOMEM; |
883 | 884 | ||
884 | INIT_LIST_HEAD(&container->group_list); | 885 | INIT_LIST_HEAD(&container->group_list); |
885 | mutex_init(&container->group_lock); | 886 | init_rwsem(&container->group_lock); |
886 | kref_init(&container->kref); | 887 | kref_init(&container->kref); |
887 | 888 | ||
888 | filep->private_data = container; | 889 | filep->private_data = container; |
@@ -961,7 +962,7 @@ static void __vfio_group_unset_container(struct vfio_group *group) | |||
961 | struct vfio_container *container = group->container; | 962 | struct vfio_container *container = group->container; |
962 | struct vfio_iommu_driver *driver; | 963 | struct vfio_iommu_driver *driver; |
963 | 964 | ||
964 | mutex_lock(&container->group_lock); | 965 | down_write(&container->group_lock); |
965 | 966 | ||
966 | driver = container->iommu_driver; | 967 | driver = container->iommu_driver; |
967 | if (driver) | 968 | if (driver) |
@@ -979,7 +980,7 @@ static void __vfio_group_unset_container(struct vfio_group *group) | |||
979 | container->iommu_data = NULL; | 980 | container->iommu_data = NULL; |
980 | } | 981 | } |
981 | 982 | ||
982 | mutex_unlock(&container->group_lock); | 983 | up_write(&container->group_lock); |
983 | 984 | ||
984 | vfio_container_put(container); | 985 | vfio_container_put(container); |
985 | } | 986 | } |
@@ -1039,7 +1040,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) | |||
1039 | container = f.file->private_data; | 1040 | container = f.file->private_data; |
1040 | WARN_ON(!container); /* fget ensures we don't race vfio_release */ | 1041 | WARN_ON(!container); /* fget ensures we don't race vfio_release */ |
1041 | 1042 | ||
1042 | mutex_lock(&container->group_lock); | 1043 | down_write(&container->group_lock); |
1043 | 1044 | ||
1044 | driver = container->iommu_driver; | 1045 | driver = container->iommu_driver; |
1045 | if (driver) { | 1046 | if (driver) { |
@@ -1057,7 +1058,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) | |||
1057 | atomic_inc(&group->container_users); | 1058 | atomic_inc(&group->container_users); |
1058 | 1059 | ||
1059 | unlock_out: | 1060 | unlock_out: |
1060 | mutex_unlock(&container->group_lock); | 1061 | up_write(&container->group_lock); |
1061 | fdput(f); | 1062 | fdput(f); |
1062 | return ret; | 1063 | return ret; |
1063 | } | 1064 | } |