aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAsias He <asias@redhat.com>2013-05-07 02:54:36 -0400
committerMichael S. Tsirkin <mst@redhat.com>2013-07-11 08:38:40 -0400
commit22fa90c7fb479694d6affebc049d21f06b714be6 (patch)
treefd62ad11e27171f38d29470e5935736d835d3a4c
parente7802212ea4bbbd5db99181942a19ab36ca4b914 (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.c16
-rw-r--r--drivers/vhost/scsi.c6
-rw-r--r--drivers/vhost/test.c6
-rw-r--r--drivers/vhost/vhost.h10
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
969err_used: 965err_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;