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); |
