Merge tag 'renesas-clock2-for-v3.17' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / vhost / net.c
index be414d2..8dae2f7 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/workqueue.h>
 #include <linux/file.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 
 #include <linux/net.h>
 #include <linux/if_packet.h>
@@ -373,7 +374,7 @@ static void handle_tx(struct vhost_net *net)
                              % UIO_MAXIOV == nvq->done_idx))
                        break;
 
-               head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
+               head = vhost_get_vq_desc(vq, vq->iov,
                                         ARRAY_SIZE(vq->iov),
                                         &out, &in,
                                         NULL, NULL);
@@ -505,7 +506,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
                        r = -ENOBUFS;
                        goto err;
                }
-               r = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg,
+               r = vhost_get_vq_desc(vq, vq->iov + seg,
                                      ARRAY_SIZE(vq->iov) - seg, &out,
                                      &in, log, log_num);
                if (unlikely(r < 0))
@@ -584,9 +585,9 @@ static void handle_rx(struct vhost_net *net)
        vhost_hlen = nvq->vhost_hlen;
        sock_hlen = nvq->sock_hlen;
 
-       vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
+       vq_log = unlikely(vhost_has_feature(vq, VHOST_F_LOG_ALL)) ?
                vq->log : NULL;
-       mergeable = vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF);
+       mergeable = vhost_has_feature(vq, VIRTIO_NET_F_MRG_RXBUF);
 
        while ((sock_len = peek_head_len(sock->sk))) {
                sock_len += sock_hlen;
@@ -701,16 +702,20 @@ static void handle_rx_net(struct vhost_work *work)
 
 static int vhost_net_open(struct inode *inode, struct file *f)
 {
-       struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL);
+       struct vhost_net *n;
        struct vhost_dev *dev;
        struct vhost_virtqueue **vqs;
        int i;
 
-       if (!n)
-               return -ENOMEM;
+       n = kmalloc(sizeof *n, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
+       if (!n) {
+               n = vmalloc(sizeof *n);
+               if (!n)
+                       return -ENOMEM;
+       }
        vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL);
        if (!vqs) {
-               kfree(n);
+               kvfree(n);
                return -ENOMEM;
        }
 
@@ -827,7 +832,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
         * since jobs can re-queue themselves. */
        vhost_net_flush(n);
        kfree(n->dev.vqs);
-       kfree(n);
+       kvfree(n);
        return 0;
 }
 
@@ -1038,15 +1043,13 @@ static int vhost_net_set_features(struct vhost_net *n, u64 features)
                mutex_unlock(&n->dev.mutex);
                return -EFAULT;
        }
-       n->dev.acked_features = features;
-       smp_wmb();
        for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
                mutex_lock(&n->vqs[i].vq.mutex);
+               n->vqs[i].vq.acked_features = features;
                n->vqs[i].vhost_hlen = vhost_hlen;
                n->vqs[i].sock_hlen = sock_hlen;
                mutex_unlock(&n->vqs[i].vq.mutex);
        }
-       vhost_net_flush(n);
        mutex_unlock(&n->dev.mutex);
        return 0;
 }