diff options
| author | Asias He <asias@redhat.com> | 2013-05-07 02:54:36 -0400 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2013-07-11 08:38:40 -0400 |
| commit | 22fa90c7fb479694d6affebc049d21f06b714be6 (patch) | |
| tree | fd62ad11e27171f38d29470e5935736d835d3a4c /drivers/vhost | |
| parent | e7802212ea4bbbd5db99181942a19ab36ca4b914 (diff) | |
vhost: Remove custom vhost rcu usage
Now, vq->private_data is always accessed under vq mutex. No need to play
the vhost rcu trick.
Signed-off-by: Asias He <asias@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost')
| -rw-r--r-- | drivers/vhost/net.c | 16 | ||||
| -rw-r--r-- | drivers/vhost/scsi.c | 6 | ||||
| -rw-r--r-- | drivers/vhost/test.c | 6 | ||||
| -rw-r--r-- | drivers/vhost/vhost.h | 10 |
4 files changed, 12 insertions, 26 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 99f8d63491aa..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 | ||
| @@ -749,8 +748,7 @@ static int vhost_net_enable_vq(struct vhost_net *n, | |||
| 749 | struct vhost_poll *poll = n->poll + (nvq - n->vqs); | 748 | struct vhost_poll *poll = n->poll + (nvq - n->vqs); |
| 750 | struct socket *sock; | 749 | struct socket *sock; |
| 751 | 750 | ||
| 752 | sock = rcu_dereference_protected(vq->private_data, | 751 | sock = vq->private_data; |
| 753 | lockdep_is_held(&vq->mutex)); | ||
| 754 | if (!sock) | 752 | if (!sock) |
| 755 | return 0; | 753 | return 0; |
| 756 | 754 | ||
| @@ -763,10 +761,9 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n, | |||
| 763 | struct socket *sock; | 761 | struct socket *sock; |
| 764 | 762 | ||
| 765 | mutex_lock(&vq->mutex); | 763 | mutex_lock(&vq->mutex); |
| 766 | sock = rcu_dereference_protected(vq->private_data, | 764 | sock = vq->private_data; |
| 767 | lockdep_is_held(&vq->mutex)); | ||
| 768 | vhost_net_disable_vq(n, vq); | 765 | vhost_net_disable_vq(n, vq); |
| 769 | rcu_assign_pointer(vq->private_data, NULL); | 766 | vq->private_data = NULL; |
| 770 | mutex_unlock(&vq->mutex); | 767 | mutex_unlock(&vq->mutex); |
| 771 | return sock; | 768 | return sock; |
| 772 | } | 769 | } |
| @@ -922,8 +919,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
| 922 | } | 919 | } |
| 923 | 920 | ||
| 924 | /* start polling new socket */ | 921 | /* start polling new socket */ |
| 925 | oldsock = rcu_dereference_protected(vq->private_data, | 922 | oldsock = vq->private_data; |
| 926 | lockdep_is_held(&vq->mutex)); | ||
| 927 | if (sock != oldsock) { | 923 | if (sock != oldsock) { |
| 928 | ubufs = vhost_net_ubuf_alloc(vq, | 924 | ubufs = vhost_net_ubuf_alloc(vq, |
| 929 | sock && vhost_sock_zcopy(sock)); | 925 | sock && vhost_sock_zcopy(sock)); |
| @@ -933,7 +929,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
| 933 | } | 929 | } |
| 934 | 930 | ||
| 935 | vhost_net_disable_vq(n, vq); | 931 | vhost_net_disable_vq(n, vq); |
| 936 | rcu_assign_pointer(vq->private_data, sock); | 932 | vq->private_data = sock; |
| 937 | r = vhost_init_used(vq); | 933 | r = vhost_init_used(vq); |
| 938 | if (r) | 934 | if (r) |
| 939 | goto err_used; | 935 | goto err_used; |
| @@ -967,7 +963,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
| 967 | return 0; | 963 | return 0; |
| 968 | 964 | ||
| 969 | err_used: | 965 | err_used: |
| 970 | rcu_assign_pointer(vq->private_data, oldsock); | 966 | vq->private_data = oldsock; |
| 971 | vhost_net_enable_vq(n, vq); | 967 | vhost_net_enable_vq(n, vq); |
| 972 | if (ubufs) | 968 | if (ubufs) |
| 973 | vhost_net_ubuf_put_wait_and_free(ubufs); | 969 | vhost_net_ubuf_put_wait_and_free(ubufs); |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 45365396dbbc..35ab0ce98414 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
| @@ -1223,9 +1223,8 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs, | |||
| 1223 | sizeof(vs->vs_vhost_wwpn)); | 1223 | sizeof(vs->vs_vhost_wwpn)); |
| 1224 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { | 1224 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { |
| 1225 | vq = &vs->vqs[i].vq; | 1225 | vq = &vs->vqs[i].vq; |
| 1226 | /* Flushing the vhost_work acts as synchronize_rcu */ | ||
| 1227 | mutex_lock(&vq->mutex); | 1226 | mutex_lock(&vq->mutex); |
| 1228 | rcu_assign_pointer(vq->private_data, vs_tpg); | 1227 | vq->private_data = vs_tpg; |
| 1229 | vhost_init_used(vq); | 1228 | vhost_init_used(vq); |
| 1230 | mutex_unlock(&vq->mutex); | 1229 | mutex_unlock(&vq->mutex); |
| 1231 | } | 1230 | } |
| @@ -1304,9 +1303,8 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs, | |||
| 1304 | if (match) { | 1303 | if (match) { |
| 1305 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { | 1304 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { |
| 1306 | vq = &vs->vqs[i].vq; | 1305 | vq = &vs->vqs[i].vq; |
| 1307 | /* Flushing the vhost_work acts as synchronize_rcu */ | ||
| 1308 | mutex_lock(&vq->mutex); | 1306 | mutex_lock(&vq->mutex); |
| 1309 | rcu_assign_pointer(vq->private_data, NULL); | 1307 | vq->private_data = NULL; |
| 1310 | mutex_unlock(&vq->mutex); | 1308 | mutex_unlock(&vq->mutex); |
| 1311 | } | 1309 | } |
| 1312 | } | 1310 | } |
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index a73ea217f24d..339eae85859a 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
| 15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
| 16 | #include <linux/rcupdate.h> | ||
| 17 | #include <linux/file.h> | 16 | #include <linux/file.h> |
| 18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 19 | 18 | ||
| @@ -200,9 +199,8 @@ static long vhost_test_run(struct vhost_test *n, int test) | |||
| 200 | priv = test ? n : NULL; | 199 | priv = test ? n : NULL; |
| 201 | 200 | ||
| 202 | /* start polling new socket */ | 201 | /* start polling new socket */ |
| 203 | oldpriv = rcu_dereference_protected(vq->private_data, | 202 | oldpriv = vq->private_data; |
| 204 | lockdep_is_held(&vq->mutex)); | 203 | vq->private_data = priv; |
| 205 | rcu_assign_pointer(vq->private_data, priv); | ||
| 206 | 204 | ||
| 207 | r = vhost_init_used(&n->vqs[index]); | 205 | r = vhost_init_used(&n->vqs[index]); |
| 208 | 206 | ||
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 42298cd23c73..4465ed5f316d 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
| @@ -103,14 +103,8 @@ struct vhost_virtqueue { | |||
| 103 | struct iovec iov[UIO_MAXIOV]; | 103 | struct iovec iov[UIO_MAXIOV]; |
| 104 | struct iovec *indirect; | 104 | struct iovec *indirect; |
| 105 | struct vring_used_elem *heads; | 105 | struct vring_used_elem *heads; |
| 106 | /* We use a kind of RCU to access private pointer. | 106 | /* Protected by virtqueue mutex. */ |
| 107 | * All readers access it from worker, which makes it possible to | 107 | void *private_data; |
| 108 | * flush the vhost_work instead of synchronize_rcu. Therefore readers do | ||
| 109 | * not need to call rcu_read_lock/rcu_read_unlock: the beginning of | ||
| 110 | * vhost_work execution acts instead of rcu_read_lock() and the end of | ||
| 111 | * vhost_work execution acts instead of rcu_read_unlock(). | ||
| 112 | * Writers use virtqueue mutex. */ | ||
| 113 | void __rcu *private_data; | ||
| 114 | /* Log write descriptors */ | 108 | /* Log write descriptors */ |
| 115 | void __user *log_base; | 109 | void __user *log_base; |
| 116 | struct vhost_log *log; | 110 | struct vhost_log *log; |
