diff options
Diffstat (limited to 'drivers/vhost/net.c')
-rw-r--r-- | drivers/vhost/net.c | 37 |
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 | 462 | out: | |
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 | 653 | out: | |
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 | ||
970 | err_used: | 965 | err_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); |