aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vhost/net.c')
-rw-r--r--drivers/vhost/net.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 027be91db139..969a85960e9f 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -15,7 +15,6 @@
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/workqueue.h> 17#include <linux/workqueue.h>
18#include <linux/rcupdate.h>
19#include <linux/file.h> 18#include <linux/file.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21 20
@@ -346,12 +345,11 @@ static void handle_tx(struct vhost_net *net)
346 struct vhost_net_ubuf_ref *uninitialized_var(ubufs); 345 struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
347 bool zcopy, zcopy_used; 346 bool zcopy, zcopy_used;
348 347
349 /* TODO: check that we are running from vhost_worker? */ 348 mutex_lock(&vq->mutex);
350 sock = rcu_dereference_check(vq->private_data, 1); 349 sock = vq->private_data;
351 if (!sock) 350 if (!sock)
352 return; 351 goto out;
353 352
354 mutex_lock(&vq->mutex);
355 vhost_disable_notify(&net->dev, vq); 353 vhost_disable_notify(&net->dev, vq);
356 354
357 hdr_size = nvq->vhost_hlen; 355 hdr_size = nvq->vhost_hlen;
@@ -461,7 +459,7 @@ static void handle_tx(struct vhost_net *net)
461 break; 459 break;
462 } 460 }
463 } 461 }
464 462out:
465 mutex_unlock(&vq->mutex); 463 mutex_unlock(&vq->mutex);
466} 464}
467 465
@@ -570,14 +568,14 @@ static void handle_rx(struct vhost_net *net)
570 s16 headcount; 568 s16 headcount;
571 size_t vhost_hlen, sock_hlen; 569 size_t vhost_hlen, sock_hlen;
572 size_t vhost_len, sock_len; 570 size_t vhost_len, sock_len;
573 /* TODO: check that we are running from vhost_worker? */ 571 struct socket *sock;
574 struct socket *sock = rcu_dereference_check(vq->private_data, 1);
575
576 if (!sock)
577 return;
578 572
579 mutex_lock(&vq->mutex); 573 mutex_lock(&vq->mutex);
574 sock = vq->private_data;
575 if (!sock)
576 goto out;
580 vhost_disable_notify(&net->dev, vq); 577 vhost_disable_notify(&net->dev, vq);
578
581 vhost_hlen = nvq->vhost_hlen; 579 vhost_hlen = nvq->vhost_hlen;
582 sock_hlen = nvq->sock_hlen; 580 sock_hlen = nvq->sock_hlen;
583 581
@@ -652,7 +650,7 @@ static void handle_rx(struct vhost_net *net)
652 break; 650 break;
653 } 651 }
654 } 652 }
655 653out:
656 mutex_unlock(&vq->mutex); 654 mutex_unlock(&vq->mutex);
657} 655}
658 656
@@ -750,8 +748,7 @@ static int vhost_net_enable_vq(struct vhost_net *n,
750 struct vhost_poll *poll = n->poll + (nvq - n->vqs); 748 struct vhost_poll *poll = n->poll + (nvq - n->vqs);
751 struct socket *sock; 749 struct socket *sock;
752 750
753 sock = rcu_dereference_protected(vq->private_data, 751 sock = vq->private_data;
754 lockdep_is_held(&vq->mutex));
755 if (!sock) 752 if (!sock)
756 return 0; 753 return 0;
757 754
@@ -764,10 +761,9 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n,
764 struct socket *sock; 761 struct socket *sock;
765 762
766 mutex_lock(&vq->mutex); 763 mutex_lock(&vq->mutex);
767 sock = rcu_dereference_protected(vq->private_data, 764 sock = vq->private_data;
768 lockdep_is_held(&vq->mutex));
769 vhost_net_disable_vq(n, vq); 765 vhost_net_disable_vq(n, vq);
770 rcu_assign_pointer(vq->private_data, NULL); 766 vq->private_data = NULL;
771 mutex_unlock(&vq->mutex); 767 mutex_unlock(&vq->mutex);
772 return sock; 768 return sock;
773} 769}
@@ -923,8 +919,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
923 } 919 }
924 920
925 /* start polling new socket */ 921 /* start polling new socket */
926 oldsock = rcu_dereference_protected(vq->private_data, 922 oldsock = vq->private_data;
927 lockdep_is_held(&vq->mutex));
928 if (sock != oldsock) { 923 if (sock != oldsock) {
929 ubufs = vhost_net_ubuf_alloc(vq, 924 ubufs = vhost_net_ubuf_alloc(vq,
930 sock && vhost_sock_zcopy(sock)); 925 sock && vhost_sock_zcopy(sock));
@@ -934,7 +929,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
934 } 929 }
935 930
936 vhost_net_disable_vq(n, vq); 931 vhost_net_disable_vq(n, vq);
937 rcu_assign_pointer(vq->private_data, sock); 932 vq->private_data = sock;
938 r = vhost_init_used(vq); 933 r = vhost_init_used(vq);
939 if (r) 934 if (r)
940 goto err_used; 935 goto err_used;
@@ -968,7 +963,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
968 return 0; 963 return 0;
969 964
970err_used: 965err_used:
971 rcu_assign_pointer(vq->private_data, oldsock); 966 vq->private_data = oldsock;
972 vhost_net_enable_vq(n, vq); 967 vhost_net_enable_vq(n, vq);
973 if (ubufs) 968 if (ubufs)
974 vhost_net_ubuf_put_wait_and_free(ubufs); 969 vhost_net_ubuf_put_wait_and_free(ubufs);