Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Asias He and committed by
Michael S. Tsirkin
22fa90c7 e7802212

+12 -26
+6 -10
drivers/vhost/net.c
··· 15 15 #include <linux/moduleparam.h> 16 16 #include <linux/mutex.h> 17 17 #include <linux/workqueue.h> 18 - #include <linux/rcupdate.h> 19 18 #include <linux/file.h> 20 19 #include <linux/slab.h> 21 20 ··· 748 749 struct vhost_poll *poll = n->poll + (nvq - n->vqs); 749 750 struct socket *sock; 750 751 751 - sock = rcu_dereference_protected(vq->private_data, 752 - lockdep_is_held(&vq->mutex)); 752 + sock = vq->private_data; 753 753 if (!sock) 754 754 return 0; 755 755 ··· 761 763 struct socket *sock; 762 764 763 765 mutex_lock(&vq->mutex); 764 - sock = rcu_dereference_protected(vq->private_data, 765 - lockdep_is_held(&vq->mutex)); 766 + sock = vq->private_data; 766 767 vhost_net_disable_vq(n, vq); 767 - rcu_assign_pointer(vq->private_data, NULL); 768 + vq->private_data = NULL; 768 769 mutex_unlock(&vq->mutex); 769 770 return sock; 770 771 } ··· 919 922 } 920 923 921 924 /* start polling new socket */ 922 - oldsock = rcu_dereference_protected(vq->private_data, 923 - lockdep_is_held(&vq->mutex)); 925 + oldsock = vq->private_data; 924 926 if (sock != oldsock) { 925 927 ubufs = vhost_net_ubuf_alloc(vq, 926 928 sock && vhost_sock_zcopy(sock)); ··· 929 933 } 930 934 931 935 vhost_net_disable_vq(n, vq); 932 - rcu_assign_pointer(vq->private_data, sock); 936 + vq->private_data = sock; 933 937 r = vhost_init_used(vq); 934 938 if (r) 935 939 goto err_used; ··· 963 967 return 0; 964 968 965 969 err_used: 966 - rcu_assign_pointer(vq->private_data, oldsock); 970 + vq->private_data = oldsock; 967 971 vhost_net_enable_vq(n, vq); 968 972 if (ubufs) 969 973 vhost_net_ubuf_put_wait_and_free(ubufs);
+2 -4
drivers/vhost/scsi.c
··· 1223 1223 sizeof(vs->vs_vhost_wwpn)); 1224 1224 for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { 1225 1225 vq = &vs->vqs[i].vq; 1226 - /* Flushing the vhost_work acts as synchronize_rcu */ 1227 1226 mutex_lock(&vq->mutex); 1228 - rcu_assign_pointer(vq->private_data, vs_tpg); 1227 + vq->private_data = vs_tpg; 1229 1228 vhost_init_used(vq); 1230 1229 mutex_unlock(&vq->mutex); 1231 1230 } ··· 1303 1304 if (match) { 1304 1305 for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { 1305 1306 vq = &vs->vqs[i].vq; 1306 - /* Flushing the vhost_work acts as synchronize_rcu */ 1307 1307 mutex_lock(&vq->mutex); 1308 - rcu_assign_pointer(vq->private_data, NULL); 1308 + vq->private_data = NULL; 1309 1309 mutex_unlock(&vq->mutex); 1310 1310 } 1311 1311 }
+2 -4
drivers/vhost/test.c
··· 13 13 #include <linux/module.h> 14 14 #include <linux/mutex.h> 15 15 #include <linux/workqueue.h> 16 - #include <linux/rcupdate.h> 17 16 #include <linux/file.h> 18 17 #include <linux/slab.h> 19 18 ··· 199 200 priv = test ? n : NULL; 200 201 201 202 /* start polling new socket */ 202 - oldpriv = rcu_dereference_protected(vq->private_data, 203 - lockdep_is_held(&vq->mutex)); 204 - rcu_assign_pointer(vq->private_data, priv); 203 + oldpriv = vq->private_data; 204 + vq->private_data = priv; 205 205 206 206 r = vhost_init_used(&n->vqs[index]); 207 207
+2 -8
drivers/vhost/vhost.h
··· 103 103 struct iovec iov[UIO_MAXIOV]; 104 104 struct iovec *indirect; 105 105 struct vring_used_elem *heads; 106 - /* We use a kind of RCU to access private pointer. 107 - * All readers access it from worker, which makes it possible to 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; 106 + /* Protected by virtqueue mutex. */ 107 + void *private_data; 114 108 /* Log write descriptors */ 115 109 void __user *log_base; 116 110 struct vhost_log *log;