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