diff options
Diffstat (limited to 'drivers/vhost/test.c')
| -rw-r--r-- | drivers/vhost/test.c | 39 | 
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 1ee45bc85f67..339eae85859a 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -13,12 +13,11 @@  #include <linux/module.h>  #include <linux/mutex.h>  #include <linux/workqueue.h> -#include <linux/rcupdate.h>  #include <linux/file.h>  #include <linux/slab.h>  #include "test.h" -#include "vhost.c" +#include "vhost.h"  /* Max number of bytes transferred before requeueing the job.   * Using this limit prevents one virtqueue from starving others. */ @@ -38,17 +37,19 @@ struct vhost_test {   * read-size critical section for our kind of RCU. */  static void handle_vq(struct vhost_test *n)  { -	struct vhost_virtqueue *vq = &n->dev.vqs[VHOST_TEST_VQ]; +	struct vhost_virtqueue *vq = &n->vqs[VHOST_TEST_VQ];  	unsigned out, in;  	int head;  	size_t len, total_len = 0;  	void *private; -	private = rcu_dereference_check(vq->private_data, 1); -	if (!private) +	mutex_lock(&vq->mutex); +	private = vq->private_data; +	if (!private) { +		mutex_unlock(&vq->mutex);  		return; +	} -	mutex_lock(&vq->mutex);  	vhost_disable_notify(&n->dev, vq);  	for (;;) { @@ -102,15 +103,23 @@ static int vhost_test_open(struct inode *inode, struct file *f)  {  	struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);  	struct vhost_dev *dev; +	struct vhost_virtqueue **vqs;  	int r;  	if (!n)  		return -ENOMEM; +	vqs = kmalloc(VHOST_TEST_VQ_MAX * sizeof(*vqs), GFP_KERNEL); +	if (!vqs) { +		kfree(n); +		return -ENOMEM; +	}  	dev = &n->dev; +	vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];  	n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; -	r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX); +	r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);  	if (r < 0) { +		kfree(vqs);  		kfree(n);  		return r;  	} @@ -126,9 +135,8 @@ static void *vhost_test_stop_vq(struct vhost_test *n,  	void *private;  	mutex_lock(&vq->mutex); -	private = rcu_dereference_protected(vq->private_data, -					 lockdep_is_held(&vq->mutex)); -	rcu_assign_pointer(vq->private_data, NULL); +	private = vq->private_data; +	vq->private_data = NULL;  	mutex_unlock(&vq->mutex);  	return private;  } @@ -140,7 +148,7 @@ static void vhost_test_stop(struct vhost_test *n, void **privatep)  static void vhost_test_flush_vq(struct vhost_test *n, int index)  { -	vhost_poll_flush(&n->dev.vqs[index].poll); +	vhost_poll_flush(&n->vqs[index].poll);  }  static void vhost_test_flush(struct vhost_test *n) @@ -191,9 +199,8 @@ static long vhost_test_run(struct vhost_test *n, int test)  		priv = test ? n : NULL;  		/* start polling new socket */ -		oldpriv = rcu_dereference_protected(vq->private_data, -						    lockdep_is_held(&vq->mutex)); -		rcu_assign_pointer(vq->private_data, priv); +		oldpriv = vq->private_data; +		vq->private_data = priv;  		r = vhost_init_used(&n->vqs[index]); @@ -268,14 +275,14 @@ static long vhost_test_ioctl(struct file *f, unsigned int ioctl,  			return -EFAULT;  		return vhost_test_run(n, test);  	case VHOST_GET_FEATURES: -		features = VHOST_NET_FEATURES; +		features = VHOST_FEATURES;  		if (copy_to_user(featurep, &features, sizeof features))  			return -EFAULT;  		return 0;  	case VHOST_SET_FEATURES:  		if (copy_from_user(&features, featurep, sizeof features))  			return -EFAULT; -		if (features & ~VHOST_NET_FEATURES) +		if (features & ~VHOST_FEATURES)  			return -EOPNOTSUPP;  		return vhost_test_set_features(n, features);  	case VHOST_RESET_OWNER:  | 
