summaryrefslogtreecommitdiffstats
path: root/drivers/vhost/vhost.c
diff options
context:
space:
mode:
authorTonghao Zhang <xiangxia.m.yue@gmail.com>2018-09-25 08:36:49 -0400
committerDavid S. Miller <davem@davemloft.net>2018-09-26 23:25:54 -0400
commit78139c94dc8c96a478e67dab3bee84dc6eccb5fd (patch)
tree234738bd1ed26c48485efea826d6d5dc3ddc7419 /drivers/vhost/vhost.c
parentaf4325ecc24f45933d5567e72227cff2c1594764 (diff)
net: vhost: lock the vqs one by one
This patch changes the way that lock all vqs at the same, to lock them one by one. It will be used for next patch to avoid the deadlock. Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r--drivers/vhost/vhost.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index b13c6b4b2c66..f52008bb8df7 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -294,8 +294,11 @@ static void vhost_vq_meta_reset(struct vhost_dev *d)
294{ 294{
295 int i; 295 int i;
296 296
297 for (i = 0; i < d->nvqs; ++i) 297 for (i = 0; i < d->nvqs; ++i) {
298 mutex_lock(&d->vqs[i]->mutex);
298 __vhost_vq_meta_reset(d->vqs[i]); 299 __vhost_vq_meta_reset(d->vqs[i]);
300 mutex_unlock(&d->vqs[i]->mutex);
301 }
299} 302}
300 303
301static void vhost_vq_reset(struct vhost_dev *dev, 304static void vhost_vq_reset(struct vhost_dev *dev,
@@ -891,20 +894,6 @@ static inline void __user *__vhost_get_user(struct vhost_virtqueue *vq,
891#define vhost_get_used(vq, x, ptr) \ 894#define vhost_get_used(vq, x, ptr) \
892 vhost_get_user(vq, x, ptr, VHOST_ADDR_USED) 895 vhost_get_user(vq, x, ptr, VHOST_ADDR_USED)
893 896
894static void vhost_dev_lock_vqs(struct vhost_dev *d)
895{
896 int i = 0;
897 for (i = 0; i < d->nvqs; ++i)
898 mutex_lock_nested(&d->vqs[i]->mutex, i);
899}
900
901static void vhost_dev_unlock_vqs(struct vhost_dev *d)
902{
903 int i = 0;
904 for (i = 0; i < d->nvqs; ++i)
905 mutex_unlock(&d->vqs[i]->mutex);
906}
907
908static int vhost_new_umem_range(struct vhost_umem *umem, 897static int vhost_new_umem_range(struct vhost_umem *umem,
909 u64 start, u64 size, u64 end, 898 u64 start, u64 size, u64 end,
910 u64 userspace_addr, int perm) 899 u64 userspace_addr, int perm)
@@ -954,7 +943,10 @@ static void vhost_iotlb_notify_vq(struct vhost_dev *d,
954 if (msg->iova <= vq_msg->iova && 943 if (msg->iova <= vq_msg->iova &&
955 msg->iova + msg->size - 1 >= vq_msg->iova && 944 msg->iova + msg->size - 1 >= vq_msg->iova &&
956 vq_msg->type == VHOST_IOTLB_MISS) { 945 vq_msg->type == VHOST_IOTLB_MISS) {
946 mutex_lock(&node->vq->mutex);
957 vhost_poll_queue(&node->vq->poll); 947 vhost_poll_queue(&node->vq->poll);
948 mutex_unlock(&node->vq->mutex);
949
958 list_del(&node->node); 950 list_del(&node->node);
959 kfree(node); 951 kfree(node);
960 } 952 }
@@ -986,7 +978,6 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev,
986 int ret = 0; 978 int ret = 0;
987 979
988 mutex_lock(&dev->mutex); 980 mutex_lock(&dev->mutex);
989 vhost_dev_lock_vqs(dev);
990 switch (msg->type) { 981 switch (msg->type) {
991 case VHOST_IOTLB_UPDATE: 982 case VHOST_IOTLB_UPDATE:
992 if (!dev->iotlb) { 983 if (!dev->iotlb) {
@@ -1020,7 +1011,6 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev,
1020 break; 1011 break;
1021 } 1012 }
1022 1013
1023 vhost_dev_unlock_vqs(dev);
1024 mutex_unlock(&dev->mutex); 1014 mutex_unlock(&dev->mutex);
1025 1015
1026 return ret; 1016 return ret;