vhost: move -net specific code out
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 1 Nov 2012 09:16:46 +0000 (09:16 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 3 Nov 2012 01:29:58 +0000 (21:29 -0400)
Zerocopy handling code is vhost-net specific.
Move it from vhost.c/vhost.h out to net.c

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/vhost/net.c
drivers/vhost/tcm_vhost.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h

index f80ae5fc9b007d2e0a16023194258e88d33b107b..532fc8830c428ad4afd70ae889176cd574dfdd5b 100644 (file)
@@ -126,6 +126,42 @@ static void tx_poll_start(struct vhost_net *net, struct socket *sock)
        net->tx_poll_state = VHOST_NET_POLL_STARTED;
 }
 
+/* In case of DMA done not in order in lower device driver for some reason.
+ * upend_idx is used to track end of used idx, done_idx is used to track head
+ * of used idx. Once lower device DMA done contiguously, we will signal KVM
+ * guest used idx.
+ */
+int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq)
+{
+       int i;
+       int j = 0;
+
+       for (i = vq->done_idx; i != vq->upend_idx; i = (i + 1) % UIO_MAXIOV) {
+               if (VHOST_DMA_IS_DONE(vq->heads[i].len)) {
+                       vq->heads[i].len = VHOST_DMA_CLEAR_LEN;
+                       vhost_add_used_and_signal(vq->dev, vq,
+                                                 vq->heads[i].id, 0);
+                       ++j;
+               } else
+                       break;
+       }
+       if (j)
+               vq->done_idx = i;
+       return j;
+}
+
+static void vhost_zerocopy_callback(struct ubuf_info *ubuf, int status)
+{
+       struct vhost_ubuf_ref *ubufs = ubuf->ctx;
+       struct vhost_virtqueue *vq = ubufs->vq;
+
+       vhost_poll_queue(&vq->poll);
+       /* set len to mark this desc buffers done DMA */
+       vq->heads[ubuf->desc].len = status ?
+               VHOST_DMA_FAILED_LEN : VHOST_DMA_DONE_LEN;
+       vhost_ubuf_put(ubufs);
+}
+
 /* Expects to be always run from workqueue - which acts as
  * read-size critical section for our kind of RCU. */
 static void handle_tx(struct vhost_net *net)
@@ -594,9 +630,18 @@ static int vhost_net_release(struct inode *inode, struct file *f)
        struct vhost_net *n = f->private_data;
        struct socket *tx_sock;
        struct socket *rx_sock;
+       int i;
 
        vhost_net_stop(n, &tx_sock, &rx_sock);
        vhost_net_flush(n);
+       vhost_dev_stop(&n->dev);
+       for (i = 0; i < n->dev.nvqs; ++i) {
+               /* Wait for all lower device DMAs done. */
+               if (n->dev.vqs[i].ubufs)
+                       vhost_ubuf_put_and_wait(n->dev.vqs[i].ubufs);
+
+               vhost_zerocopy_signal_used(n, &n->dev.vqs[i]);
+       }
        vhost_dev_cleanup(&n->dev, false);
        if (tx_sock)
                fput(tx_sock->file);
index aa31692064ddd08b6aa91718ed1ece369da74631..23c138fdc1951558f69854639e75b81aea46395a 100644 (file)
@@ -895,6 +895,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f)
                vhost_scsi_clear_endpoint(s, &backend);
        }
 
+       vhost_dev_stop(&s->dev);
        vhost_dev_cleanup(&s->dev, false);
        kfree(s);
        return 0;
index 5affce3250314344a506261e973bb70af1806d45..ef8f5988f8550add8e2bbb2aaa13f4fd9f3027c3 100644 (file)
 #include <linux/kthread.h>
 #include <linux/cgroup.h>
 
-#include <linux/net.h>
-#include <linux/if_packet.h>
-#include <linux/if_arp.h>
-
 #include "vhost.h"
 
 enum {
@@ -414,28 +410,16 @@ long vhost_dev_reset_owner(struct vhost_dev *dev)
        return 0;
 }
 
-/* In case of DMA done not in order in lower device driver for some reason.
- * upend_idx is used to track end of used idx, done_idx is used to track head
- * of used idx. Once lower device DMA done contiguously, we will signal KVM
- * guest used idx.
- */
-int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq)
+void vhost_dev_stop(struct vhost_dev *dev)
 {
        int i;
-       int j = 0;
-
-       for (i = vq->done_idx; i != vq->upend_idx; i = (i + 1) % UIO_MAXIOV) {
-               if (VHOST_DMA_IS_DONE(vq->heads[i].len)) {
-                       vq->heads[i].len = VHOST_DMA_CLEAR_LEN;
-                       vhost_add_used_and_signal(vq->dev, vq,
-                                                 vq->heads[i].id, 0);
-                       ++j;
-               } else
-                       break;
+
+       for (i = 0; i < dev->nvqs; ++i) {
+               if (dev->vqs[i].kick && dev->vqs[i].handle_kick) {
+                       vhost_poll_stop(&dev->vqs[i].poll);
+                       vhost_poll_flush(&dev->vqs[i].poll);
+               }
        }
-       if (j)
-               vq->done_idx = i;
-       return j;
 }
 
 /* Caller should have device mutex if and only if locked is set */
@@ -444,17 +428,6 @@ void vhost_dev_cleanup(struct vhost_dev *dev, bool locked)
        int i;
 
        for (i = 0; i < dev->nvqs; ++i) {
-               if (dev->vqs[i].kick && dev->vqs[i].handle_kick) {
-                       vhost_poll_stop(&dev->vqs[i].poll);
-                       vhost_poll_flush(&dev->vqs[i].poll);
-               }
-               /* Wait for all lower device DMAs done. */
-               if (dev->vqs[i].ubufs)
-                       vhost_ubuf_put_and_wait(dev->vqs[i].ubufs);
-
-               /* Signal guest as appropriate. */
-               vhost_zerocopy_signal_used(&dev->vqs[i]);
-
                if (dev->vqs[i].error_ctx)
                        eventfd_ctx_put(dev->vqs[i].error_ctx);
                if (dev->vqs[i].error)
@@ -1599,15 +1572,3 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
        wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
        kfree(ubufs);
 }
-
-void vhost_zerocopy_callback(struct ubuf_info *ubuf, int status)
-{
-       struct vhost_ubuf_ref *ubufs = ubuf->ctx;
-       struct vhost_virtqueue *vq = ubufs->vq;
-
-       vhost_poll_queue(&vq->poll);
-       /* set len to mark this desc buffers done DMA */
-       vq->heads[ubuf->desc].len = status ?
-               VHOST_DMA_FAILED_LEN : VHOST_DMA_DONE_LEN;
-       kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
-}
index 464469d901d5cfcb31c79de6c49e46cc9747fffd..5e19e3d5db8cda6d77a516a8d3aa27bc92efbf9a 100644 (file)
@@ -7,27 +7,11 @@
 #include <linux/mutex.h>
 #include <linux/poll.h>
 #include <linux/file.h>
-#include <linux/skbuff.h>
 #include <linux/uio.h>
 #include <linux/virtio_config.h>
 #include <linux/virtio_ring.h>
 #include <linux/atomic.h>
 
-/*
- * For transmit, used buffer len is unused; we override it to track buffer
- * status internally; used for zerocopy tx only.
- */
-/* Lower device DMA failed */
-#define VHOST_DMA_FAILED_LEN   3
-/* Lower device DMA done */
-#define VHOST_DMA_DONE_LEN     2
-/* Lower device DMA in progress */
-#define VHOST_DMA_IN_PROGRESS  1
-/* Buffer unused */
-#define VHOST_DMA_CLEAR_LEN    0
-
-#define VHOST_DMA_IS_DONE(len) ((len) >= VHOST_DMA_DONE_LEN)
-
 struct vhost_device;
 
 struct vhost_work;
@@ -80,6 +64,8 @@ struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *, bool zcopy);
 void vhost_ubuf_put(struct vhost_ubuf_ref *);
 void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *);
 
+struct ubuf_info;
+
 /* The virtqueue structure describes a queue attached to a device. */
 struct vhost_virtqueue {
        struct vhost_dev *dev;
@@ -177,6 +163,7 @@ long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs);
 long vhost_dev_check_owner(struct vhost_dev *);
 long vhost_dev_reset_owner(struct vhost_dev *);
 void vhost_dev_cleanup(struct vhost_dev *, bool locked);
+void vhost_dev_stop(struct vhost_dev *);
 long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg);
 int vhost_vq_access_ok(struct vhost_virtqueue *vq);
 int vhost_log_access_ok(struct vhost_dev *);
@@ -201,8 +188,6 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *);
 
 int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
                    unsigned int log_num, u64 len);
-void vhost_zerocopy_callback(struct ubuf_info *, bool);
-int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq);
 
 #define vq_err(vq, fmt, ...) do {                                  \
                pr_debug(pr_fmt(fmt), ##__VA_ARGS__);       \