[RFC V2 5/7] VSOCK: Introduce vhost-vsock.ko

2014-07-04 Thread Asias He
From: Asias He 

VM sockets vhost transport implementation. This module runs in host
kernel.

Signed-off-by: Asias He 
---
 drivers/vhost/vsock.c | 572 ++
 drivers/vhost/vsock.h |   4 +
 2 files changed, 576 insertions(+)
 create mode 100644 drivers/vhost/vsock.c
 create mode 100644 drivers/vhost/vsock.h

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
new file mode 100644
index 000..deffed9
--- /dev/null
+++ b/drivers/vhost/vsock.c
@@ -0,0 +1,572 @@
+/*
+ * vhost transport for vsock
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Author: Asias He 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "vhost.h"
+#include "vsock.h"
+
+#define VHOST_VSOCK_DEFAULT_HOST_CID   2
+
+static int vhost_transport_socket_init(struct vsock_sock *vsk,
+  struct vsock_sock *psk);
+
+enum {
+   VHOST_VSOCK_FEATURES = VHOST_FEATURES,
+};
+
+/* Used to track all the vhost_vsock instances on the system. */
+static LIST_HEAD(vhost_vsock_list);
+static DEFINE_MUTEX(vhost_vsock_mutex);
+
+struct vhost_vsock_virtqueue {
+   struct vhost_virtqueue vq;
+};
+
+struct vhost_vsock {
+   /* Vhost device */
+   struct vhost_dev dev;
+   /* Vhost vsock virtqueue*/
+   struct vhost_vsock_virtqueue vqs[VSOCK_VQ_MAX];
+   /* Link to global vhost_vsock_list*/
+   struct list_head list;
+   /* Head for pkt from host to guest */
+   struct list_head send_pkt_list;
+   /* Work item to send pkt */
+   struct vhost_work send_pkt_work;
+   /* Wait queue for send pkt */
+   wait_queue_head_t queue_wait;
+   /* Used for global tx buf limitation */
+   u32 total_tx_buf;
+   /* Guest contex id this vhost_vsock instance handles */
+   u32 guest_cid;
+};
+
+static u32 vhost_transport_get_local_cid(void)
+{
+   u32 cid = VHOST_VSOCK_DEFAULT_HOST_CID;
+   return cid;
+}
+
+static struct vhost_vsock *vhost_vsock_get(u32 guest_cid)
+{
+   struct vhost_vsock *vsock;
+
+   mutex_lock(&vhost_vsock_mutex);
+   list_for_each_entry(vsock, &vhost_vsock_list, list) {
+   if (vsock->guest_cid == guest_cid) {
+   mutex_unlock(&vhost_vsock_mutex);
+   return vsock;
+   }
+   }
+   mutex_unlock(&vhost_vsock_mutex);
+
+   return NULL;
+}
+
+static void
+vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
+   struct vhost_virtqueue *vq)
+{
+   struct virtio_vsock_pkt *pkt;
+   bool added = false;
+   unsigned out, in;
+   struct sock *sk;
+   int head, ret;
+
+   mutex_lock(&vq->mutex);
+   vhost_disable_notify(&vsock->dev, vq);
+   for (;;) {
+   if (list_empty(&vsock->send_pkt_list)) {
+   vhost_enable_notify(&vsock->dev, vq);
+   break;
+   }
+
+   head = vhost_get_vq_desc(&vsock->dev, vq, vq->iov,
+   ARRAY_SIZE(vq->iov), &out, &in,
+   NULL, NULL);
+   pr_debug("%s: head = %d\n", __func__, head);
+   if (head < 0)
+   break;
+
+   if (head == vq->num) {
+   if (unlikely(vhost_enable_notify(&vsock->dev, vq))) {
+   vhost_disable_notify(&vsock->dev, vq);
+   continue;
+   }
+   break;
+   }
+
+   pkt = list_first_entry(&vsock->send_pkt_list,
+  struct virtio_vsock_pkt, list);
+   list_del_init(&pkt->list);
+
+   /* FIXME: no assumption of frame layout */
+   ret = __copy_to_user(vq->iov[0].iov_base, &pkt->hdr,
+sizeof(pkt->hdr));
+   if (ret) {
+   virtio_transport_free_pkt(pkt);
+   vq_err(vq, "Faulted on copying pkt hdr\n");
+   break;
+   }
+   if (pkt->buf && pkt->len > 0) {
+   ret = __copy_to_user(vq->iov[1].iov_base, pkt->buf,
+   pkt->len);
+   if (ret) {
+   virtio_transport_free_pkt(pkt);
+   vq_err(vq, "Faulted on copying pkt buf\n");
+   break;
+   }
+   }
+
+   vhost_add_used(vq, head, pkt->len);
+   added = true;
+
+   virtio_transport_dec_tx_pkt(pkt);
+  

[RFC V2 4/7] VSOCK: Introduce virtio-vsock.ko

2014-07-04 Thread Asias He
From: Asias He 

VM sockets virtio transport implementation. This module runs in guest
kernel.

Signed-off-by: Asias He 
---
 net/vmw_vsock/virtio_transport.c | 448 +++
 1 file changed, 448 insertions(+)
 create mode 100644 net/vmw_vsock/virtio_transport.c

diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
new file mode 100644
index 000..05a06a8
--- /dev/null
+++ b/net/vmw_vsock/virtio_transport.c
@@ -0,0 +1,448 @@
+/*
+ * virtio transport for vsock
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Author: Asias He 
+ *
+ * Some of the code is take from Gerd Hoffmann 's
+ * early virtio-vsock proof-of-concept bits.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static struct workqueue_struct *virtio_vsock_workqueue;
+static struct virtio_vsock *the_virtio_vsock;
+static void virtio_vsock_rx_fill(struct virtio_vsock *vsock);
+
+struct virtio_vsock {
+   /* Virtio device */
+   struct virtio_device *vdev;
+   /* Virtio virtqueue */
+   struct virtqueue *vqs[VSOCK_VQ_MAX];
+   /* Wait queue for send pkt */
+   wait_queue_head_t queue_wait;
+   /* Work item to send pkt */
+   struct work_struct tx_work;
+   /* Work item to recv pkt */
+   struct work_struct rx_work;
+   /* Mutex to protect send pkt*/
+   struct mutex tx_lock;
+   /* Mutex to protect recv pkt*/
+   struct mutex rx_lock;
+   /* Number of recv buffers */
+   int rx_buf_nr;
+   /* Number of max recv buffers */
+   int rx_buf_max_nr;
+   /* Used for global tx buf limitation */
+   u32 total_tx_buf;
+   /* Guest context id, just like guest ip address */
+   u32 guest_cid;
+};
+
+static struct virtio_vsock *virtio_vsock_get(void)
+{
+   return the_virtio_vsock;
+}
+
+static u32 virtio_transport_get_local_cid(void)
+{
+   struct virtio_vsock *vsock = virtio_vsock_get();
+
+   return vsock->guest_cid;
+}
+
+static int
+virtio_transport_send_pkt(struct vsock_sock *vsk,
+ struct virtio_vsock_pkt_info *info)
+{
+   u32 src_cid, src_port, dst_cid, dst_port;
+   int ret, in_sg = 0, out_sg = 0;
+   struct virtio_transport *trans;
+   struct virtio_vsock_pkt *pkt;
+   struct virtio_vsock *vsock;
+   struct scatterlist hdr, buf, *sgs[2];
+   struct virtqueue *vq;
+   u32 pkt_len = info->pkt_len;
+   DEFINE_WAIT(wait);
+
+   vsock = virtio_vsock_get();
+   if (!vsock)
+   return -ENODEV;
+
+   src_cid = virtio_transport_get_local_cid();
+   src_port = vsk->local_addr.svm_port;
+   if (!info->remote_cid) {
+   dst_cid = vsk->remote_addr.svm_cid;
+   dst_port = vsk->remote_addr.svm_port;
+   } else {
+   dst_cid = info->remote_cid;
+   dst_port = info->remote_port;
+   }
+
+   trans = vsk->trans;
+   vq = vsock->vqs[VSOCK_VQ_TX];
+
+   if (pkt_len > VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE)
+   pkt_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
+   pkt_len = virtio_transport_get_credit(trans, pkt_len);
+   /* Do not send zero length OP_RW pkt*/
+   if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW)
+   return pkt_len;
+
+   /* Respect global tx buf limitation */
+   mutex_lock(&vsock->tx_lock);
+   while (pkt_len + vsock->total_tx_buf > VIRTIO_VSOCK_MAX_TX_BUF_SIZE) {
+   prepare_to_wait_exclusive(&vsock->queue_wait, &wait,
+ TASK_UNINTERRUPTIBLE);
+   mutex_unlock(&vsock->tx_lock);
+   schedule();
+   mutex_lock(&vsock->tx_lock);
+   finish_wait(&vsock->queue_wait, &wait);
+   }
+   vsock->total_tx_buf += pkt_len;
+   mutex_unlock(&vsock->tx_lock);
+
+   pkt = virtio_transport_alloc_pkt(vsk, info, pkt_len,
+src_cid, src_port,
+dst_cid, dst_port);
+   if (!pkt) {
+   virtio_transport_put_credit(trans, pkt_len);
+   return -ENOMEM;
+   }
+
+   pr_debug("%s:info->pkt_len= %d\n", __func__, info->pkt_len);
+
+   /* Will be released in virtio_transport_send_pkt_work */
+   sock_hold(&trans->vsk->sk);
+   virtio_transport_inc_tx_pkt(pkt);
+
+   /* Put pkt in the virtqueue */
+   sg_init_one(&hdr, &pkt->hdr, sizeof(pkt->hdr));
+   sgs[out_sg++] = &hdr;
+   if (info->iov && info->pkt_len > 0) {
+   sg_init_one(&buf, pkt->buf, pkt->len);
+   sgs[out_sg++] = &buf;
+   }
+
+   mutex_lock(&vsock->tx_lock);

[RFC V2 6/7] VSOCK: Add Makefile and Kconfig

2014-07-04 Thread Asias He
From: Asias He 

Enable virtio-vsock and vhost-vsock.

Signed-off-by: Asias He 
---
 drivers/vhost/Kconfig   |  4 
 drivers/vhost/Kconfig.vsock |  7 +++
 drivers/vhost/Makefile  |  5 +
 net/vmw_vsock/Kconfig   | 18 ++
 net/vmw_vsock/Makefile  |  4 
 5 files changed, 38 insertions(+)
 create mode 100644 drivers/vhost/Kconfig.vsock

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 017a1e8..169fb19 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -32,3 +32,7 @@ config VHOST
---help---
  This option is selected by any driver which needs to access
  the core of vhost.
+
+if STAGING
+source "drivers/vhost/Kconfig.vsock"
+endif
diff --git a/drivers/vhost/Kconfig.vsock b/drivers/vhost/Kconfig.vsock
new file mode 100644
index 000..3491865
--- /dev/null
+++ b/drivers/vhost/Kconfig.vsock
@@ -0,0 +1,7 @@
+config VHOST_VSOCK
+   tristate "vhost virtio-vsock driver"
+   depends on VSOCKETS && EVENTFD
+   select VIRTIO_VSOCKETS_COMMON
+   default n
+   ---help---
+   Say M here to enable the vhost-vsock for virtio-vsock guests
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
index e0441c3..eccff51 100644
--- a/drivers/vhost/Makefile
+++ b/drivers/vhost/Makefile
@@ -4,5 +4,10 @@ vhost_net-y := net.o
 obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
 vhost_scsi-y := scsi.o
 
+obj-$(CONFIG_VHOST_VSOCK) += vhost_vsock.o
+vhost_vsock-y := vsock.o
+CFLAGS_vsock.o := -DDEBUG
+
 obj-$(CONFIG_VHOST_RING) += vringh.o
+
 obj-$(CONFIG_VHOST)+= vhost.o
diff --git a/net/vmw_vsock/Kconfig b/net/vmw_vsock/Kconfig
index b5fa7e4..c2b6d6f 100644
--- a/net/vmw_vsock/Kconfig
+++ b/net/vmw_vsock/Kconfig
@@ -26,3 +26,21 @@ config VMWARE_VMCI_VSOCKETS
 
  To compile this driver as a module, choose M here: the module
  will be called vmw_vsock_vmci_transport. If unsure, say N.
+
+config VIRTIO_VSOCKETS
+   tristate "virtio transport for Virtual Sockets"
+   depends on VSOCKETS && VIRTIO
+   select VIRTIO_VSOCKETS_COMMON
+   help
+ This module implements a virtio transport for Virtual Sockets.
+
+ Enable this transport if your Virtual Machine runs on Qemu/KVM.
+
+ To compile this driver as a module, choose M here: the module
+ will be called virtio_vsock_transport. If unsure, say N.
+
+config VIRTIO_VSOCKETS_COMMON
+   tristate
+   ---help---
+ This option is selected by any driver which needs to access
+ the virtio_vsock.
diff --git a/net/vmw_vsock/Makefile b/net/vmw_vsock/Makefile
index 2ce52d7..a8fea3af 100644
--- a/net/vmw_vsock/Makefile
+++ b/net/vmw_vsock/Makefile
@@ -1,5 +1,9 @@
 obj-$(CONFIG_VSOCKETS) += vsock.o
 obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o
+obj-$(CONFIG_VIRTIO_VSOCKETS) += virtio_transport.o
+obj-$(CONFIG_VIRTIO_VSOCKETS_COMMON) += virtio_transport_common.o
+CFLAGS_virtio_transport.o := -DDEBUG
+CFLAGS_virtio_transport_common.o := -DDEBUG
 
 vsock-y += af_vsock.o vsock_addr.o
 
-- 
1.9.3

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC V2 3/7] VSOCK: Introduce virtio-vsock-common.ko

2014-07-04 Thread Asias He
From: Asias He 

This module contains the common code and header files for the following
virtio-vsock and virtio-vhost kernel modules.

Signed-off-by: Asias He 
---
 include/linux/virtio_vsock.h   |  207 
 include/uapi/linux/virtio_ids.h|1 +
 .../uapi/linux/{virtio_ids.h => virtio_vsock.h}|   78 +-
 net/vmw_vsock/virtio_transport_common.c| 1220 
 4 files changed, 1485 insertions(+), 21 deletions(-)
 create mode 100644 include/linux/virtio_vsock.h
 copy include/uapi/linux/{virtio_ids.h => virtio_vsock.h} (50%)
 create mode 100644 net/vmw_vsock/virtio_transport_common.c

diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
new file mode 100644
index 000..926ebac
--- /dev/null
+++ b/include/linux/virtio_vsock.h
@@ -0,0 +1,207 @@
+/*
+ * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
+ * anyone can use the definitions to implement compatible drivers/servers:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *may be used to endorse or promote products derived from this software
+ *without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 
IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (C) Red Hat, Inc., 2013
+ * Copyright (C) Asias He , 2013
+ */
+
+#ifndef _LINUX_VIRTIO_VSOCK_H
+#define _LINUX_VIRTIO_VSOCK_H
+
+#include 
+#include 
+#include 
+
+#define VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE  128
+#define VIRTIO_VSOCK_DEFAULT_BUF_SIZE  (1024 * 256)
+#define VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE  (1024 * 256)
+#define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE   (1024 * 4)
+#define VIRTIO_VSOCK_MAX_BUF_SIZE  0xUL
+#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE  (1024 * 64)
+#define VIRTIO_VSOCK_MAX_TX_BUF_SIZE   (1024 * 1024 * 16)
+#define VIRTIO_VSOCK_MAX_DGRAM_SIZE(1024 * 64)
+
+struct vsock_transport_recv_notify_data;
+struct vsock_transport_send_notify_data;
+struct sockaddr_vm;
+struct vsock_sock;
+
+enum {
+   VSOCK_VQ_CTRL   = 0,
+   VSOCK_VQ_RX = 1, /* for host to guest data */
+   VSOCK_VQ_TX = 2, /* for guest to host data */
+   VSOCK_VQ_MAX= 3,
+};
+
+/* virtio transport socket state */
+struct virtio_transport {
+   struct virtio_transport_pkt_ops *ops;
+   struct vsock_sock *vsk;
+
+   u32 buf_size;
+   u32 buf_size_min;
+   u32 buf_size_max;
+
+   struct mutex tx_lock;
+   struct mutex rx_lock;
+
+   struct list_head rx_queue;
+   u32 rx_bytes;
+
+   /* Protected by trans->tx_lock */
+   u32 tx_cnt;
+   u32 buf_alloc;
+   u32 peer_fwd_cnt;
+   u32 peer_buf_alloc;
+   /* Protected by trans->rx_lock */
+   u32 fwd_cnt;
+
+   u16 dgram_id;
+};
+
+struct virtio_vsock_pkt {
+   struct virtio_vsock_hdr hdr;
+   struct virtio_transport *trans;
+   struct work_struct work;
+   struct list_head list;
+   void *buf;
+   u32 len;
+   u32 off;
+};
+
+struct virtio_vsock_pkt_info {
+   u32 remote_cid, remote_port;
+   struct iovec *iov;
+   u32 pkt_len;
+   u16 type;
+   u16 op;
+   u32 flags;
+   u16 dgram_id;
+   u16 dgram_len;
+};
+
+struct virtio_transport_pkt_ops {
+   int (*send_pkt)(struct vsock_sock *vsk,
+   struct virtio_vsock_pkt_info *info);
+};
+
+void virtio_vsock_dumppkt(const char *func,
+ const struct virtio_vsock_pkt *pkt);
+
+struct sock *
+virtio_transport_get_pending(struct sock *listener,
+struct virtio_vsock_pkt *pkt);
+struct virtio_vsock_pkt *
+virtio_transport_alloc_pkt(

[RFC V2 7/7] Disable debug

2014-07-04 Thread Asias He
From: Asias He 

Signed-off-by: Asias He 
---
 drivers/vhost/Makefile | 1 -
 net/vmw_vsock/Makefile | 2 --
 2 files changed, 3 deletions(-)

diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
index eccff51..6b012b9 100644
--- a/drivers/vhost/Makefile
+++ b/drivers/vhost/Makefile
@@ -6,7 +6,6 @@ vhost_scsi-y := scsi.o
 
 obj-$(CONFIG_VHOST_VSOCK) += vhost_vsock.o
 vhost_vsock-y := vsock.o
-CFLAGS_vsock.o := -DDEBUG
 
 obj-$(CONFIG_VHOST_RING) += vringh.o
 
diff --git a/net/vmw_vsock/Makefile b/net/vmw_vsock/Makefile
index a8fea3af..cf4c294 100644
--- a/net/vmw_vsock/Makefile
+++ b/net/vmw_vsock/Makefile
@@ -2,8 +2,6 @@ obj-$(CONFIG_VSOCKETS) += vsock.o
 obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o
 obj-$(CONFIG_VIRTIO_VSOCKETS) += virtio_transport.o
 obj-$(CONFIG_VIRTIO_VSOCKETS_COMMON) += virtio_transport_common.o
-CFLAGS_virtio_transport.o := -DDEBUG
-CFLAGS_virtio_transport_common.o := -DDEBUG
 
 vsock-y += af_vsock.o vsock_addr.o
 
-- 
1.9.3

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC V2 2/7] VSOCK: Add dgram_skb to vsock_sock

2014-07-04 Thread Asias He
From: Asias He 

Signed-off-by: Asias He 
---
 include/net/af_vsock.h   | 1 +
 net/vmw_vsock/af_vsock.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 88f559a..ef668a0 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -58,6 +58,7 @@ struct vsock_sock {
 */
struct list_head pending_links;
struct list_head accept_queue;
+   struct list_head dgram_skb;
bool rejected;
struct delayed_work dwork;
u32 peer_shutdown;
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 9b48d4e..df8781c 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -684,6 +684,7 @@ struct sock *__vsock_create(struct net *net,
vsk->listener = NULL;
INIT_LIST_HEAD(&vsk->pending_links);
INIT_LIST_HEAD(&vsk->accept_queue);
+   INIT_LIST_HEAD(&vsk->dgram_skb);
vsk->rejected = false;
vsk->sent_request = false;
vsk->ignore_connecting_rst = false;
-- 
1.9.3

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC V2 1/7] VSOCK: Introduce vsock_find_unbound_socket and vsock_bind_dgram_generic

2014-07-04 Thread Asias He
From: Asias He 

Signed-off-by: Asias He 
---
 include/net/af_vsock.h   |  2 ++
 net/vmw_vsock/af_vsock.c | 70 
 2 files changed, 72 insertions(+)

diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 7d64d36..88f559a 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -168,8 +168,10 @@ void vsock_insert_connected(struct vsock_sock *vsk);
 void vsock_remove_bound(struct vsock_sock *vsk);
 void vsock_remove_connected(struct vsock_sock *vsk);
 struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr);
+struct sock *vsock_find_unbound_socket(struct sockaddr_vm *addr);
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
 struct sockaddr_vm *dst);
 void vsock_for_each_connected_socket(void (*fn)(struct sock *sk));
+int vsock_bind_dgram_generic(struct vsock_sock *vsk, struct sockaddr_vm *addr);
 
 #endif /* __AF_VSOCK_H__ */
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 545c08b..9b48d4e 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -224,6 +224,17 @@ static struct sock *__vsock_find_bound_socket(struct 
sockaddr_vm *addr)
return NULL;
 }
 
+static struct sock *__vsock_find_unbound_socket(struct sockaddr_vm *addr)
+{
+   struct vsock_sock *vsk;
+
+   list_for_each_entry(vsk, vsock_unbound_sockets, bound_table)
+   if (addr->svm_port == vsk->local_addr.svm_port)
+   return sk_vsock(vsk);
+
+   return NULL;
+}
+
 static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src,
  struct sockaddr_vm *dst)
 {
@@ -299,6 +310,21 @@ struct sock *vsock_find_bound_socket(struct sockaddr_vm 
*addr)
 }
 EXPORT_SYMBOL_GPL(vsock_find_bound_socket);
 
+struct sock *vsock_find_unbound_socket(struct sockaddr_vm *addr)
+{
+   struct sock *sk;
+
+   spin_lock_bh(&vsock_table_lock);
+   sk = __vsock_find_unbound_socket(addr);
+   if (sk)
+   sock_hold(sk);
+
+   spin_unlock_bh(&vsock_table_lock);
+
+   return sk;
+}
+EXPORT_SYMBOL_GPL(vsock_find_unbound_socket);
+
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
 struct sockaddr_vm *dst)
 {
@@ -533,6 +559,50 @@ static int __vsock_bind_stream(struct vsock_sock *vsk,
return 0;
 }
 
+int vsock_bind_dgram_generic(struct vsock_sock *vsk, struct sockaddr_vm *addr)
+{
+   static u32 port = LAST_RESERVED_PORT + 1;
+   struct sockaddr_vm new_addr;
+
+   vsock_addr_init(&new_addr, addr->svm_cid, addr->svm_port);
+
+   if (addr->svm_port == VMADDR_PORT_ANY) {
+   bool found = false;
+   unsigned int i;
+
+   for (i = 0; i < MAX_PORT_RETRIES; i++) {
+   if (port <= LAST_RESERVED_PORT)
+   port = LAST_RESERVED_PORT + 1;
+
+   new_addr.svm_port = port++;
+
+   if (!__vsock_find_unbound_socket(&new_addr)) {
+   found = true;
+   break;
+   }
+   }
+
+   if (!found)
+   return -EADDRNOTAVAIL;
+   } else {
+   /* If port is in reserved range, ensure caller
+* has necessary privileges.
+*/
+   if (addr->svm_port <= LAST_RESERVED_PORT &&
+   !capable(CAP_NET_BIND_SERVICE)) {
+   return -EACCES;
+   }
+
+   if (__vsock_find_unbound_socket(&new_addr))
+   return -EADDRINUSE;
+   }
+
+   vsock_addr_init(&vsk->local_addr, new_addr.svm_cid, new_addr.svm_port);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vsock_bind_dgram_generic);
+
 static int __vsock_bind_dgram(struct vsock_sock *vsk,
  struct sockaddr_vm *addr)
 {
-- 
1.9.3

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC V2 0/7] Introduce VM Sockets virtio transport

2014-07-04 Thread Asias He
 is not defined.
  
  When op is VIRTIO_VSOCK_OP_SHUTDOWN, flags specifies the shutdown mode when 
the
  socket is being shutdown. 1 is for receive shutdown, 2 is for transmit
  shutdown, 3 is for both receive and transmit shutdown.

fwd_cnt: specifies the the number of bytes the receiver has forwarded to
userspace.

buf_alloc: specifies the size of the receiver's recieve buffer in bytes.

Virtio VM socket connection creation:
1) Client sends VIRTIO_VSOCK_OP_REQUEST to server
2) Server responses with VIRTIO_VSOCK_OP_RESPONSE to client
3) Client responses with VIRTIO_VSOCK_OP_ATTACH to server

Virtio VM socket credit update:
Virtio VM socket uses credit-based flow control. The sender maintains tx_cnt
which counts the totoal number of bytes it has sent out, peer_fwd_cnt which
counts the totoal number of byes the receiver has forwarded, and peer_buf_alloc
which is the size of the receiver's receive buffer. The sender can send no more
than the credit the receiver gives to the sender: credit = peer_buf_alloc -
(tx_cnt - peer_fwd_cnt). The receiver can send VIRTIO_VSOCK_OP_CREDIT packet to
tell sender its current fwd_cnt and buf_alloc value explicitly. However, as an
optimization, the fwd_cnt and buf_alloc is always included in the packet header
virtio_vsock_hdr.

Virtio VM socket syn cookie:
When a server receives a VIRTIO_VSOCK_OP_REQUEST pkt from client, it does not
allocate the resouces immediately. It calculates a secret cookie and sends a
VIRTIO_VSOCK_OP_RESPONSE pkt to client. When a client receives a
VIRTIO_VSOCK_OP_RESPONSE pkt, it sends a VIRTIO_VSOCK_OP_ACK pkt to server.
When the server receives the VIRTIO_VSOCK_OP_ACK pkt, it checks the cookie to
make sure the cookie is sent by the server. If the check is passed, the
connection is created. If the check is not passed, the pkt is dropped and no
connection is created.

Virtio VM socket SOCK_DGRAM frgamentation:
The maximum datagram supported is 64KB. The maximum rx buffer is 4KB. If a
datagram is larger than the maximum rx buffer, the datagram is fragmented into
multiple small 4KB pkt.

The guest driver should make the receive virtqueue as fully populated as
possible: if it runs out, the performance will suffer.

The controlq is used to control device. Currently, no control operation is
defined.

Asias He (7):
  VSOCK: Introduce vsock_find_unbound_socket and
vsock_bind_dgram_generic
  VSOCK: Add dgram_skb to vsock_sock
  VSOCK: Introduce virtio-vsock-common.ko
  VSOCK: Introduce virtio-vsock.ko
  VSOCK: Introduce vhost-vsock.ko
  VSOCK: Add Makefile and Kconfig
  Disable debug

 drivers/vhost/Kconfig  |4 +
 drivers/vhost/Kconfig.vsock|7 +
 drivers/vhost/Makefile |4 +
 drivers/vhost/vsock.c  |  572 +
 drivers/vhost/vsock.h  |4 +
 include/linux/virtio_vsock.h   |  207 
 include/net/af_vsock.h |3 +
 include/uapi/linux/virtio_ids.h|1 +
 .../uapi/linux/{virtio_ids.h => virtio_vsock.h}|   78 +-
 net/vmw_vsock/Kconfig  |   18 +
 net/vmw_vsock/Makefile |2 +
 net/vmw_vsock/af_vsock.c   |   71 ++
 net/vmw_vsock/virtio_transport.c   |  448 +++
 net/vmw_vsock/virtio_transport_common.c| 1220 
 14 files changed, 2618 insertions(+), 21 deletions(-)
 create mode 100644 drivers/vhost/Kconfig.vsock
 create mode 100644 drivers/vhost/vsock.c
 create mode 100644 drivers/vhost/vsock.h
 create mode 100644 include/linux/virtio_vsock.h
 copy include/uapi/linux/{virtio_ids.h => virtio_vsock.h} (50%)
 create mode 100644 net/vmw_vsock/virtio_transport.c
 create mode 100644 net/vmw_vsock/virtio_transport_common.c

-- 
1.9.3

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] virtio-scsi: Fix hotcpu_notifier use-after-free with virtscsi_freeze

2013-10-28 Thread Asias He
vqs are freed in virtscsi_freeze but the hotcpu_notifier is not
unregistered. We will have a use-after-free usage when the notifier
callback is called after virtscsi_freeze.

Signed-off-by: Asias He 
---
 drivers/scsi/virtio_scsi.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 74b88ef..b26f1a5 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -957,6 +957,10 @@ static void virtscsi_remove(struct virtio_device *vdev)
 #ifdef CONFIG_PM
 static int virtscsi_freeze(struct virtio_device *vdev)
 {
+   struct Scsi_Host *sh = virtio_scsi_host(vdev);
+   struct virtio_scsi *vscsi = shost_priv(sh);
+
+   unregister_hotcpu_notifier(&vscsi->nb);
virtscsi_remove_vqs(vdev);
return 0;
 }
@@ -965,8 +969,17 @@ static int virtscsi_restore(struct virtio_device *vdev)
 {
struct Scsi_Host *sh = virtio_scsi_host(vdev);
struct virtio_scsi *vscsi = shost_priv(sh);
+   int err;
+
+   err = virtscsi_init(vdev, vscsi);
+   if (err)
+   return err;
+
+   err = register_hotcpu_notifier(&vscsi->nb);
+   if (err)
+   vdev->config->del_vqs(vdev);
 
-   return virtscsi_init(vdev, vscsi);
+   return err;
 }
 #endif
 
-- 
1.8.3.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost/scsi: Fix incorrect usage of get_user_pages_fast write parameter

2013-10-27 Thread Asias He
On Fri, Oct 25, 2013 at 06:07:16PM +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger 
> 
> This patch addresses a long-standing bug where the get_user_pages_fast()
> write parameter used for setting the underlying page table entry permission
> bits was incorrectly set to write=1 for data_direction=DMA_TO_DEVICE, and
> passed into get_user_pages_fast() via vhost_scsi_map_iov_to_sgl().
> 
> However, this parameter is intended to signal WRITEs to pinned userspace
> PTEs for the virtio-scsi DMA_FROM_DEVICE -> READ payload case, and *not*
> for the virtio-scsi DMA_TO_DEVICE -> WRITE payload case.
> 
> This bug would manifest itself as random process segmentation faults on
> KVM host after repeated vhost starts + stops and/or with lots of vhost
> endpoints + LUNs.
> 
> Cc: Stefan Hajnoczi 
> Cc: Michael S. Tsirkin 
> Cc: Asias He 
> Cc:  # 3.6+
> Signed-off-by: Nicholas Bellinger 

Reviewed-by: Asias He 

> ---
>  drivers/vhost/scsi.c |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> index ce5221f..e663921 100644
> --- a/drivers/vhost/scsi.c
> +++ b/drivers/vhost/scsi.c
> @@ -1056,7 +1056,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
> vhost_virtqueue *vq)
>   if (data_direction != DMA_NONE) {
>   ret = vhost_scsi_map_iov_to_sgl(cmd,
>   &vq->iov[data_first], data_num,
> - data_direction == DMA_TO_DEVICE);
> + data_direction == DMA_FROM_DEVICE);
>   if (unlikely(ret)) {
>   vq_err(vq, "Failed to map iov to sgl\n");
>   goto err_free;
> -- 
> 1.7.2.5
> 

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost/scsi: use vmalloc for order-10 allocation

2013-09-17 Thread Asias He
On Tue, Sep 17, 2013 at 10:21:07AM +0300, Michael S. Tsirkin wrote:
> As vhost scsi device struct is large, if the device is
> created on a busy system, kzalloc() might fail, so this patch does a
> fallback to vzalloc().
> 
> As vmalloc() adds overhead on data-path, add __GFP_REPEAT
> to kzalloc() flags to do this fallback only when really needed.
> 
> Reported-by: Dan Aloni 
> Signed-off-by: Michael S. Tsirkin 

Reviewed-by: Asias He 

> ---
> 
> I put this on my vhost fixes branch, intend to merge for 3.12.
> Dan, could you please confirm this works for you?
> 
>  drivers/vhost/scsi.c | 41 +++--
>  1 file changed, 27 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> index 4b79a1f..2c30bb0 100644
> --- a/drivers/vhost/scsi.c
> +++ b/drivers/vhost/scsi.c
> @@ -1373,21 +1373,30 @@ static int vhost_scsi_set_features(struct vhost_scsi 
> *vs, u64 features)
>   return 0;
>  }
>  
> +static void vhost_scsi_free(struct vhost_scsi *vs)
> +{
> +if (is_vmalloc_addr(vs))
> +vfree(vs);
> +else
> +kfree(vs);
> +}
> +
>  static int vhost_scsi_open(struct inode *inode, struct file *f)
>  {
>   struct vhost_scsi *vs;
>   struct vhost_virtqueue **vqs;
> - int r, i;
> + int r = -ENOMEM, i;
>  
> - vs = kzalloc(sizeof(*vs), GFP_KERNEL);
> - if (!vs)
> - return -ENOMEM;
> +vs = kzalloc(sizeof(*vs), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
> + if (!vs) {
> + vs = vzalloc(sizeof(*vs));
> + if (!vs)
> + goto err_vs;
> + }
>  
>   vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL);
> - if (!vqs) {
> - kfree(vs);
> - return -ENOMEM;
> - }
> + if (!vqs)
> + goto err_vqs;
>  
>   vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work);
>   vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work);
> @@ -1407,14 +1416,18 @@ static int vhost_scsi_open(struct inode *inode, 
> struct file *f)
>  
>   tcm_vhost_init_inflight(vs, NULL);
>  
> - if (r < 0) {
> - kfree(vqs);
> - kfree(vs);
> - return r;
> - }
> + if (r < 0)
> + goto err_init;
>  
>   f->private_data = vs;
>   return 0;
> +
> +err_init:
> + kfree(vqs);
> +err_vqs:
> + vhost_scsi_free(vs);
> +err_vs:
> + return r;
>  }
>  
>  static int vhost_scsi_release(struct inode *inode, struct file *f)
> @@ -1431,7 +1444,7 @@ static int vhost_scsi_release(struct inode *inode, 
> struct file *f)
>   /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
>   vhost_scsi_flush(vs);
>   kfree(vs->dev.vqs);
> - kfree(vs);
> + vhost_scsi_free(vs);
>   return 0;
>  }
>  
> -- 
> MST

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2] vhost: Include linux/uio.h instead of linux/socket.h

2013-08-18 Thread Asias He
memcpy_fromiovec is moved from net/core/iovec.c to lib/iovec.c.
linux/uio.h provides the declaration for memcpy_fromiovec.

Include linux/uio.h instead of inux/socket.h for it.

Signed-off-by: Asias He 
---
 drivers/vhost/vhost.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index e58cf00..448efe0 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -13,7 +13,7 @@
 
 #include 
 #include 
-#include  /* memcpy_fromiovec */
+#include 
 #include 
 #include 
 #include 
-- 
1.8.3.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost: Drop linux/socket.h

2013-08-16 Thread Asias He
On Fri, Aug 16, 2013 at 12:31:59AM -0700, David Miller wrote:
> From: Asias He 
> Date: Fri, 16 Aug 2013 09:27:43 +0800
> 
> > On Thu, Aug 15, 2013 at 02:07:40PM -0700, David Miller wrote:
> >> From: Asias He 
> >> Date: Thu, 15 Aug 2013 11:20:16 +0800
> >> 
> >> > memcpy_fromiovec is moved to lib/iovec.c. No need to include
> >> > linux/socket.h for it.
> >> > 
> >> > Signed-off-by: Asias He 
> >> 
> >> You can't do this.
> >> 
> >> Because this file doesn't include the header file that
> >> provides the declaration, which is linux/uio.h
> > 
> > vhost.c includes drivers/vhost/vhost.h. In drivers/vhost/vhost.h, we
> > have linux/uio.h included.
> 
> Nothing in vhost.h needs linux/uio.h right?  That's very poor style,
> include the header where the dependency exists which is vhost.c

We use 'struct iovec' in vhost.h which needs linux/uio.h, no?

So, how about including linux/uio.h in both vhost.c and vhost.h.

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost: Drop linux/socket.h

2013-08-15 Thread Asias He
On Thu, Aug 15, 2013 at 02:07:40PM -0700, David Miller wrote:
> From: Asias He 
> Date: Thu, 15 Aug 2013 11:20:16 +0800
> 
> > memcpy_fromiovec is moved to lib/iovec.c. No need to include
> > linux/socket.h for it.
> > 
> > Signed-off-by: Asias He 
> 
> You can't do this.
> 
> Because this file doesn't include the header file that
> provides the declaration, which is linux/uio.h

vhost.c includes drivers/vhost/vhost.h. In drivers/vhost/vhost.h, we
have linux/uio.h included.

> linux/socket.h includes linux/uio.h, so honestly leaving
> things the way they are is a 1000 times better than your
> patch.

Vhost is a separate module and a generic infrastructure which is not
bound to network anymore. I guess it's better to include the real one
instead of the socket one.

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] vhost: Drop linux/socket.h

2013-08-14 Thread Asias He
memcpy_fromiovec is moved to lib/iovec.c. No need to include
linux/socket.h for it.

Signed-off-by: Asias He 
---
 drivers/vhost/vhost.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index e58cf00..038c242 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -13,7 +13,6 @@
 
 #include 
 #include 
-#include  /* memcpy_fromiovec */
 #include 
 #include 
 #include 
-- 
1.8.3.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/5] Enable Drivers for Intel MIC X100 Coprocessors.

2013-08-01 Thread Asias He
Hello Sudeep Dutt,

On Wed, Jul 31, 2013 at 06:46:08PM -0700, Greg Kroah-Hartman wrote:
> On Wed, Jul 24, 2013 at 08:31:31PM -0700, Sudeep Dutt wrote:
> > An Intel MIC X100 device is a PCIe form factor add-in coprocessor
> > card based on the Intel Many Integrated Core (MIC) architecture
> > that runs a Linux OS. It is a PCIe endpoint in a platform and therefore
> > implements the three required standard address spaces i.e. configuration,
> > memory and I/O. The host OS loads a device driver as is typical for
> > PCIe devices. The card itself runs a bootstrap after reset that
> > transfers control to the card OS downloaded from the host driver.
> > The card OS as shipped by Intel is a Linux kernel with modifications
> > for the X100 devices.
> > 
> > Since it is a PCIe card, it does not have the ability to host hardware
> > devices for networking, storage and console. We provide these devices
> > on X100 coprocessors thus enabling a self-bootable equivalent environment
> > for applications. A key benefit of our solution is that it leverages
> > the standard virtio framework for network, disk and console devices,
> > though in our case the virtio framework is used across a PCIe bus.
> > 
> > Here is a block diagram of the various components described above. The
> > virtio backends are situated on the host rather than the card given better
> > single threaded performance for the host compared to MIC and the ability of
> > the host to initiate DMA's to/from the card using the MIC DMA engine.
> > 
> >   |
> >+--+   | +--+
> >| Card OS  |   | | Host OS  |
> >+--+   | +--+
> >   |
> > +---+ ++ +--+ | +-+  ++ ++
> > | Virtio| |Virtio  | |Virtio| | |Virtio   |  |Virtio  | |Virtio  |
> > | Net   | |Console | |Block | | |Net  |  |Console | |Block   |
> > | Driver| |Driver  | |Driver| | |backend  |  |backend | |backend |
> > +---+ ++ +--+ | +-+  ++ ++
> > | | | |  || |
> > | | | |Ring 3|| |
> > | | | |--||-|---
> > +---+ |Ring 0+--+
> >   |   |  | Virtio over PCIe IOCTLs  |
> >   |   |  +--+
> >   +--+|   |
> >   |Intel MIC ||+---+
> >   |Card Driver   |||Intel MIC  |
> >   +--+||Host Driver|
> >   |   |+---+
> >   |   |   |
> >  +-+
> >  | |
> >  |PCIe Bus |
> >  +-+


Could you send the whole series to virtualization@lists.linux-foundation.org 
next time?


> That's some nice information, why isn't it in one of the patches you
> sent, so that others can read it later on to try to figure out what is
> going on with this codebase?
> 
> thanks,
> 
> greg k-h
> ___
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] virtio-scsi: Fix virtqueue affinity setup

2013-07-31 Thread Asias He
vscsi->num_queues counts the number of request virtqueue which does not
include the control and event virtqueue. It is wrong to subtract
VIRTIO_SCSI_VQ_BASE from vscsi->num_queues.

This patch fixes the following panic.

(qemu) device_del scsi0

 BUG: unable to handle kernel NULL pointer dereference at 0020
 IP: [] __virtscsi_set_affinity+0x6f/0x120
 PGD 0
 Oops:  [#1] SMP
 Modules linked in:
 CPU: 0 PID: 659 Comm: kworker/0:1 Not tainted 3.11.0-rc2+ #1172
 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
 Workqueue: kacpi_hotplug _handle_hotplug_event_func
 task: 88007bee1cc0 ti: 88007bfe4000 task.ti: 88007bfe4000
 RIP: 0010:[]  [] 
__virtscsi_set_affinity+0x6f/0x120
 RSP: 0018:88007bfe5a38  EFLAGS: 00010202
 RAX: 0010 RBX: 880077fd0d28 RCX: 0050
 RDX:  RSI: 0246 RDI: 
 RBP: 88007bfe5a58 R08: 880077f6ff00 R09: 0001
 R10: 8143e673 R11: 0001 R12: 0001
 R13: 880077fd0800 R14:  R15: 88007bf489b0
 FS:  () GS:88007ea0() knlGS:
 CS:  0010 DS:  ES:  CR0: 8005003b
 CR2: 0020 CR3: 79f8b000 CR4: 06f0
 Stack:
  880077fd0d28  880077fd0800 0008
  88007bfe5a78 8179b37d 88007bccc800 88007bccc800
  88007bfe5a98 8179b3b6 88007bccc800 880077fd0d28
 Call Trace:
  [] virtscsi_set_affinity+0x2d/0x40
  [] virtscsi_remove_vqs+0x26/0x50
  [] virtscsi_remove+0x82/0xa0
  [] virtio_dev_remove+0x22/0x70
  [] __device_release_driver+0x69/0xd0
  [] device_release_driver+0x2d/0x40
  [] bus_remove_device+0x116/0x150
  [] device_del+0x126/0x1e0
  [] device_unregister+0x16/0x30
  [] unregister_virtio_device+0x19/0x30
  [] virtio_pci_remove+0x36/0x80
  [] pci_device_remove+0x37/0x70
  [] __device_release_driver+0x69/0xd0
  [] device_release_driver+0x2d/0x40
  [] bus_remove_device+0x116/0x150
  [] device_del+0x126/0x1e0
  [] pci_stop_bus_device+0x9c/0xb0
  [] pci_stop_and_remove_bus_device+0x16/0x30
  [] acpiphp_disable_slot+0x8e/0x150
  [] hotplug_event_func+0xba/0x1a0
  [] ? acpi_os_release_object+0xe/0x12
  [] _handle_hotplug_event_func+0x31/0x70
  [] process_one_work+0x183/0x500
  [] worker_thread+0x122/0x400
  [] ? manage_workers+0x2d0/0x2d0
  [] kthread+0xce/0xe0
  [] ? kthread_freezable_should_stop+0x70/0x70
  [] ret_from_fork+0x7c/0xb0
  [] ? kthread_freezable_should_stop+0x70/0x70
 Code: 01 00 00 00 74 59 45 31 e4 83 bb c8 01 00 00 02 74 46 66 2e 0f 1f 84 00 
00 00 00 00 49 63 c4 48 c1 e0 04 48 8b bc 0
3 10 02 00 00 <48> 8b 47 20 48 8b 80 d0 01 00 00 48 8b 40 50 48 85 c0 74 07 be
 RIP  [] __virtscsi_set_affinity+0x6f/0x120
  RSP 
 CR2: 0020
 ---[ end trace 99679331a3775f48 ]---

CC: sta...@vger.kernel.org
Signed-off-by: Asias He 
---
 drivers/scsi/virtio_scsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 2168258..74b88ef 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -751,7 +751,7 @@ static void __virtscsi_set_affinity(struct virtio_scsi 
*vscsi, bool affinity)
 
vscsi->affinity_hint_set = true;
} else {
-   for (i = 0; i < vscsi->num_queues - VIRTIO_SCSI_VQ_BASE; i++)
+   for (i = 0; i < vscsi->num_queues; i++)
virtqueue_set_affinity(vscsi->req_vqs[i].vq, -1);
 
vscsi->affinity_hint_set = false;
-- 
1.8.3.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 2/2] virtio_net: fix race in RX VQ processing

2013-07-09 Thread Asias He
On Tue, Jul 09, 2013 at 11:28:34AM +0800, Jason Wang wrote:
> On 07/08/2013 05:04 PM, Michael S. Tsirkin wrote:
> > virtio net called virtqueue_enable_cq on RX path after napi_complete, so
> > with NAPI_STATE_SCHED clear - outside the implicit napi lock.
> > This violates the requirement to synchronize virtqueue_enable_cq wrt
> > virtqueue_add_buf.  In particular, used event can move backwards,
> > causing us to lose interrupts.
> > In a debug build, this can trigger panic within START_USE.
> >
> > Jason Wang reports that he can trigger the races artificially,
> > by adding udelay() in virtqueue_enable_cb() after virtio_mb().
> >
> > However, we must call napi_complete to clear NAPI_STATE_SCHED before
> > polling the virtqueue for used buffers, otherwise napi_schedule_prep in
> > a callback will fail, causing us to lose RX events.
> >
> > To fix, call virtqueue_enable_cb_prepare with NAPI_STATE_SCHED
> > set (under napi lock), later call virtqueue_poll with
> > NAPI_STATE_SCHED clear (outside the lock).
> >
> > Reported-by: Jason Wang 
> > Signed-off-by: Michael S. Tsirkin 

Acked-by: Asias He 

> > ---
> 
> Tested-by: Jason Wang 
> Acked-by: Jason Wang 
> >  drivers/net/virtio_net.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 5305bd1..fbdd79a 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -622,8 +622,9 @@ again:
> >  
> > /* Out of packets? */
> > if (received < budget) {
> > +   unsigned r = virtqueue_enable_cb_prepare(rq->vq);
> > napi_complete(napi);
> > -   if (unlikely(!virtqueue_enable_cb(rq->vq)) &&
> > +   if (unlikely(virtqueue_poll(rq->vq, r)) &&
> > napi_schedule_prep(napi)) {
> > virtqueue_disable_cb(rq->vq);
> > __napi_schedule(napi);
> 
> ___
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 1/2] virtio: support unlocked queue poll

2013-07-09 Thread Asias He
On Mon, Jul 08, 2013 at 12:04:36PM +0300, Michael S. Tsirkin wrote:
> This adds a way to check ring empty state after enable_cb outside any
> locks. Will be used by virtio_net.
> 
> Note: there's room for more optimization: caller is likely to have a
> memory barrier already, which means we might be able to get rid of a
> barrier here.  Deferring this optimization until we do some
> benchmarking.
> 
> Signed-off-by: Michael S. Tsirkin 

Acked-by: Asias He 

> ---
>  drivers/virtio/virtio_ring.c | 56 
> ++--
>  include/linux/virtio.h   |  4 
>  2 files changed, 48 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index 5217baf..37d58f8 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -607,19 +607,21 @@ void virtqueue_disable_cb(struct virtqueue *_vq)
>  EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
>  
>  /**
> - * virtqueue_enable_cb - restart callbacks after disable_cb.
> + * virtqueue_enable_cb_prepare - restart callbacks after disable_cb
>   * @vq: the struct virtqueue we're talking about.
>   *
> - * This re-enables callbacks; it returns "false" if there are pending
> - * buffers in the queue, to detect a possible race between the driver
> - * checking for more work, and enabling callbacks.
> + * This re-enables callbacks; it returns current queue state
> + * in an opaque unsigned value. This value should be later tested by
> + * virtqueue_poll, to detect a possible race between the driver checking for
> + * more work, and enabling callbacks.
>   *
>   * Caller must ensure we don't call this with other virtqueue
>   * operations at the same time (except where noted).
>   */
> -bool virtqueue_enable_cb(struct virtqueue *_vq)
> +unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
>  {
>   struct vring_virtqueue *vq = to_vvq(_vq);
> + u16 last_used_idx;
>  
>   START_USE(vq);
>  
> @@ -629,15 +631,45 @@ bool virtqueue_enable_cb(struct virtqueue *_vq)
>* either clear the flags bit or point the event index at the next
>* entry. Always do both to keep code simple. */
>   vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
> - vring_used_event(&vq->vring) = vq->last_used_idx;
> + vring_used_event(&vq->vring) = last_used_idx = vq->last_used_idx;
> + END_USE(vq);
> + return last_used_idx;
> +}
> +EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare);
> +
> +/**
> + * virtqueue_poll - query pending used buffers
> + * @vq: the struct virtqueue we're talking about.
> + * @last_used_idx: virtqueue state (from call to 
> virtqueue_enable_cb_prepare).
> + *
> + * Returns "true" if there are pending used buffers in the queue.
> + *
> + * This does not need to be serialized.
> + */
> +bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx)
> +{
> + struct vring_virtqueue *vq = to_vvq(_vq);
> +
>   virtio_mb(vq->weak_barriers);
> - if (unlikely(more_used(vq))) {
> - END_USE(vq);
> - return false;
> - }
> + return (u16)last_used_idx != vq->vring.used->idx;
> +}
> +EXPORT_SYMBOL_GPL(virtqueue_poll);
>  
> - END_USE(vq);
> - return true;
> +/**
> + * virtqueue_enable_cb - restart callbacks after disable_cb.
> + * @vq: the struct virtqueue we're talking about.
> + *
> + * This re-enables callbacks; it returns "false" if there are pending
> + * buffers in the queue, to detect a possible race between the driver
> + * checking for more work, and enabling callbacks.
> + *
> + * Caller must ensure we don't call this with other virtqueue
> + * operations at the same time (except where noted).
> + */
> +bool virtqueue_enable_cb(struct virtqueue *_vq)
> +{
> + unsigned last_used_idx = virtqueue_enable_cb_prepare(_vq);
> + return !virtqueue_poll(_vq, last_used_idx);
>  }
>  EXPORT_SYMBOL_GPL(virtqueue_enable_cb);
>  
> diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> index 9ff8645..72398ee 100644
> --- a/include/linux/virtio.h
> +++ b/include/linux/virtio.h
> @@ -70,6 +70,10 @@ void virtqueue_disable_cb(struct virtqueue *vq);
>  
>  bool virtqueue_enable_cb(struct virtqueue *vq);
>  
> +unsigned virtqueue_enable_cb_prepare(struct virtqueue *vq);
> +
> +bool virtqueue_poll(struct virtqueue *vq, unsigned);
> +
>  bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
>  
>  void *virtqueue_detach_unused_buf(struct virtqueue *vq);
> -- 
> MST
> 
> ___
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2 03/11] vhost: Make vhost a separate module

2013-07-09 Thread Asias He
On Sun, Jul 07, 2013 at 05:40:51PM +0300, Michael S. Tsirkin wrote:
> On Sun, Jul 07, 2013 at 02:37:10PM +0300, Michael S. Tsirkin wrote:
> > On Mon, May 06, 2013 at 08:10:03PM +0800, Asias He wrote:
> > > On Mon, May 06, 2013 at 01:03:42PM +0300, Michael S. Tsirkin wrote:
> > > > On Mon, May 06, 2013 at 04:38:21PM +0800, Asias He wrote:
> > > > > Currently, vhost-net and vhost-scsi are sharing the vhost core code.
> > > > > However, vhost-scsi shares the code by including the vhost.c file
> > > > > directly.
> > > > > 
> > > > > Making vhost a separate module makes it is easier to share code with
> > > > > other vhost devices.
> > > > > 
> > > > > Signed-off-by: Asias He 
> > > > 
> > > > Also this will break test.c, right? Let's fix it in the same
> > > > commit too.
> > > 
> > > I will fix it up and remove the useless 'return'.
> > 
> > Don't see v3 anywhere?

The fix for vhost/test.c was inflight, see '[PATCH v2] vhost-test: Make
vhost/test.c work'.

> I did these tweaks, you can see the result on the vhost
> branch in my tree.

Thanks! /me just come back from vacation.

> > > > > ---
> > > > >  drivers/vhost/Kconfig  |  8 
> > > > >  drivers/vhost/Makefile |  3 ++-
> > > > >  drivers/vhost/scsi.c   |  1 -
> > > > >  drivers/vhost/vhost.c  | 51 
> > > > > +-
> > > > >  drivers/vhost/vhost.h  |  2 ++
> > > > >  5 files changed, 62 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> > > > > index 8b9226d..017a1e8 100644
> > > > > --- a/drivers/vhost/Kconfig
> > > > > +++ b/drivers/vhost/Kconfig
> > > > > @@ -1,6 +1,7 @@
> > > > >  config VHOST_NET
> > > > >   tristate "Host kernel accelerator for virtio net"
> > > > >   depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || 
> > > > > !MACVTAP)
> > > > > + select VHOST
> > > > >   select VHOST_RING
> > > > >   ---help---
> > > > > This kernel module can be loaded in host kernel to accelerate
> > > > > @@ -13,6 +14,7 @@ config VHOST_NET
> > > > >  config VHOST_SCSI
> > > > >   tristate "VHOST_SCSI TCM fabric driver"
> > > > >   depends on TARGET_CORE && EVENTFD && m
> > > > > + select VHOST
> > > > >   select VHOST_RING
> > > > >   default n
> > > > >   ---help---
> > > > > @@ -24,3 +26,9 @@ config VHOST_RING
> > > > >   ---help---
> > > > > This option is selected by any driver which needs to access
> > > > > the host side of a virtio ring.
> > > > > +
> > > > > +config VHOST
> > > > > + tristate
> > > > > + ---help---
> > > > > +   This option is selected by any driver which needs to access
> > > > > +   the core of vhost.
> > > > > diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
> > > > > index 654e9afb..e0441c3 100644
> > > > > --- a/drivers/vhost/Makefile
> > > > > +++ b/drivers/vhost/Makefile
> > > > > @@ -1,7 +1,8 @@
> > > > >  obj-$(CONFIG_VHOST_NET) += vhost_net.o
> > > > > -vhost_net-y := vhost.o net.o
> > > > > +vhost_net-y := net.o
> > > > >  
> > > > >  obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
> > > > >  vhost_scsi-y := scsi.o
> > > > >  
> > > > >  obj-$(CONFIG_VHOST_RING) += vringh.o
> > > > > +obj-$(CONFIG_VHOST)  += vhost.o
> > > > > diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> > > > > index 5179f7a..2dcb94a 100644
> > > > > --- a/drivers/vhost/scsi.c
> > > > > +++ b/drivers/vhost/scsi.c
> > > > > @@ -49,7 +49,6 @@
> > > > >  #include 
> > > > >  #include 
> > > > >  
> > > > > -#include "vhost.c"
> > > > >  #include "vhost.h"
> > > > >  
> > > > >  #define TCM_VHOST_VERSI

Re: [PATCH net] virtio-net: fix the race between channels setting and refill

2013-07-03 Thread Asias He
On Wed, Jul 03, 2013 at 08:15:52PM +0800, Jason Wang wrote:
> Commit 55257d72bd1c51f25106350f4983ec19f62ed1fa (virtio-net: fill only rx 
> queues
> which are being used) tries to refill on demand when changing the number of
> channels by call try_refill_recv() directly, this may race:
> 
> - the refill work who may do the refill in the same time
> - the try_refill_recv() called in bh since napi was not disabled
> 
> Which may led guest complain during setting channels:
> 
> virtio_net virtio0: input.1:id 0 is not a head!
> 
> Solve this issue by scheduling a refill work which can guarantee the
> serialization of refill.
> 
> Cc: Sasha Levin 
> Cc: Rusty Russell 
> Cc: Michael S. Tsirkin 
> Signed-off-by: Jason Wang 

Reviewed-by: Asias He 

> ---
>  drivers/net/virtio_net.c |5 +
>  1 files changed, 1 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index c9e0038..47b4882 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -901,7 +901,6 @@ static int virtnet_set_queues(struct virtnet_info *vi, 
> u16 queue_pairs)
>   struct scatterlist sg;
>   struct virtio_net_ctrl_mq s;
>   struct net_device *dev = vi->dev;
> - int i;
>  
>   if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
>   return 0;
> @@ -915,10 +914,8 @@ static int virtnet_set_queues(struct virtnet_info *vi, 
> u16 queue_pairs)
>queue_pairs);
>   return -EINVAL;
>   } else {
> - for (i = vi->curr_queue_pairs; i < queue_pairs; i++)
> - if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
> - schedule_delayed_work(&vi->refill, 0);
>   vi->curr_queue_pairs = queue_pairs;
> + schedule_delayed_work(&vi->refill, 0);
>   }

Also, this is not on the data path, it is simpler this way.

>  
>   return 0;
> -- 
> 1.7.1
> 
> ___
> Virtualization mailing list
> Virtualization@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [RFC 2/5] VSOCK: Introduce virtio-vsock-common.ko

2013-06-29 Thread Asias He
Hi David,

On Fri, Jun 28, 2013 at 09:32:25PM -0700, David Miller wrote:
> From: Asias He 
> Date: Thu, 27 Jun 2013 16:00:01 +0800
> 
> > +static void
> > +virtio_transport_recv_dgram(struct sock *sk,
> > +   struct virtio_vsock_pkt *pkt)
>  ...
> > +   memcpy(skb->data, pkt, sizeof(*pkt));
> > +   memcpy(skb->data + sizeof(*pkt), pkt->buf, pkt->len);
> 
> Are you sure this is right?
> 
> Shouldn't you be using "sizeof(struct virtio_vsock_hdr)" instead of
> "sizeof(*pkt)".  'pkt' is "struct virtio_vsock_pkt" and has all kinds
> of meta-data you probably don't mean to include in the SKB.

Right, virtio_vsock_hdr is enough. Will fix this.

Thanks for looking at this. 

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [RFC 4/5] VSOCK: Introduce vhost-vsock.ko

2013-06-27 Thread Asias He
On Thu, Jun 27, 2013 at 01:42:46PM +0300, Michael S. Tsirkin wrote:
> On Thu, Jun 27, 2013 at 04:00:03PM +0800, Asias He wrote:
> > VM sockets vhost transport implementation. This module runs in host
> > kernel.
> > 
> > Signed-off-by: Asias He 
> 
> Has any thought been given to how this affects migration?
> I don't see any API for an application to
> move to a different host and reconnect to a running
> vsock in guest.
> 
> I think we could merge without this, there are more
> pressing issues, but it's probably a requirement
> if you want this to replace e.g. serial in many
> scenarious.

I do not plan to support migration for the initial merge as well.

Reconnection is one issue needs to be addressed. Another issue is that if
the destination host is running vhost-vsock already, the port might be
used already. We probably need namesapce support.

> > ---
> >  drivers/vhost/vsock.c | 534 
> > ++
> >  drivers/vhost/vsock.h |   4 +
> >  2 files changed, 538 insertions(+)
> >  create mode 100644 drivers/vhost/vsock.c
> >  create mode 100644 drivers/vhost/vsock.h
> > 
> > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> > new file mode 100644
> > index 000..cb54090
> > --- /dev/null
> > +++ b/drivers/vhost/vsock.c
> > @@ -0,0 +1,534 @@
> > +/*
> > + * vhost transport for vsock
> > + *
> > + * Copyright (C) 2013 Red Hat, Inc.
> > + * Author: Asias He 
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2.
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "../../../net/vmw_vsock/af_vsock.h"
> 
> Send patch to move this to include/linux ?

Okay. Will cook a patch.

> > +#include "vhost.h"
> > +#include "vsock.h"
> > +
> > +#define VHOST_VSOCK_DEFAULT_HOST_CID   2;
> 
> Sure you want that ; there? This can result in strange code, e.g.
> 
>   int a = VHOST_VSOCK_DEFAULT_HOST_CID + 1;
>   set's a to 2.

Fixed.

> > +
> > +static int vhost_transport_socket_init(struct vsock_sock *vsk,
> > +  struct vsock_sock *psk);
> > +
> > +enum {
> > +   VHOST_VSOCK_FEATURES = VHOST_FEATURES,
> > +};
> > +
> > +/* Used to track all the vhost_vsock instacne on the system. */
> 
> typo

Fixed.

> > +static LIST_HEAD(vhost_vsock_list);
> > +static DEFINE_MUTEX(vhost_vsock_mutex);
> > +
> > +struct vhost_vsock_virtqueue {
> > +   struct vhost_virtqueue vq;
> > +};
> > +
> > +struct vhost_vsock {
> > +   /* Vhost device */
> > +   struct vhost_dev dev;
> > +   /* Vhost vsock virtqueue*/
> > +   struct vhost_vsock_virtqueue vqs[VSOCK_VQ_MAX];
> > +   /* Link to global vhost_vsock_list*/
> > +   struct list_head list;
> > +   /* Head for pkt from host to guest */
> > +   struct list_head send_pkt_list;
> > +   /* Work item to send pkt */
> > +   struct vhost_work send_pkt_work;
> > +   /* Guest contex id this vhost_vsock instance handles */
> > +   u32 guest_cid;
> > +};
> > +
> > +static u32 vhost_transport_get_local_cid(void)
> > +{
> > +   u32 cid = VHOST_VSOCK_DEFAULT_HOST_CID;
> > +   return cid;
> > +}
> > +
> 
> Interesting. So all hosts in fact have the same CID?

Yes. Andy commented on this already.

> > +static struct vhost_vsock *vhost_vsock_get(u32 guest_cid)
> > +{
> > +   struct vhost_vsock *vsock;
> > +
> > +   mutex_lock(&vhost_vsock_mutex);
> > +   list_for_each_entry(vsock, &vhost_vsock_list, list) {
> > +   if (vsock->guest_cid == guest_cid) {
> > +   mutex_unlock(&vhost_vsock_mutex);
> > +   return vsock;
> > +   }
> > +   }
> > +   mutex_unlock(&vhost_vsock_mutex);
> > +
> > +   return NULL;
> > +}
> > +
> > +static void
> > +vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
> > +   struct vhost_virtqueue *vq)
> > +{
> > +   struct virtio_vsock_pkt *pkt;
> > +   unsigned out, in;
> > +   struct sock *sk;
> > +   int head, ret;
> > +
> > +   mutex_lock(&vq->mutex);
> > +   vhost_disable_notify(&vsock->dev, vq);
> > +   for (;;) {
> > +   if (list_empty(&vsock->send_pkt_list)) {
> > +   vhost_enable_notify(&vsock->dev, vq);
> > +   

Re: [RFC 2/5] VSOCK: Introduce virtio-vsock-common.ko

2013-06-27 Thread Asias He
On Thu, Jun 27, 2013 at 01:34:30PM +0300, Michael S. Tsirkin wrote:
> On Thu, Jun 27, 2013 at 04:00:01PM +0800, Asias He wrote:
> > This module contains the common code and header files for the following
> > virtio-vsock and virtio-vhost kernel modules.
> > 
> > Signed-off-by: Asias He 
> > ---
> >  include/linux/virtio_vsock.h| 200 +++
> >  include/uapi/linux/virtio_ids.h |   1 +
> >  include/uapi/linux/virtio_vsock.h   |  70 +++
> >  net/vmw_vsock/virtio_transport_common.c | 992 
> > 
> >  4 files changed, 1263 insertions(+)
> >  create mode 100644 include/linux/virtio_vsock.h
> >  create mode 100644 include/uapi/linux/virtio_vsock.h
> >  create mode 100644 net/vmw_vsock/virtio_transport_common.c
> > 
> > diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
> > new file mode 100644
> > index 000..cd8ed95
> > --- /dev/null
> > +++ b/include/linux/virtio_vsock.h
> > @@ -0,0 +1,200 @@
> > +/*
> > + * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
> > + * anyone can use the definitions to implement compatible drivers/servers:
> > + *
> > + *
> > + * Redistribution and use in source and binary forms, with or without
> > + * modification, are permitted provided that the following conditions
> > + * are met:
> > + * 1. Redistributions of source code must retain the above copyright
> > + *notice, this list of conditions and the following disclaimer.
> > + * 2. Redistributions in binary form must reproduce the above copyright
> > + *notice, this list of conditions and the following disclaimer in the
> > + *documentation and/or other materials provided with the distribution.
> > + * 3. Neither the name of IBM nor the names of its contributors
> > + *may be used to endorse or promote products derived from this software
> > + *without specific prior written permission.
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
> > ``AS IS''
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
> > THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
> > PURPOSE
> > + * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
> > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
> > CONSEQUENTIAL
> > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
> > STRICT
> > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 
> > WAY
> > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> > + * SUCH DAMAGE.
> > + *
> > + * Copyright (C) Red Hat, Inc., 2013
> > + * Copyright (C) Asias He , 2013
> > + */
> > +
> > +#ifndef _LINUX_VIRTIO_VSOCK_H
> > +#define _LINUX_VIRTIO_VSOCK_H
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE  128
> > +#define VIRTIO_VSOCK_DEFAULT_BUF_SIZE  (1024 * 256)
> > +#define VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE  (1024 * 256)
> > +#define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE   (1024 * 4)
> > +#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE  (1024 * 64)
> > +
> > +struct vsock_transport_recv_notify_data;
> > +struct vsock_transport_send_notify_data;
> > +struct sockaddr_vm;
> > +struct vsock_sock;
> > +
> > +enum {
> > +   VSOCK_VQ_CTRL   = 0,
> > +   VSOCK_VQ_RX = 1, /* for host to guest data */
> > +   VSOCK_VQ_TX = 2, /* for guest to host data */
> > +   VSOCK_VQ_MAX= 3,
> > +};
> > +
> > +/* virtio transport socket state */
> > +struct virtio_transport {
> > +   struct virtio_transport_pkt_ops *ops;
> > +   struct vsock_sock *vsk;
> > +
> > +   u64 buf_size;
> > +   u64 buf_size_min;
> > +   u64 buf_size_max;
> > +
> > +   struct mutex tx_lock;
> > +   struct mutex rx_lock;
> > +
> > +   struct list_head rx_queue;
> > +   u64 rx_bytes;
> > +
> > +   /* Protected by trans->tx_lock */
> > +   u64 tx_cnt;
> > +   u64 buf_alloc;
> > +   u64 peer_fwd_cnt;
> > +   u64 peer_buf_alloc;
> > +   /* Protected by trans->rx_lock */
> > +   u64 fwd_cnt;
> > +};
> > +
> > +struct virtio_vsock_pkt {
> > +   struct virtio_vsock_hdr hd

Re: [RFC 0/5] Introduce VM Sockets virtio transport

2013-06-27 Thread Asias He
On Thu, Jun 27, 2013 at 03:03:01PM -0400, Sasha Levin wrote:
> Hi Asias,
> 
> Looks nice! Some comments inline below (I've removed anything that mst already
> commented on).

Thanks.

> On 06/27/2013 03:59 AM, Asias He wrote:
> >Hello guys,
> >
> >In commit d021c344051af91 (VSOCK: Introduce VM Sockets), VMware added VM
> >Sockets support. VM Sockets allows communication between virtual
> >machines and the hypervisor. VM Sockets is able to use different
> >hyervisor neutral transport to transfer data. Currently, only VMware
> >VMCI transport is supported.
> >
> >This series introduces virtio transport for VM Sockets.
> >
> >Any comments are appreciated! Thanks!
> >
> >Code:
> >=
> >1) kernel bits
> >git://github.com/asias/linux.git vsock
> >
> >2) userspace bits:
> >git://github.com/asias/linux-kvm.git vsock
> >
> >Howto:
> >=
> >Make sure you have these kernel options:
> >
> >   CONFIG_VSOCKETS=y
> >   CONFIG_VIRTIO_VSOCKETS=y
> >   CONFIG_VIRTIO_VSOCKETS_COMMON=y
> >   CONFIG_VHOST_VSOCK=m
> >
> >$ git clone git://github.com/asias/linux-kvm.git
> >$ cd linux-kvm/tools/kvm
> >$ co -b vsock origin/vsock
> >$ make
> >$ modprobe vhost_vsock
> >$ ./lkvm run -d os.img -k bzImage --vsock guest_cid
> >
> >Test:
> >=
> >I hacked busybox's http server and wget to run over vsock. Start http
> >server in host and guest, download a 512MB file in guest and host
> >simultaneously for 6000 times. Manged to run the http stress test.
> >
> >Also, I wrote a small libvsock.so to play the LD_PRELOAD trick and
> >managed to make sshd and ssh work over virito-vsock without modifying
> >the source code.
> 
> Why did it require hacking in the first place? Does running with kvmtool
> and just doing regular networking over virtio-net running on top of vsock
> achieves the same goal?

VM Sockets introduces a new address family. We need to modify the source
code of the application to use the new address family.

Using vsock there is no need to use virtio-net at all. We can not run
virtio-net on top of vsock.

> >Draft VM Sockets Virtio Device spec:
> >=
> >Appendix K: VM Sockets Device
> >
> >The virtio VM sockets device is a virtio transport device for VM Sockets. VM
> >Sockets allows communication between virtual machines and the hypervisor.
> >
> >Configuration:
> >
> >Subsystem Device ID 13
> >
> >Virtqueues:
> > 0:controlq; 1:receiveq0; 2:transmitq0 ... 2N+1:receivqN; 2N+2:transmitqN
> 
> controlq is "defined but not used", is there something in mind for it? if not,
> does it make sense keeping it here? we can always re-add it to the end just
> like in virtio-net.

In virtio-net, each queue pairs contains a controlq, I think it is not
necessary for virtio-vsock. e.g.

receiveq0 transmitq0 controlq0

In virtio-scsi, we have ctrlq evetq and N requestq. I want the similar
layout here, to reserve a ctrl queue in the front.

> >Feature bits:
> > Currently, no feature bits are defined.
> >
> >Device configuration layout:
> >
> >Two configuration fields are currently defined.
> >
> >struct virtio_vsock_config {
> >__u32 guest_cid;
> >__u32 max_virtqueue_pairs;
> >} __packed;
> >
> >The guest_cid field specifies the guest context id which likes the guest IP
> >address. The max_virtqueue_pairs field specifies the maximum number of 
> >receive
> >and transmit virtqueue pairs (receiveq0 ...  receiveqN and transmitq0 ...
> >transmitqN respectively; N = max_virtqueue_pairs - 1 ) that can be 
> >configured.
> >The driver is free to use only one virtqueue pairs, or it can use more to
> >achieve better performance.
> 
> How does the driver tell the device how many vqs it's planning on actually 
> using?
> or is it assumed that all of them are in use?

I want the driver to use all of them.

> >
> >Device Initialization:
> >The initialization routine should discover the device's virtqueues.
> >
> >Device Operation:
> >Packets are transmitted by placing them in the transmitq0..transmitqN, and
> >buffers for incoming packets are placed in the receiveq0..receiveqN. In each
> >case, the packet itself is preceded by a header:
> >
> >struct virtio_vsock_hdr {
> >__u32   src_cid;
> >__u32   src_port;
> >__u32   dst_cid;
> >   

Re: [RFC 0/5] Introduce VM Sockets virtio transport

2013-06-27 Thread Asias He
On Thu, Jun 27, 2013 at 01:23:24PM +0300, Michael S. Tsirkin wrote:
> On Thu, Jun 27, 2013 at 03:59:59PM +0800, Asias He wrote:
> > Hello guys,
> > 
> > In commit d021c344051af91 (VSOCK: Introduce VM Sockets), VMware added VM
> > Sockets support. VM Sockets allows communication between virtual
> > machines and the hypervisor. VM Sockets is able to use different
> > hyervisor neutral transport to transfer data. Currently, only VMware
> > VMCI transport is supported. 
> > 
> > This series introduces virtio transport for VM Sockets.
> > 
> > Any comments are appreciated! Thanks!
> > 
> > Code:
> > =
> > 1) kernel bits
> >git://github.com/asias/linux.git vsock
> > 
> > 2) userspace bits:
> >git://github.com/asias/linux-kvm.git vsock
> > 
> > Howto:
> > =
> > Make sure you have these kernel options:
> > 
> >   CONFIG_VSOCKETS=y
> >   CONFIG_VIRTIO_VSOCKETS=y
> >   CONFIG_VIRTIO_VSOCKETS_COMMON=y
> >   CONFIG_VHOST_VSOCK=m
> > 
> > $ git clone git://github.com/asias/linux-kvm.git
> > $ cd linux-kvm/tools/kvm
> > $ co -b vsock origin/vsock
> > $ make
> > $ modprobe vhost_vsock
> > $ ./lkvm run -d os.img -k bzImage --vsock guest_cid
> > 
> > Test:
> > =
> > I hacked busybox's http server and wget to run over vsock. Start http
> > server in host and guest, download a 512MB file in guest and host
> > simultaneously for 6000 times. Manged to run the http stress test.
> > 
> > Also, I wrote a small libvsock.so to play the LD_PRELOAD trick and
> > managed to make sshd and ssh work over virito-vsock without modifying
> > the source code.
> > 
> > Draft VM Sockets Virtio Device spec:
> > =
> > Appendix K: VM Sockets Device
> > 
> > The virtio VM sockets device is a virtio transport device for VM Sockets. VM
> > Sockets allows communication between virtual machines and the hypervisor.
> > 
> > Configuration:
> > 
> > Subsystem Device ID 13
> > 
> > Virtqueues:
> > 0:controlq; 1:receiveq0; 2:transmitq0 ... 2N+1:receivqN; 2N+2:transmitqN
> > 
> > Feature bits:
> > Currently, no feature bits are defined.
> > 
> > Device configuration layout:
> > 
> > Two configuration fields are currently defined.
> > 
> >struct virtio_vsock_config {
> 
> which fields are RW,RO,WO?

All are RO.

> >__u32 guest_cid;
> 
> Given that cid is like an IP address, 32 bit seems too
> limiting. I would go for a 64 bit one or maybe even 128 bit,
> so that e.g. GUIDs can be used there.
> 
> 
> >__u32 max_virtqueue_pairs;
> 
> I'd make this little endian.

okay.

> >} __packed;
> 
> 
> > 
> > The guest_cid field specifies the guest context id which likes the guest IP
> > address. The max_virtqueue_pairs field specifies the maximum number of 
> > receive
> > and transmit virtqueue pairs (receiveq0 ...  receiveqN and transmitq0 ...
> > transmitqN respectively; N = max_virtqueue_pairs - 1 ) that can be 
> > configured.
> > The driver is free to use only one virtqueue pairs, or it can use more to
> > achieve better performance.
> 
> Don't we need a field for driver to specify the # of VQs?

To make it simple, I want to make the driver use all of the virtqueue
pairs we offered in max_virtqueue_pairs.

> I note packets have no sequence numbers.
> This means that a given stream should only use
> a single VQ in each direction, correct?
> Maybe make this explicit.

Right, let's make it explicit.

> > 
> > Device Initialization:
> > The initialization routine should discover the device's virtqueues.
> > 
> > Device Operation:
> > Packets are transmitted by placing them in the transmitq0..transmitqN, and
> > buffers for incoming packets are placed in the receiveq0..receiveqN. In each
> > case, the packet itself is preceded by a header:
> > 
> >struct virtio_vsock_hdr {
> 
> Let's make header explicitly little endian and avoid the
> heartburn we have with many other transports.

Sounds good to me.

> >__u32   src_cid;
> >__u32   src_port;
> >__u32   dst_cid;
> >__u32   dst_port;
> 
> Ports are 32 bit? I guess most applications can't work with >16 bit.
> 
> Also, why put cid's in all packets? They are only needed
> when you create a connection, no? Afterwards port numbers
> can be used.
> 
&g

Re: [RFC 0/5] Introduce VM Sockets virtio transport

2013-06-27 Thread Asias He
On Thu, Jun 27, 2013 at 07:25:40PM -0700, Andy King wrote:
> Hi Michael,
> 
> > >__u32 guest_cid;
> > 
> > Given that cid is like an IP address, 32 bit seems too
> > limiting. I would go for a 64 bit one or maybe even 128 bit,
> > so that e.g. GUIDs can be used there.
> 
> That's likely based on what vSockets uses, which is in turn based on
> what the VMCI device exposes (which is what vSockets was originally
> built on), so unfortunately it's too late to extend that type.
> However, that still allows just under 2^32 VMs per host (there are
> three reserved values).

Yes, 32 bit cid and port are defined by vSockets, we can not go for 64 bit
for virtio transport.

> > >__u32   dst_port;
> > 
> > Ports are 32 bit? I guess most applications can't work with >16 bit.
> 
> As with the cid, the width of the port type comes from vSockets,
> which is what this plugs into.

Yes.

> > Also, why put cid's in all packets? They are only needed
> > when you create a connection, no? Afterwards port numbers
> > can be used.
> 
> The cid is present in DGRAM packets and STREAM _control_ packets
> (connection handshake, signal read/write and so forth).  I don't
> think the intent here is for it to be in STREAM _data_ packets,
> but Asias can clarify.

Virtio transport stream data packets are a bit different from how VMCI transport
handles them. In VMCI, a dedicated queue pairs is created for each
stream. In virtio, all the streams share the single virtqueue pairs.

On the recv path, we need the cid and port information from the packet
header to figure out which socket is responsible for the packet.

> > > Virtio VM socket connection creation:
> > > 1) Client sends VIRTIO_VSOCK_OP_REQUEST to server
> > > 2) Server reponses with VIRTIO_VSOCK_OP_NEGOTIATE to client
> > > 3) Client sends VIRTIO_VSOCK_OP_OFFER to server
> > > 4) Server responses with VIRTIO_VSOCK_OP_ATTACH to client
> > 
> > What's the reason for a 4 stage setup? Most transports
> > make do with 3.
> 
> I'm guessing that's also based on the original vSockets/VMCI
> implementation, where the NEGOTIATE/OFFER stages are used to
> negotiate the underlying transport buffer size (in VMCI, the
> queuepair that underlies a STREAM socket).  The virtio
> transport can probably use 3.

Right, I wanted to follow how VMCI transport does the connection setup.

We can drop the IRTIO_VSOCK_OP_ATTACH stage, and make the client into
SS_CONNECTED state once we get the VIRTIO_VSOCK_OP_NEGOTIATE pkt.

> Thanks!
> - Andy

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC 5/5] VSOCK: Add Makefile and Kconfig

2013-06-27 Thread Asias He
Enable virtio-vsock and vhost-vsock.

Signed-off-by: Asias He 
---
 drivers/vhost/Kconfig   |  4 
 drivers/vhost/Kconfig.vsock |  7 +++
 drivers/vhost/Makefile  |  5 +
 net/vmw_vsock/Kconfig   | 18 ++
 net/vmw_vsock/Makefile  |  4 
 5 files changed, 38 insertions(+)
 create mode 100644 drivers/vhost/Kconfig.vsock

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 017a1e8..169fb19 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -32,3 +32,7 @@ config VHOST
---help---
  This option is selected by any driver which needs to access
  the core of vhost.
+
+if STAGING
+source "drivers/vhost/Kconfig.vsock"
+endif
diff --git a/drivers/vhost/Kconfig.vsock b/drivers/vhost/Kconfig.vsock
new file mode 100644
index 000..3491865
--- /dev/null
+++ b/drivers/vhost/Kconfig.vsock
@@ -0,0 +1,7 @@
+config VHOST_VSOCK
+   tristate "vhost virtio-vsock driver"
+   depends on VSOCKETS && EVENTFD
+   select VIRTIO_VSOCKETS_COMMON
+   default n
+   ---help---
+   Say M here to enable the vhost-vsock for virtio-vsock guests
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
index e0441c3..ddf87cb 100644
--- a/drivers/vhost/Makefile
+++ b/drivers/vhost/Makefile
@@ -4,5 +4,10 @@ vhost_net-y := net.o
 obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
 vhost_scsi-y := scsi.o
 
+obj-$(CONFIG_VHOST_VSOCK) += vhost_vsock.o
+vhost_vsock-y := vsock.o
+#CFLAGS_vsock.o := -DDEBUG
+
 obj-$(CONFIG_VHOST_RING) += vringh.o
+
 obj-$(CONFIG_VHOST)+= vhost.o
diff --git a/net/vmw_vsock/Kconfig b/net/vmw_vsock/Kconfig
index b5fa7e4..c2b6d6f 100644
--- a/net/vmw_vsock/Kconfig
+++ b/net/vmw_vsock/Kconfig
@@ -26,3 +26,21 @@ config VMWARE_VMCI_VSOCKETS
 
  To compile this driver as a module, choose M here: the module
  will be called vmw_vsock_vmci_transport. If unsure, say N.
+
+config VIRTIO_VSOCKETS
+   tristate "virtio transport for Virtual Sockets"
+   depends on VSOCKETS && VIRTIO
+   select VIRTIO_VSOCKETS_COMMON
+   help
+ This module implements a virtio transport for Virtual Sockets.
+
+ Enable this transport if your Virtual Machine runs on Qemu/KVM.
+
+ To compile this driver as a module, choose M here: the module
+ will be called virtio_vsock_transport. If unsure, say N.
+
+config VIRTIO_VSOCKETS_COMMON
+   tristate
+   ---help---
+ This option is selected by any driver which needs to access
+ the virtio_vsock.
diff --git a/net/vmw_vsock/Makefile b/net/vmw_vsock/Makefile
index 2ce52d7..bc37e59 100644
--- a/net/vmw_vsock/Makefile
+++ b/net/vmw_vsock/Makefile
@@ -1,5 +1,9 @@
 obj-$(CONFIG_VSOCKETS) += vsock.o
 obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o
+obj-$(CONFIG_VIRTIO_VSOCKETS) += virtio_transport.o
+obj-$(CONFIG_VIRTIO_VSOCKETS_COMMON) += virtio_transport_common.o
+#CFLAGS_virtio_transport.o := -DDEBUG
+#CFLAGS_virtio_transport_common.o := -DDEBUG
 
 vsock-y += af_vsock.o vsock_addr.o
 
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC 3/5] VSOCK: Introduce virtio-vsock.ko

2013-06-27 Thread Asias He
VM sockets virtio transport implementation. This module runs in guest
kernel.

Signed-off-by: Asias He 
---
 net/vmw_vsock/virtio_transport.c | 424 +++
 1 file changed, 424 insertions(+)
 create mode 100644 net/vmw_vsock/virtio_transport.c

diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
new file mode 100644
index 000..f4323aa
--- /dev/null
+++ b/net/vmw_vsock/virtio_transport.c
@@ -0,0 +1,424 @@
+/*
+ * virtio transport for vsock
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Author: Asias He 
+ *
+ * Some of the code is take from Gerd Hoffmann 's
+ * early virtio-vsock proof-of-concept bits.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "af_vsock.h"
+
+static struct workqueue_struct *virtio_vsock_workqueue;
+static struct virtio_vsock *the_virtio_vsock;
+static void virtio_vsock_rx_fill(struct virtio_vsock *vsock);
+
+struct virtio_vsock {
+   /* Virtio device */
+   struct virtio_device *vdev;
+   /* Virtio virtqueue */
+   struct virtqueue *vqs[VSOCK_VQ_MAX];
+   /* Wait queue for send pkt */
+   wait_queue_head_t queue_wait;
+   /* Work item to send pkt */
+   struct work_struct tx_work;
+   /* Work item to recv pkt */
+   struct work_struct rx_work;
+   /* Mutex to protect send pkt*/
+   struct mutex tx_lock;
+   /* Mutex to protect recv pkt*/
+   struct mutex rx_lock;
+   /* Number of recv buffers */
+   int rx_buf_nr;
+   /* Number of max recv buffers */
+   int rx_buf_max_nr;
+   /* Guest context id, just like guest ip address */
+   u32 guest_cid;
+};
+
+static struct virtio_vsock *virtio_vsock_get(void)
+{
+   return the_virtio_vsock;
+}
+
+static u32 virtio_transport_get_local_cid(void)
+{
+   struct virtio_vsock *vsock = virtio_vsock_get();
+
+   return vsock->guest_cid;
+}
+
+static int
+virtio_transport_send_pkt(struct vsock_sock *vsk,
+ struct virtio_vsock_pkt_info *info)
+{
+   u32 src_cid, src_port, dst_cid, dst_port;
+   int ret, in_sg = 0, out_sg = 0;
+   struct virtio_transport *trans;
+   struct virtio_vsock_pkt *pkt;
+   struct virtio_vsock *vsock;
+   struct scatterlist sg[2];
+   struct virtqueue *vq;
+   DEFINE_WAIT(wait);
+   u64 credit;
+
+   vsock = virtio_vsock_get();
+   if (!vsock)
+   return -ENODEV;
+
+   src_cid = virtio_transport_get_local_cid();
+   src_port = vsk->local_addr.svm_port;
+   dst_cid = vsk->remote_addr.svm_cid;
+   dst_port = vsk->remote_addr.svm_port;
+
+   trans = vsk->trans;
+   vq = vsock->vqs[VSOCK_VQ_TX];
+
+   if (info->type == SOCK_STREAM) {
+   credit = virtio_transport_get_credit(trans);
+   if (info->len > credit)
+   info->len = credit;
+   }
+   if (info->len > VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE)
+   info->len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
+   /* Do not send zero length OP_RW pkt*/
+   if (info->len == 0 && info->op == VIRTIO_VSOCK_OP_RW)
+   return info->len;
+
+   pkt = virtio_transport_alloc_pkt(vsk, info, info->len,
+src_cid, src_port,
+dst_cid, dst_port);
+   if (!pkt)
+   return -ENOMEM;
+
+   pr_debug("%s:info->len= %d\n", __func__, info->len);
+
+   /* Will be released in virtio_transport_send_pkt_work */
+   sock_hold(&trans->vsk->sk);
+   virtio_transport_inc_tx_pkt(pkt);
+
+   /* Put pkt in the virtqueue */
+   sg_init_table(sg, ARRAY_SIZE(sg));
+   sg_set_buf(&sg[out_sg++], &pkt->hdr, sizeof(pkt->hdr));
+   if (info->iov && info->len > 0)
+   sg_set_buf(&sg[out_sg++], pkt->buf, pkt->len);
+
+   mutex_lock(&vsock->tx_lock);
+   while ((ret = virtqueue_add_buf(vq, sg, out_sg, in_sg, pkt,
+   GFP_KERNEL)) < 0) {
+   prepare_to_wait_exclusive(&vsock->queue_wait, &wait,
+ TASK_UNINTERRUPTIBLE);
+
+   mutex_unlock(&vsock->tx_lock);
+   schedule();
+   mutex_lock(&vsock->tx_lock);
+
+   finish_wait(&vsock->queue_wait, &wait);
+   }
+   virtqueue_kick(vq);
+   mutex_unlock(&vsock->tx_lock);
+
+   return info->len;
+}
+
+static struct virtio_transport_pkt_ops virtio_ops = {
+   .send_pkt = virtio_transport_send_pkt,
+};
+
+static void virtio_vsock_rx_fill(struct virtio_vsock *vsock)
+{
+   int buf_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
+   struc

[RFC 4/5] VSOCK: Introduce vhost-vsock.ko

2013-06-27 Thread Asias He
VM sockets vhost transport implementation. This module runs in host
kernel.

Signed-off-by: Asias He 
---
 drivers/vhost/vsock.c | 534 ++
 drivers/vhost/vsock.h |   4 +
 2 files changed, 538 insertions(+)
 create mode 100644 drivers/vhost/vsock.c
 create mode 100644 drivers/vhost/vsock.h

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
new file mode 100644
index 000..cb54090
--- /dev/null
+++ b/drivers/vhost/vsock.c
@@ -0,0 +1,534 @@
+/*
+ * vhost transport for vsock
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Author: Asias He 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../../../net/vmw_vsock/af_vsock.h"
+#include "vhost.h"
+#include "vsock.h"
+
+#define VHOST_VSOCK_DEFAULT_HOST_CID   2;
+
+static int vhost_transport_socket_init(struct vsock_sock *vsk,
+  struct vsock_sock *psk);
+
+enum {
+   VHOST_VSOCK_FEATURES = VHOST_FEATURES,
+};
+
+/* Used to track all the vhost_vsock instacne on the system. */
+static LIST_HEAD(vhost_vsock_list);
+static DEFINE_MUTEX(vhost_vsock_mutex);
+
+struct vhost_vsock_virtqueue {
+   struct vhost_virtqueue vq;
+};
+
+struct vhost_vsock {
+   /* Vhost device */
+   struct vhost_dev dev;
+   /* Vhost vsock virtqueue*/
+   struct vhost_vsock_virtqueue vqs[VSOCK_VQ_MAX];
+   /* Link to global vhost_vsock_list*/
+   struct list_head list;
+   /* Head for pkt from host to guest */
+   struct list_head send_pkt_list;
+   /* Work item to send pkt */
+   struct vhost_work send_pkt_work;
+   /* Guest contex id this vhost_vsock instance handles */
+   u32 guest_cid;
+};
+
+static u32 vhost_transport_get_local_cid(void)
+{
+   u32 cid = VHOST_VSOCK_DEFAULT_HOST_CID;
+   return cid;
+}
+
+static struct vhost_vsock *vhost_vsock_get(u32 guest_cid)
+{
+   struct vhost_vsock *vsock;
+
+   mutex_lock(&vhost_vsock_mutex);
+   list_for_each_entry(vsock, &vhost_vsock_list, list) {
+   if (vsock->guest_cid == guest_cid) {
+   mutex_unlock(&vhost_vsock_mutex);
+   return vsock;
+   }
+   }
+   mutex_unlock(&vhost_vsock_mutex);
+
+   return NULL;
+}
+
+static void
+vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
+   struct vhost_virtqueue *vq)
+{
+   struct virtio_vsock_pkt *pkt;
+   unsigned out, in;
+   struct sock *sk;
+   int head, ret;
+
+   mutex_lock(&vq->mutex);
+   vhost_disable_notify(&vsock->dev, vq);
+   for (;;) {
+   if (list_empty(&vsock->send_pkt_list)) {
+   vhost_enable_notify(&vsock->dev, vq);
+   break;
+   }
+
+   head = vhost_get_vq_desc(&vsock->dev, vq, vq->iov,
+   ARRAY_SIZE(vq->iov), &out, &in,
+   NULL, NULL);
+   pr_debug("%s: head = %d\n", __func__, head);
+   if (head < 0)
+   break;
+
+   if (head == vq->num) {
+   if (unlikely(vhost_enable_notify(&vsock->dev, vq))) {
+   vhost_disable_notify(&vsock->dev, vq);
+   continue;
+   }
+   break;
+   }
+
+   pkt = list_first_entry(&vsock->send_pkt_list,
+  struct virtio_vsock_pkt, list);
+   list_del_init(&pkt->list);
+
+   /* FIXME: no assumption of frame layout */
+   ret = __copy_to_user(vq->iov[0].iov_base, &pkt->hdr,
+sizeof(pkt->hdr));
+   if (ret) {
+   virtio_transport_free_pkt(pkt);
+   vq_err(vq, "Faulted on copying pkt hdr\n");
+   break;
+   }
+   if (pkt->buf && pkt->len > 0) {
+   ret = __copy_to_user(vq->iov[1].iov_base, pkt->buf,
+   pkt->len);
+   if (ret) {
+   virtio_transport_free_pkt(pkt);
+   vq_err(vq, "Faulted on copying pkt buf\n");
+   break;
+   }
+   }
+
+   vhost_add_used(vq, head, pkt->len);
+
+   virtio_transport_dec_tx_pkt(pkt);
+
+   sk = sk_vsock(pkt->trans->vsk);
+   /* Release refcnt taken in vhost_transport_send_pkt */
+   sock_put(sk);
+
+   virtio_transpor

[RFC 2/5] VSOCK: Introduce virtio-vsock-common.ko

2013-06-27 Thread Asias He
This module contains the common code and header files for the following
virtio-vsock and virtio-vhost kernel modules.

Signed-off-by: Asias He 
---
 include/linux/virtio_vsock.h| 200 +++
 include/uapi/linux/virtio_ids.h |   1 +
 include/uapi/linux/virtio_vsock.h   |  70 +++
 net/vmw_vsock/virtio_transport_common.c | 992 
 4 files changed, 1263 insertions(+)
 create mode 100644 include/linux/virtio_vsock.h
 create mode 100644 include/uapi/linux/virtio_vsock.h
 create mode 100644 net/vmw_vsock/virtio_transport_common.c

diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
new file mode 100644
index 000..cd8ed95
--- /dev/null
+++ b/include/linux/virtio_vsock.h
@@ -0,0 +1,200 @@
+/*
+ * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
+ * anyone can use the definitions to implement compatible drivers/servers:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *may be used to endorse or promote products derived from this software
+ *without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 
IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (C) Red Hat, Inc., 2013
+ * Copyright (C) Asias He , 2013
+ */
+
+#ifndef _LINUX_VIRTIO_VSOCK_H
+#define _LINUX_VIRTIO_VSOCK_H
+
+#include 
+#include 
+#include 
+
+#define VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE  128
+#define VIRTIO_VSOCK_DEFAULT_BUF_SIZE  (1024 * 256)
+#define VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE  (1024 * 256)
+#define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE   (1024 * 4)
+#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE  (1024 * 64)
+
+struct vsock_transport_recv_notify_data;
+struct vsock_transport_send_notify_data;
+struct sockaddr_vm;
+struct vsock_sock;
+
+enum {
+   VSOCK_VQ_CTRL   = 0,
+   VSOCK_VQ_RX = 1, /* for host to guest data */
+   VSOCK_VQ_TX = 2, /* for guest to host data */
+   VSOCK_VQ_MAX= 3,
+};
+
+/* virtio transport socket state */
+struct virtio_transport {
+   struct virtio_transport_pkt_ops *ops;
+   struct vsock_sock *vsk;
+
+   u64 buf_size;
+   u64 buf_size_min;
+   u64 buf_size_max;
+
+   struct mutex tx_lock;
+   struct mutex rx_lock;
+
+   struct list_head rx_queue;
+   u64 rx_bytes;
+
+   /* Protected by trans->tx_lock */
+   u64 tx_cnt;
+   u64 buf_alloc;
+   u64 peer_fwd_cnt;
+   u64 peer_buf_alloc;
+   /* Protected by trans->rx_lock */
+   u64 fwd_cnt;
+};
+
+struct virtio_vsock_pkt {
+   struct virtio_vsock_hdr hdr;
+   struct virtio_transport *trans;
+   struct work_struct work;
+   struct list_head list;
+   void *buf;
+   u32 len;
+   u32 off;
+};
+
+struct virtio_vsock_pkt_info {
+   struct sockaddr_vm *src;
+   struct sockaddr_vm *dst;
+   struct iovec *iov;
+   u32 len;
+   u8 type;
+   u8 op;
+   u8 shut;
+};
+
+struct virtio_transport_pkt_ops {
+   int (*send_pkt)(struct vsock_sock *vsk,
+   struct virtio_vsock_pkt_info *info);
+};
+
+void virtio_vsock_dumppkt(const char *func,
+ const struct virtio_vsock_pkt *pkt);
+
+struct sock *
+virtio_transport_get_pending(struct sock *listener,
+struct virtio_vsock_pkt *pkt);
+struct virtio_vsock_pkt *
+virtio_transport_alloc_pkt(struct vsock_sock *vsk,
+  struct virtio_vsock_pkt_info *info,
+  size_t len,
+  u32 src_cid,
+  u32 src_port,
+  u32 dst_cid,
+  u32 dst_port);
+ssize_t
+virtio_transport_stream_dequeue(struct

[RFC 1/5] VSOCK: Introduce vsock_find_unbound_socket and vsock_bind_dgram_generic

2013-06-27 Thread Asias He
Signed-off-by: Asias He 
---
 net/vmw_vsock/af_vsock.c | 70 
 net/vmw_vsock/af_vsock.h |  2 ++
 2 files changed, 72 insertions(+)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 593071d..bc76ddb 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -225,6 +225,17 @@ static struct sock *__vsock_find_bound_socket(struct 
sockaddr_vm *addr)
return NULL;
 }
 
+static struct sock *__vsock_find_unbound_socket(struct sockaddr_vm *addr)
+{
+   struct vsock_sock *vsk;
+
+   list_for_each_entry(vsk, vsock_unbound_sockets, bound_table)
+   if (addr->svm_port == vsk->local_addr.svm_port)
+   return sk_vsock(vsk);
+
+   return NULL;
+}
+
 static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src,
  struct sockaddr_vm *dst)
 {
@@ -300,6 +311,21 @@ struct sock *vsock_find_bound_socket(struct sockaddr_vm 
*addr)
 }
 EXPORT_SYMBOL_GPL(vsock_find_bound_socket);
 
+struct sock *vsock_find_unbound_socket(struct sockaddr_vm *addr)
+{
+   struct sock *sk;
+
+   spin_lock_bh(&vsock_table_lock);
+   sk = __vsock_find_unbound_socket(addr);
+   if (sk)
+   sock_hold(sk);
+
+   spin_unlock_bh(&vsock_table_lock);
+
+   return sk;
+}
+EXPORT_SYMBOL_GPL(vsock_find_unbound_socket);
+
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
 struct sockaddr_vm *dst)
 {
@@ -534,6 +560,50 @@ static int __vsock_bind_stream(struct vsock_sock *vsk,
return 0;
 }
 
+int vsock_bind_dgram_generic(struct vsock_sock *vsk, struct sockaddr_vm *addr)
+{
+   static u32 port = LAST_RESERVED_PORT + 1;
+   struct sockaddr_vm new_addr;
+
+   vsock_addr_init(&new_addr, addr->svm_cid, addr->svm_port);
+
+   if (addr->svm_port == VMADDR_PORT_ANY) {
+   bool found = false;
+   unsigned int i;
+
+   for (i = 0; i < MAX_PORT_RETRIES; i++) {
+   if (port <= LAST_RESERVED_PORT)
+   port = LAST_RESERVED_PORT + 1;
+
+   new_addr.svm_port = port++;
+
+   if (!__vsock_find_unbound_socket(&new_addr)) {
+   found = true;
+   break;
+   }
+   }
+
+   if (!found)
+   return -EADDRNOTAVAIL;
+   } else {
+   /* If port is in reserved range, ensure caller
+* has necessary privileges.
+*/
+   if (addr->svm_port <= LAST_RESERVED_PORT &&
+   !capable(CAP_NET_BIND_SERVICE)) {
+   return -EACCES;
+   }
+
+   if (__vsock_find_unbound_socket(&new_addr))
+   return -EADDRINUSE;
+   }
+
+   vsock_addr_init(&vsk->local_addr, new_addr.svm_cid, new_addr.svm_port);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vsock_bind_dgram_generic);
+
 static int __vsock_bind_dgram(struct vsock_sock *vsk,
  struct sockaddr_vm *addr)
 {
diff --git a/net/vmw_vsock/af_vsock.h b/net/vmw_vsock/af_vsock.h
index 7d64d36..88f559a 100644
--- a/net/vmw_vsock/af_vsock.h
+++ b/net/vmw_vsock/af_vsock.h
@@ -168,8 +168,10 @@ void vsock_insert_connected(struct vsock_sock *vsk);
 void vsock_remove_bound(struct vsock_sock *vsk);
 void vsock_remove_connected(struct vsock_sock *vsk);
 struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr);
+struct sock *vsock_find_unbound_socket(struct sockaddr_vm *addr);
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
 struct sockaddr_vm *dst);
 void vsock_for_each_connected_socket(void (*fn)(struct sock *sk));
+int vsock_bind_dgram_generic(struct vsock_sock *vsk, struct sockaddr_vm *addr);
 
 #endif /* __AF_VSOCK_H__ */
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[RFC 0/5] Introduce VM Sockets virtio transport

2013-06-27 Thread Asias He
rtio_vsock_hdr.

The guest driver should make the receive virtqueue as fully populated as
possible: if it runs out, the performance will suffer.

The controlq is used to control device. Currently, no control operation is
defined.

Asias He (5):
  VSOCK: Introduce vsock_find_unbound_socket and
vsock_bind_dgram_generic
  VSOCK: Introduce virtio-vsock-common.ko
  VSOCK: Introduce virtio-vsock.ko
  VSOCK: Introduce vhost-vsock.ko
  VSOCK: Add Makefile and Kconfig

 drivers/vhost/Kconfig   |   4 +
 drivers/vhost/Kconfig.vsock |   7 +
 drivers/vhost/Makefile  |   5 +
 drivers/vhost/vsock.c   | 534 +
 drivers/vhost/vsock.h   |   4 +
 include/linux/virtio_vsock.h| 200 +++
 include/uapi/linux/virtio_ids.h |   1 +
 include/uapi/linux/virtio_vsock.h   |  70 +++
 net/vmw_vsock/Kconfig   |  18 +
 net/vmw_vsock/Makefile  |   4 +
 net/vmw_vsock/af_vsock.c|  70 +++
 net/vmw_vsock/af_vsock.h|   2 +
 net/vmw_vsock/virtio_transport.c| 424 ++
 net/vmw_vsock/virtio_transport_common.c | 992 
 14 files changed, 2335 insertions(+)
 create mode 100644 drivers/vhost/Kconfig.vsock
 create mode 100644 drivers/vhost/vsock.c
 create mode 100644 drivers/vhost/vsock.h
 create mode 100644 include/linux/virtio_vsock.h
 create mode 100644 include/uapi/linux/virtio_vsock.h
 create mode 100644 net/vmw_vsock/virtio_transport.c
 create mode 100644 net/vmw_vsock/virtio_transport_common.c

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush

2013-06-21 Thread Asias He
On Thu, Jun 20, 2013 at 02:48:13PM +0300, Michael S. Tsirkin wrote:
> vhost_net_ubuf_put_and_wait has a confusing name:
> it will actually also free it's argument.
> Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01
> vhost_net_flush tries to use the argument after passing it
> to vhost_net_ubuf_put_and_wait, this results
> in use after free.
> To fix, don't free the argument in vhost_net_ubuf_put_and_wait,
> add an new API for callers that want to free ubufs.
> 
> Signed-off-by: Michael S. Tsirkin 

Acked-by: Asias He 

> ---
> 
> Dave, this is needed for stable as well, but
> the code has moved a bit since then.
> I'll post a patch tweaked to apply against 3.9 and 3.8 separately.
> 
>  drivers/vhost/net.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 5c77d6a..534adb0 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -149,6 +149,11 @@ static void vhost_net_ubuf_put_and_wait(struct 
> vhost_net_ubuf_ref *ubufs)
>  {
>   kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
>   wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
> +}
> +
> +static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref 
> *ubufs)
> +{
> + vhost_net_ubuf_put_and_wait(ubufs);
>   kfree(ubufs);
>  }
>  
> @@ -1073,7 +1078,7 @@ static long vhost_net_set_backend(struct vhost_net *n, 
> unsigned index, int fd)
>   mutex_unlock(&vq->mutex);
>  
>   if (oldubufs) {
> - vhost_net_ubuf_put_and_wait(oldubufs);
> + vhost_net_ubuf_put_wait_and_free(oldubufs);
>   mutex_lock(&vq->mutex);
>   vhost_zerocopy_signal_used(n, vq);
>   mutex_unlock(&vq->mutex);
> @@ -1091,7 +1096,7 @@ err_used:
>   vq->private_data = oldsock;
>   vhost_net_enable_vq(n, vq);
>   if (ubufs)
> - vhost_net_ubuf_put_and_wait(ubufs);
> + vhost_net_ubuf_put_wait_and_free(ubufs);
>  err_ubufs:
>   fput(sock->file);
>  err_vq:
> -- 
> MST

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-scsi: return -ENOENT when no matching tcm_vhost_tpg found

2013-05-28 Thread Asias He
On Tue, May 28, 2013 at 04:54:44PM +0800, Wenchao Xia wrote:
> ioctl for VHOST_SCSI_SET_ENDPOINT report file exist errori, when I forget
> to set it correctly in configfs, make user confused. Actually it fail
> to find a matching one, so change the error value.
> 
> Signed-off-by: Wenchao Xia 

Acked-by: Asias He 

BTW, It would be nice to print more informative info in qemu when wwpn
is not available as well.

> ---
>  drivers/vhost/scsi.c |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> index 7014202..6325b1d 100644
> --- a/drivers/vhost/scsi.c
> +++ b/drivers/vhost/scsi.c
> @@ -1219,7 +1219,7 @@ static int vhost_scsi_set_endpoint(
>   }
>   ret = 0;
>   } else {
> - ret = -EEXIST;
> + ret = -ENOENT;
>   }
>  
>   /*
> -- 
> 1.7.1
> 

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-scsi: Depend on NET for memcpy_fromiovec

2013-05-15 Thread Asias He
On Thu, May 16, 2013 at 01:04:58PM +0930, Rusty Russell wrote:
> Asias He  writes:
> > On Wed, May 15, 2013 at 02:47:53PM +0930, Rusty Russell wrote:
> >> Asias He  writes:
> >> > scsi.c includes vhost.c which uses memcpy_fromiovec.
> >> >
> >> > This patch fixes this build failure.
> >> >
> >> >From Randy Dunlap:
> >> >'''
> >> >on x86_64:
> >> >
> >> >ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
> >> >
> >> >It needs to depend on NET since net/core/ provides that function.
> >> >'''
> >> 
> >> Proper fix please.
> >
> > --verbose please ;-)
> >
> > Making VHOST_SCSI depends on NET looks weird but this is because vhost
> > core depends on it. A bunch of patches are cleaning this up. Since MST
> > wanted do the vhost.ko split up in 3.11, plus your WIP vringh work, so I
> > wanted the fix for 3.10 as minimum as possible.
> 
> If this isn't the only symbol causing the problem, then this should be
> mentioned in the changelog.  If it is, it should be fixed: we have
> plenty of time for that.
>
> Either way, your commit message or the commit itself needs to justify
> it!

memcpy_fromiovec is the only one causing the problem.

> 
> > Other users are using memcpy_fromiovec and friends outside net. It seems
> > a good idea to put it in a util library. e.g.  crypto/algif_skcipher.c
> > which also depends on NET for it.
> >
> >> Though I can't see why you thought this was a good idea.  Nonetheless, I
> >> shan't highlight why: I have far too much respect for your intellects
> >> and abilities.
> >> 
> >> No, don't thank me!
> >
> > Interesting.
> 
> Heh... I originally wrote an explanation, then found it a bit insulting:
> I knew I didn't need to tell you :)

;-)

> How's this?

Looks good and the commit log is more informative. 

The

   memcpy_toiovec
   memcpy_toiovecend
   memcpy_fromiovec
   memcpy_fromiovecend

are all not net specific. 

How about move them all to lib/ ?

Also need to make sure all the callers have uio.h included.  e.g.
drivers/dma/iovlock.c

> From: Rusty Russell 
> Subject: Hoist memcpy_fromiovec into lib/
> 
> ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
> 
> That function is only present with CONFIG_NET.  Turns out that
> crypto/algif_skcipher.c also uses that outside net, but it actually
> needs sockets anyway.
> 
> socket.h already include uio.h, so no callers need updating.
> 
> Reported-by: Randy Dunlap 
> Signed-off-by: Rusty Russell 
> 
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index 428c37a..7266775 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -305,7 +305,6 @@ struct ucred {
>  
>  extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct 
> ucred *ucred);
>  
> -extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int 
> len);
>  extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
>  int offset, int len);
>  extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
> diff --git a/include/linux/uio.h b/include/linux/uio.h
> index 629aaf5..21628d3 100644
> --- a/include/linux/uio.h
> +++ b/include/linux/uio.h
> @@ -35,4 +35,6 @@ static inline size_t iov_length(const struct iovec *iov, 
> unsigned long nr_segs)
>  }
>  
>  unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t 
> to);
> +
> +int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
>  #endif
> diff --git a/lib/Makefile b/lib/Makefile
> index e9c52e1..2377211 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -9,7 +9,7 @@ endif
>  
>  lib-y := ctype.o string.o vsprintf.o cmdline.o \
>rbtree.o radix-tree.o dump_stack.o timerqueue.o\
> -  idr.o int_sqrt.o extable.o \
> +  idr.o int_sqrt.o extable.o iovec.o \
>sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
>proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \
>is_single_threaded.o plist.o decompress.o kobject_uevent.o \
> diff --git a/lib/iovec.c b/lib/iovec.c
> new file mode 100644
> index 000..632c5ea
> --- /dev/null
> +++ b/lib/iovec.c
> @@ -0,0 +1,29 @@
> +#include 
> +#include 
> +#include 
> +
> +/*
> + *   Copy iovec to kernel. Returns -EFAULT on error.
> + *
> + *   Note: this modifies the original iovec.
> + */
> +
> +int me

Re: [PATCH] vhost-scsi: Depend on NET for memcpy_fromiovec

2013-05-15 Thread Asias He
On Thu, May 16, 2013 at 09:05:38AM +0930, Rusty Russell wrote:
> "Nicholas A. Bellinger"  writes:
> > On Wed, 2013-05-15 at 14:47 +0930, Rusty Russell wrote:
> >> Asias He  writes:
> >> > scsi.c includes vhost.c which uses memcpy_fromiovec.
> >> >
> >> > This patch fixes this build failure.
> >> >
> >> >From Randy Dunlap:
> >> >'''
> >> >on x86_64:
> >> >
> >> >ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
> >> >
> >> >It needs to depend on NET since net/core/ provides that function.
> >> >'''
> >> 
> >> Proper fix please.
> >> 
> >> Though I can't see why you thought this was a good idea.  Nonetheless, I
> >> shan't highlight why: I have far too much respect for your intellects
> >> and abilities.
> >> 
> >> No, don't thank me!
> >
> > Hi Rusty & Asias,
> >
> > I assume you mean something like the following patch to allow kbuild to
> > work when VHOST_NET + VHOST_SCSI are both enabled and sharing vhost.o,
> > yes..?
> 
> No, that's a separate issue.
> 
> memcpy_fromiovec() has nothing to do with networking: that was just the
> first user.  Note that crypto/algif_skcipher.c also uses it.  The
> obvious answer is to move it into lib/.

That's true. I also want this.

> OTOH making vhost_scsi depend on CONFIG_NET is breathtakingly lazy.  I
> expect better from experienced kernel hackers :(

But do you think moving the memcpy_fromiovec stuff is a 3.10 material?

> Rusty.

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-scsi: Depend on NET for memcpy_fromiovec

2013-05-15 Thread Asias He
On Wed, May 15, 2013 at 02:47:53PM +0930, Rusty Russell wrote:
> Asias He  writes:
> > scsi.c includes vhost.c which uses memcpy_fromiovec.
> >
> > This patch fixes this build failure.
> >
> >From Randy Dunlap:
> >'''
> >on x86_64:
> >
> >ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
> >
> >It needs to depend on NET since net/core/ provides that function.
> >'''
> 
> Proper fix please.

--verbose please ;-)

Making VHOST_SCSI depends on NET looks weird but this is because vhost
core depends on it. A bunch of patches are cleaning this up. Since MST
wanted do the vhost.ko split up in 3.11, plus your WIP vringh work, so I
wanted the fix for 3.10 as minimum as possible.

Other users are using memcpy_fromiovec and friends outside net. It seems
a good idea to put it in a util library. e.g.  crypto/algif_skcipher.c
which also depends on NET for it.

> Though I can't see why you thought this was a good idea.  Nonetheless, I
> shan't highlight why: I have far too much respect for your intellects
> and abilities.
> 
> No, don't thank me!

Interesting.

> Rusty.

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-scsi: Depend on NET for memcpy_fromiovec

2013-05-15 Thread Asias He
On Wed, May 15, 2013 at 03:37:30PM -0700, Nicholas A. Bellinger wrote:
> On Wed, 2013-05-15 at 14:47 +0930, Rusty Russell wrote:
> > Asias He  writes:
> > > scsi.c includes vhost.c which uses memcpy_fromiovec.
> > >
> > > This patch fixes this build failure.
> > >
> > >From Randy Dunlap:
> > >'''
> > >on x86_64:
> > >
> > >ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
> > >
> > >It needs to depend on NET since net/core/ provides that function.
> > >'''
> > 
> > Proper fix please.
> > 
> > Though I can't see why you thought this was a good idea.  Nonetheless, I
> > shan't highlight why: I have far too much respect for your intellects
> > and abilities.
> > 
> > No, don't thank me!
> 
> Hi Rusty & Asias,
> 
> I assume you mean something like the following patch to allow kbuild to
> work when VHOST_NET + VHOST_SCSI are both enabled and sharing vhost.o,
> yes..?
> 
> Also included is dropping the now unnecessary vhost.c include, and
> allowing vhost_work_flush() to be accessed externally as scsi.c
> currently requires.
> 
> MST, care to pick this up..?
> 
> --nab


Couple of days ago, I have separated the vhost.ko. 

'vhost: Make vhost a separate module'

http://www.spinics.net/lists/kvm/msg90825.html

MST wanted to queue it up for 3.11. 

> 
> diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> index 8b9226d..016387f 100644
> --- a/drivers/vhost/Kconfig
> +++ b/drivers/vhost/Kconfig
> @@ -1,3 +1,6 @@
> +config VHOST
> +   tristate
> +
>  config VHOST_NET
> tristate "Host kernel accelerator for virtio net"
> depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP)
> @@ -12,7 +15,7 @@ config VHOST_NET
>  
>  config VHOST_SCSI
> tristate "VHOST_SCSI TCM fabric driver"
> -   depends on TARGET_CORE && EVENTFD && m
> +   depends on NET && EVENTFD && TARGET_CORE
> select VHOST_RING
> default n
> ---help---
> diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
> index 654e9afb..e5b5f0b 100644
> --- a/drivers/vhost/Makefile
> +++ b/drivers/vhost/Makefile
> @@ -1,7 +1,9 @@
> +obj-$(CONFIG_VHOST) += vhost.o
> +
>  obj-$(CONFIG_VHOST_NET) += vhost_net.o
> -vhost_net-y := vhost.o net.o
> +vhost_net-objs := net.o
>  
>  obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
> -vhost_scsi-y := scsi.o
> +vhost_scsi-objs := scsi.o
>  
>  obj-$(CONFIG_VHOST_RING) += vringh.o
> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> index 7014202..b5836a2 100644
> --- a/drivers/vhost/scsi.c
> +++ b/drivers/vhost/scsi.c
> @@ -49,7 +49,6 @@
>  #include 
>  #include 
>  
> -#include "vhost.c"
>  #include "vhost.h"
>  
>  #define TCM_VHOST_VERSION  "v0.1"
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index beee7f5..8cd1562 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -123,7 +123,7 @@ static bool vhost_work_seq_done(struct vhost_dev *dev, 
> struct vhost_work *work,
> return left <= 0;
>  }
>  
> -static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
> +void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
>  {
> unsigned seq;
> int flushing;
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index a7ad635..50ee396 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -44,6 +44,7 @@ void vhost_poll_init(struct vhost_poll *poll, 
> vhost_work_fn_t fn,
>  unsigned long mask, struct vhost_dev *dev);
>  int vhost_poll_start(struct vhost_poll *poll, struct file *file);
>  void vhost_poll_stop(struct vhost_poll *poll);
> +void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work);
>  void vhost_poll_flush(struct vhost_poll *poll);
>  void vhost_poll_queue(struct vhost_poll *poll);
> 
> 

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-scsi: Depend on NET for memcpy_fromiovec

2013-05-14 Thread Asias He
On Tue, May 14, 2013 at 08:10:20PM -0700, Nicholas A. Bellinger wrote:
> On Wed, 2013-05-15 at 08:59 +0800, Asias He wrote:
> > scsi.c includes vhost.c which uses memcpy_fromiovec.
> > 
> > This patch fixes this build failure.
> > 
> >From Randy Dunlap:
> >'''
> >on x86_64:
> > 
> >ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
> > 
> >It needs to depend on NET since net/core/ provides that function.
> >'''
> > 
> > Reported-by: Randy Dunlap 
> > Signed-off-by: Asias He 
> 
> Hey Asias & MST,
> 
> FYI, I'll be sending a PULL request to Linus in the next couple of days
> for -rc2.
> 
> Let me know if you'd like this to be picked up.

Yes, this is 3.10 material. Sounds good to me.

> --nab
> 
> > ---
> >  drivers/vhost/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> > index 8b9226d..0403323 100644
> > --- a/drivers/vhost/Kconfig
> > +++ b/drivers/vhost/Kconfig
> > @@ -12,7 +12,7 @@ config VHOST_NET
> >  
> >  config VHOST_SCSI
> > tristate "VHOST_SCSI TCM fabric driver"
> > -   depends on TARGET_CORE && EVENTFD && m
> > +   depends on NET && TARGET_CORE && EVENTFD && m
> > select VHOST_RING
> > default n
> > ---help---
> 
> 

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] vhost-scsi: Depend on NET for memcpy_fromiovec

2013-05-14 Thread Asias He
scsi.c includes vhost.c which uses memcpy_fromiovec.

This patch fixes this build failure.

   From Randy Dunlap:
   '''
   on x86_64:

   ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!

   It needs to depend on NET since net/core/ provides that function.
   '''

Reported-by: Randy Dunlap 
Signed-off-by: Asias He 
---
 drivers/vhost/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 8b9226d..0403323 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -12,7 +12,7 @@ config VHOST_NET
 
 config VHOST_SCSI
tristate "VHOST_SCSI TCM fabric driver"
-   depends on TARGET_CORE && EVENTFD && m
+   depends on NET && TARGET_CORE && EVENTFD && m
select VHOST_RING
default n
---help---
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2] vhost-test: Make vhost/test.c work

2013-05-08 Thread Asias He
On Wed, May 08, 2013 at 10:56:19AM +0300, Michael S. Tsirkin wrote:
> On Wed, May 08, 2013 at 03:24:33PM +0800, Asias He wrote:
> > Fix it by switching to use the new device specific fields per vq
> > 
> > Signed-off-by: Asias He 
> > ---
> > 
> > This is for 3.10.
> > 
> >  drivers/vhost/test.c | 35 ---
> >  1 file changed, 24 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
> > index 1ee45bc..7b49d10 100644
> > --- a/drivers/vhost/test.c
> > +++ b/drivers/vhost/test.c
> > @@ -29,16 +29,20 @@ enum {
> > VHOST_TEST_VQ_MAX = 1,
> >  };
> >  
> > +struct vhost_test_virtqueue {
> > +   struct vhost_virtqueue vq;
> > +};
> > +
> 
> Well there are no test specific fields here,
> so this structure is not needed. Here's what I queued:

Could you push the queue to your git repo ?

> --->
> 
> vhost-test: fix up test module after API change
> 
> Recent vhost API changes broke vhost test module.
> Update it to the new APIs.
> 
> Signed-off-by: Michael S. Tsirkin 
> 
> ---
> 
> diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
> index be65414..c2c3d91 100644
> --- a/drivers/vhost/test.c
> +++ b/drivers/vhost/test.c
> @@ -38,7 +38,7 @@ 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;
> @@ -102,6 +102,7 @@ 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[VHOST_TEST_VQ_MAX];
>   int r;
>  
>   if (!n)
> @@ -109,7 +110,8 @@ static int vhost_test_open(struct inode *inode, struct 
> file *f)
>  
>   dev = &n->dev;
>   n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
> - r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX);
> + vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
> + r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
>   if (r < 0) {
>   kfree(n);
>   return r;
> @@ -140,7 +142,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)
> @@ -268,21 +270,21 @@ 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:
>   return vhost_test_reset_owner(n);
>   default:
>   mutex_lock(&n->dev.mutex);
> - r = vhost_dev_ioctl(&n->dev, ioctl, arg);
> + r = vhost_dev_ioctl(&n->dev, ioctl, argp);
>   vhost_test_flush(n);
>   mutex_unlock(&n->dev.mutex);
>   return r;

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-test: Make vhost/test.c work

2013-05-08 Thread Asias He
On Wed, May 08, 2013 at 10:59:03AM +0300, Michael S. Tsirkin wrote:
> On Wed, May 08, 2013 at 03:14:58PM +0800, Asias He wrote:
> > On Tue, May 07, 2013 at 02:22:32PM +0300, Michael S. Tsirkin wrote:
> > > On Tue, May 07, 2013 at 02:52:45PM +0800, Asias He wrote:
> > > > Fix it by:
> > > > 1) switching to use the new device specific fields per vq
> > > > 2) not including vhost.c, instead make vhost-test.ko depend on vhost.ko.
> > > 
> > > Please split this up.
> > > 1. make test work for 3.10
> > > 2. make test work for 3.11
> > > 
> > > thanks!
> > 
> > okay.
> > 
> > > > ---
> > > >  drivers/vhost/test.c | 37 +
> > > >  1 file changed, 25 insertions(+), 12 deletions(-)
> > > > 
> > > > diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
> > > > index 1ee45bc..dc526eb 100644
> > > > --- a/drivers/vhost/test.c
> > > > +++ b/drivers/vhost/test.c
> > > > @@ -18,7 +18,7 @@
> > > >  #include 
> > > >  
> > > >  #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. */
> > > > @@ -29,16 +29,20 @@ enum {
> > > > VHOST_TEST_VQ_MAX = 1,
> > > >  };
> > > >  
> > > > +struct vhost_test_virtqueue {
> > > > +   struct vhost_virtqueue vq;
> > > > +};
> > > > +
> > > 
> > > This isn't needed or useful. Drop above change pls and patch
> > > size will shrink.
> > 
> > The difference is:
> > 
> >  drivers/vhost/test.c | 23 ---
> >  1 file changed, 16 insertions(+), 7 deletions(-)
> > 
> >  drivers/vhost/test.c | 35 ---
> >  1 file changed, 24 insertions(+), 11 deletions(-)
> > 
> > which is not significant.
> 
> I did it like this:
>  test.c |   14 --
>  1 file changed, 8 insertions(+), 6 deletions(-)

The extra 8 insertions is for vqs allocation which can be dropped. 

Well, if you prefer shorter code over consistency. Go ahead.

> 
> > So, I think it is better to code the same way as we do in vhost-net and
> > vhost-scsi which makes the device specific usage more consistent.
> > 
> > > >  struct vhost_test {
> > > > struct vhost_dev dev;
> > > > -   struct vhost_virtqueue vqs[VHOST_TEST_VQ_MAX];
> > > > +   struct vhost_test_virtqueue vqs[VHOST_TEST_VQ_MAX];
> > > >  };
> > > >  
> > > >  /* Expects to be always run from workqueue - which acts as
> > > >   * 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->dev.vqs[VHOST_TEST_VQ];
> > > > unsigned out, in;
> > > > int head;
> > > > size_t len, total_len = 0;
> > > > @@ -101,15 +105,23 @@ static void handle_vq_kick(struct vhost_work 
> > > > *work)
> > > >  static int vhost_test_open(struct inode *inode, struct file *f)
> > > >  {
> > > > struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);
> > > > +   struct vhost_virtqueue **vqs;
> > > > struct vhost_dev *dev;
> > > > 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;
> > > > -   n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
> > > > -   r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX);
> > > > +   vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ].vq;
> > > > +   n->vqs[VHOST_TEST_VQ].vq.handle_kick = handle_vq_kick;
> > > > +   r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
> > > > if (r < 0) {
>

[PATCH v2] vhost-test: Make vhost/test.c work

2013-05-08 Thread Asias He
Fix it by switching to use the new device specific fields per vq

Signed-off-by: Asias He 
---

This is for 3.10.

 drivers/vhost/test.c | 35 ---
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 1ee45bc..7b49d10 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -29,16 +29,20 @@ enum {
VHOST_TEST_VQ_MAX = 1,
 };
 
+struct vhost_test_virtqueue {
+   struct vhost_virtqueue vq;
+};
+
 struct vhost_test {
struct vhost_dev dev;
-   struct vhost_virtqueue vqs[VHOST_TEST_VQ_MAX];
+   struct vhost_test_virtqueue vqs[VHOST_TEST_VQ_MAX];
 };
 
 /* Expects to be always run from workqueue - which acts as
  * 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->dev.vqs[VHOST_TEST_VQ];
unsigned out, in;
int head;
size_t len, total_len = 0;
@@ -101,15 +105,23 @@ static void handle_vq_kick(struct vhost_work *work)
 static int vhost_test_open(struct inode *inode, struct file *f)
 {
struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);
+   struct vhost_virtqueue **vqs;
struct vhost_dev *dev;
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;
-   n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
-   r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX);
+   vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ].vq;
+   n->vqs[VHOST_TEST_VQ].vq.handle_kick = handle_vq_kick;
+   r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
if (r < 0) {
kfree(n);
return r;
@@ -135,12 +147,12 @@ static void *vhost_test_stop_vq(struct vhost_test *n,
 
 static void vhost_test_stop(struct vhost_test *n, void **privatep)
 {
-   *privatep = vhost_test_stop_vq(n, n->vqs + VHOST_TEST_VQ);
+   *privatep = vhost_test_stop_vq(n, &n->vqs[VHOST_TEST_VQ].vq);
 }
 
 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].vq.poll);
 }
 
 static void vhost_test_flush(struct vhost_test *n)
@@ -159,6 +171,7 @@ static int vhost_test_release(struct inode *inode, struct 
file *f)
/* We do an extra flush before freeing memory,
 * since jobs can re-queue themselves. */
vhost_test_flush(n);
+   kfree(n->dev.vqs);
kfree(n);
return 0;
 }
@@ -179,14 +192,14 @@ static long vhost_test_run(struct vhost_test *n, int test)
 
for (index = 0; index < n->dev.nvqs; ++index) {
/* Verify that ring has been setup correctly. */
-   if (!vhost_vq_access_ok(&n->vqs[index])) {
+   if (!vhost_vq_access_ok(&n->vqs[index].vq)) {
r = -EFAULT;
goto err;
}
}
 
for (index = 0; index < n->dev.nvqs; ++index) {
-   vq = n->vqs + index;
+   vq = &n->vqs[index].vq;
mutex_lock(&vq->mutex);
priv = test ? n : NULL;
 
@@ -195,7 +208,7 @@ static long vhost_test_run(struct vhost_test *n, int test)

lockdep_is_held(&vq->mutex));
rcu_assign_pointer(vq->private_data, priv);
 
-   r = vhost_init_used(&n->vqs[index]);
+   r = vhost_init_used(&n->vqs[index].vq);
 
mutex_unlock(&vq->mutex);
 
@@ -268,14 +281,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:
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost-test: Make vhost/test.c work

2013-05-08 Thread Asias He
On Tue, May 07, 2013 at 02:22:32PM +0300, Michael S. Tsirkin wrote:
> On Tue, May 07, 2013 at 02:52:45PM +0800, Asias He wrote:
> > Fix it by:
> > 1) switching to use the new device specific fields per vq
> > 2) not including vhost.c, instead make vhost-test.ko depend on vhost.ko.
> 
> Please split this up.
> 1. make test work for 3.10
> 2. make test work for 3.11
> 
> thanks!

okay.

> > ---
> >  drivers/vhost/test.c | 37 +
> >  1 file changed, 25 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
> > index 1ee45bc..dc526eb 100644
> > --- a/drivers/vhost/test.c
> > +++ b/drivers/vhost/test.c
> > @@ -18,7 +18,7 @@
> >  #include 
> >  
> >  #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. */
> > @@ -29,16 +29,20 @@ enum {
> > VHOST_TEST_VQ_MAX = 1,
> >  };
> >  
> > +struct vhost_test_virtqueue {
> > +   struct vhost_virtqueue vq;
> > +};
> > +
> 
> This isn't needed or useful. Drop above change pls and patch
> size will shrink.

The difference is:

 drivers/vhost/test.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

 drivers/vhost/test.c | 35 ---
 1 file changed, 24 insertions(+), 11 deletions(-)

which is not significant.

So, I think it is better to code the same way as we do in vhost-net and
vhost-scsi which makes the device specific usage more consistent.

> >  struct vhost_test {
> > struct vhost_dev dev;
> > -   struct vhost_virtqueue vqs[VHOST_TEST_VQ_MAX];
> > +   struct vhost_test_virtqueue vqs[VHOST_TEST_VQ_MAX];
> >  };
> >  
> >  /* Expects to be always run from workqueue - which acts as
> >   * 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->dev.vqs[VHOST_TEST_VQ];
> > unsigned out, in;
> > int head;
> > size_t len, total_len = 0;
> > @@ -101,15 +105,23 @@ static void handle_vq_kick(struct vhost_work *work)
> >  static int vhost_test_open(struct inode *inode, struct file *f)
> >  {
> > struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);
> > +   struct vhost_virtqueue **vqs;
> > struct vhost_dev *dev;
> > 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;
> > -   n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
> > -   r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX);
> > +   vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ].vq;
> > +   n->vqs[VHOST_TEST_VQ].vq.handle_kick = handle_vq_kick;
> > +   r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
> > if (r < 0) {
> > kfree(n);
> > return r;
> > @@ -135,12 +147,12 @@ static void *vhost_test_stop_vq(struct vhost_test *n,
> >  
> >  static void vhost_test_stop(struct vhost_test *n, void **privatep)
> >  {
> > -   *privatep = vhost_test_stop_vq(n, n->vqs + VHOST_TEST_VQ);
> > +   *privatep = vhost_test_stop_vq(n, &n->vqs[VHOST_TEST_VQ].vq);
> >  }
> >  
> >  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].vq.poll);
> >  }
> >  
> >  static void vhost_test_flush(struct vhost_test *n)
> > @@ -159,6 +171,7 @@ static int vhost_test_release(struct inode *inode, 
> > struct file *f)
> > /* We do an extra flush before freeing memory,
> >  * since jobs can re-queue themselves. */
> > vhost_test_flush(n);
> > +   kfree(n->dev.vqs);
> > kfree(n);
> > return 0;
> >  }
> > @@ -179,14 +192,14 @@ static long vhost_test_run(struct vhost_test *n, int 
> > test)
> >  
> > for (index = 0; index < n->dev.nvqs; ++index) {
> > /* Verify that ring has been setup correctly. */
> > -   if (!vhost_vq_access_ok(&n->vqs[index])) {
> > +   if (!vhost_vq_access_ok(

[PATCH v2] KVM: Fix kvm_irqfd_init initialization

2013-05-07 Thread Asias He
In commit a0f155e96 'KVM: Initialize irqfd from kvm_init()', when
kvm_init() is called the second time (e.g kvm-amd.ko and kvm-intel.ko),
kvm_arch_init() will fail with -EEXIST, then kvm_irqfd_exit() will be
called on the error handling path. This way, the kvm_irqfd system will
not be ready.

This patch fix the following:

BUG: unable to handle kernel NULL pointer dereference at   (null)
IP: [] _raw_spin_lock+0xe/0x30
PGD 0
Oops: 0002 [#1] SMP
Modules linked in: vhost_net
CPU 6
Pid: 4257, comm: qemu-system-x86 Not tainted 3.9.0-rc3+ #757 Dell Inc. OptiPlex 
790/0V5HMK
RIP: 0010:[]  [] _raw_spin_lock+0xe/0x30
RSP: 0018:880221721cc8  EFLAGS: 00010046
RAX: 0100 RBX: 88022dcc003f RCX: 880221734950
RDX: 8802208f6ca8 RSI: 7fff RDI: 
RBP: 880221721cc8 R08: 0002 R09: 0002
R10: 7f7fd01087e0 R11: 0246 R12: 8802208f6ca8
R13: 0080 R14: 880223e2a900 R15: 
FS:  7f7fd38488e0() GS:88022dcc() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2:  CR3: 00022309f000 CR4: 000427e0
DR0:  DR1:  DR2: 
DR3:  DR6: 0ff0 DR7: 0400
Process qemu-system-x86 (pid: 4257, threadinfo 88022172, task 
880222bd5640)
Stack:
 880221721d08 810ac5c5 88022431dc00 0086
 0080 880223e2a900 8802208f6ca8 
 880221721d48 810ac8fe  880221734000
Call Trace:
 [] __queue_work+0x45/0x2d0
 [] queue_work_on+0x8e/0xa0
 [] queue_work+0x19/0x20
 [] irqfd_deactivate+0x4b/0x60
 [] kvm_irqfd+0x39d/0x580
 [] kvm_vm_ioctl+0x207/0x5b0
 [] ? update_curr+0xf5/0x180
 [] do_vfs_ioctl+0x98/0x550
 [] ? finish_task_switch+0x4e/0xe0
 [] ? __schedule+0x2ea/0x710
 [] sys_ioctl+0x57/0x90
 [] ? trace_hardirqs_on_thunk+0x3a/0x3c
 [] system_call_fastpath+0x16/0x1b
Code: c1 ea 08 38 c2 74 0f 66 0f 1f 44 00 00 f3 90 0f b6 03 38 c2 75 f7 48 83 
c4 08 5b c9 c3 55 48 89 e5 66 66 66 66 90 b8 00 01 00 00  66 0f c1 07 89 c2 
66 c1 ea 08 38 c2 74 0c 0f 1f 00 f3 90 0f
RIP  [] _raw_spin_lock+0xe/0x30
RSP 
CR2: 
---[ end trace 13fb1e4b6e5ab21f ]---

Signed-off-by: Asias He 
---
 virt/kvm/kvm_main.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 8fd325a..85b93d2 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3078,13 +3078,21 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned 
vcpu_align,
int r;
int cpu;
 
-   r = kvm_irqfd_init();
-   if (r)
-   goto out_irqfd;
r = kvm_arch_init(opaque);
if (r)
goto out_fail;
 
+   /*
+* kvm_arch_init makes sure there's at most one caller
+* for architectures that support multiple implementations,
+* like intel and amd on x86.
+* kvm_arch_init must be called before kvm_irqfd_init to avoid creating
+* conflicts in case kvm is already setup for another implementation.
+*/
+   r = kvm_irqfd_init();
+   if (r)
+   goto out_irqfd;
+
if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) {
r = -ENOMEM;
goto out_free_0;
@@ -3159,10 +3167,10 @@ out_free_1:
 out_free_0a:
free_cpumask_var(cpus_hardware_enabled);
 out_free_0:
-   kvm_arch_exit();
-out_fail:
kvm_irqfd_exit();
 out_irqfd:
+   kvm_arch_exit();
+out_fail:
return r;
 }
 EXPORT_SYMBOL_GPL(kvm_init);
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] KVM: Fix kvm_irqfd_init initialization

2013-05-07 Thread Asias He
On Tue, May 07, 2013 at 05:59:38PM +0300, Michael S. Tsirkin wrote:
> On Tue, May 07, 2013 at 10:54:16PM +0800, Asias He wrote:
> > In commit a0f155e96 'KVM: Initialize irqfd from kvm_init()', when
> > kvm_init() is called the second time (e.g kvm-amd.ko and kvm-intel.ko),
> > kvm_arch_init() will fail with -EEXIST,
> 
> Wow. Is this intentional?

I think it is. You can not be amd and intel at the same time ;-)

kvm_arch_init

if (kvm_x86_ops) {
printk(KERN_ERR "kvm: already loaded the other module\n");
r = -EEXIST;
goto out;
}   


> > then kvm_irqfd_exit() will be
> > called on the error handling path. This way, the kvm_irqfd system will
> > not be ready.
> > 
> > This patch fix the following:
> > 
> > BUG: unable to handle kernel NULL pointer dereference at   (null)
> > IP: [] _raw_spin_lock+0xe/0x30
> > PGD 0
> > Oops: 0002 [#1] SMP
> > Modules linked in: vhost_net
> > CPU 6
> > Pid: 4257, comm: qemu-system-x86 Not tainted 3.9.0-rc3+ #757 Dell Inc. 
> > OptiPlex 790/0V5HMK
> > RIP: 0010:[]  [] _raw_spin_lock+0xe/0x30
> > RSP: 0018:880221721cc8  EFLAGS: 00010046
> > RAX: 0100 RBX: 88022dcc003f RCX: 880221734950
> > RDX: 8802208f6ca8 RSI: 7fff RDI: 
> > RBP: 880221721cc8 R08: 0002 R09: 0002
> > R10: 7f7fd01087e0 R11: 0246 R12: 8802208f6ca8
> > R13: 0080 R14: 880223e2a900 R15: 
> > FS:  7f7fd38488e0() GS:88022dcc() knlGS:
> > CS:  0010 DS:  ES:  CR0: 80050033
> > CR2:  CR3: 00022309f000 CR4: 000427e0
> > DR0:  DR1:  DR2: 
> > DR3:  DR6: 0ff0 DR7: 0400
> > Process qemu-system-x86 (pid: 4257, threadinfo 88022172, task 
> > 880222bd5640)
> > Stack:
> >  880221721d08 810ac5c5 88022431dc00 0086
> >  0080 880223e2a900 8802208f6ca8 
> >  880221721d48 810ac8fe  880221734000
> > Call Trace:
> >  [] __queue_work+0x45/0x2d0
> >  [] queue_work_on+0x8e/0xa0
> >  [] queue_work+0x19/0x20
> >  [] irqfd_deactivate+0x4b/0x60
> >  [] kvm_irqfd+0x39d/0x580
> >  [] kvm_vm_ioctl+0x207/0x5b0
> >  [] ? update_curr+0xf5/0x180
> >  [] do_vfs_ioctl+0x98/0x550
> >  [] ? finish_task_switch+0x4e/0xe0
> >  [] ? __schedule+0x2ea/0x710
> >  [] sys_ioctl+0x57/0x90
> >  [] ? trace_hardirqs_on_thunk+0x3a/0x3c
> >  [] system_call_fastpath+0x16/0x1b
> > Code: c1 ea 08 38 c2 74 0f 66 0f 1f 44 00 00 f3 90 0f b6 03 38 c2 75 f7 48 
> > 83 c4 08 5b c9 c3 55 48 89 e5 66 66 66 66 90 b8 00 01 00 00  66 0f c1 
> > 07 89 c2 66 c1 ea 08 38 c2 74 0c 0f 1f 00 f3 90 0f
> > RIP  [] _raw_spin_lock+0xe/0x30
> > RSP 
> > CR2: 
> > ---[ end trace 13fb1e4b6e5ab21f ]---
> > 
> > Signed-off-by: Asias He 
> > ---
> >  virt/kvm/kvm_main.c | 11 ++-
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 8fd325a..3c8a992 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -3078,13 +3078,14 @@ int kvm_init(void *opaque, unsigned vcpu_size, 
> > unsigned vcpu_align,
> > int r;
> > int cpu;
> >  
> > -   r = kvm_irqfd_init();
> > -   if (r)
> > -   goto out_irqfd;
> > r = kvm_arch_init(opaque);
> > if (r)
> > goto out_fail;
> >  
> > +   r = kvm_irqfd_init();
> > +   if (r)
> > +   goto out_irqfd;
> > +
> > if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) {
> > r = -ENOMEM;
> > goto out_free_0;
> > @@ -3159,10 +3160,10 @@ out_free_1:
> >  out_free_0a:
> > free_cpumask_var(cpus_hardware_enabled);
> >  out_free_0:
> > -   kvm_arch_exit();
> > -out_fail:
> > kvm_irqfd_exit();
> >  out_irqfd:
> > +   kvm_arch_exit();
> > +out_fail:
> > return r;
> >  }
> >  EXPORT_SYMBOL_GPL(kvm_init);
> > -- 
> > 1.8.1.4

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] KVM: Fix kvm_irqfd_init initialization

2013-05-07 Thread Asias He
In commit a0f155e96 'KVM: Initialize irqfd from kvm_init()', when
kvm_init() is called the second time (e.g kvm-amd.ko and kvm-intel.ko),
kvm_arch_init() will fail with -EEXIST, then kvm_irqfd_exit() will be
called on the error handling path. This way, the kvm_irqfd system will
not be ready.

This patch fix the following:

BUG: unable to handle kernel NULL pointer dereference at   (null)
IP: [] _raw_spin_lock+0xe/0x30
PGD 0
Oops: 0002 [#1] SMP
Modules linked in: vhost_net
CPU 6
Pid: 4257, comm: qemu-system-x86 Not tainted 3.9.0-rc3+ #757 Dell Inc. OptiPlex 
790/0V5HMK
RIP: 0010:[]  [] _raw_spin_lock+0xe/0x30
RSP: 0018:880221721cc8  EFLAGS: 00010046
RAX: 0100 RBX: 88022dcc003f RCX: 880221734950
RDX: 8802208f6ca8 RSI: 7fff RDI: 
RBP: 880221721cc8 R08: 0002 R09: 0002
R10: 7f7fd01087e0 R11: 0246 R12: 8802208f6ca8
R13: 0080 R14: 880223e2a900 R15: 
FS:  7f7fd38488e0() GS:88022dcc() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2:  CR3: 00022309f000 CR4: 000427e0
DR0:  DR1:  DR2: 
DR3:  DR6: 0ff0 DR7: 0400
Process qemu-system-x86 (pid: 4257, threadinfo 88022172, task 
880222bd5640)
Stack:
 880221721d08 810ac5c5 88022431dc00 0086
 0080 880223e2a900 8802208f6ca8 
 880221721d48 810ac8fe  880221734000
Call Trace:
 [] __queue_work+0x45/0x2d0
 [] queue_work_on+0x8e/0xa0
 [] queue_work+0x19/0x20
 [] irqfd_deactivate+0x4b/0x60
 [] kvm_irqfd+0x39d/0x580
 [] kvm_vm_ioctl+0x207/0x5b0
 [] ? update_curr+0xf5/0x180
 [] do_vfs_ioctl+0x98/0x550
 [] ? finish_task_switch+0x4e/0xe0
 [] ? __schedule+0x2ea/0x710
 [] sys_ioctl+0x57/0x90
 [] ? trace_hardirqs_on_thunk+0x3a/0x3c
 [] system_call_fastpath+0x16/0x1b
Code: c1 ea 08 38 c2 74 0f 66 0f 1f 44 00 00 f3 90 0f b6 03 38 c2 75 f7 48 83 
c4 08 5b c9 c3 55 48 89 e5 66 66 66 66 90 b8 00 01 00 00  66 0f c1 07 89 c2 
66 c1 ea 08 38 c2 74 0c 0f 1f 00 f3 90 0f
RIP  [] _raw_spin_lock+0xe/0x30
RSP 
CR2: 
---[ end trace 13fb1e4b6e5ab21f ]---

Signed-off-by: Asias He 
---
 virt/kvm/kvm_main.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 8fd325a..3c8a992 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3078,13 +3078,14 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned 
vcpu_align,
int r;
int cpu;
 
-   r = kvm_irqfd_init();
-   if (r)
-   goto out_irqfd;
r = kvm_arch_init(opaque);
if (r)
goto out_fail;
 
+   r = kvm_irqfd_init();
+   if (r)
+   goto out_irqfd;
+
if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) {
r = -ENOMEM;
goto out_free_0;
@@ -3159,10 +3160,10 @@ out_free_1:
 out_free_0a:
free_cpumask_var(cpus_hardware_enabled);
 out_free_0:
-   kvm_arch_exit();
-out_fail:
kvm_irqfd_exit();
 out_irqfd:
+   kvm_arch_exit();
+out_fail:
return r;
 }
 EXPORT_SYMBOL_GPL(kvm_init);
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 4/4] vhost: Remove custom vhost rcu usage

2013-05-06 Thread Asias He
Now, vq->private_data is always accessed under vq mutex. No need to play
the vhost rcu trick.

Signed-off-by: Asias He 
---
 drivers/vhost/net.c   | 16 ++--
 drivers/vhost/scsi.c  |  6 ++
 drivers/vhost/test.c  | 11 ---
 drivers/vhost/vhost.h | 10 ++
 4 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index b616d9a..05bdc3c 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -751,8 +750,7 @@ static int vhost_net_enable_vq(struct vhost_net *n,
struct vhost_poll *poll = n->poll + (nvq - n->vqs);
struct socket *sock;
 
-   sock = rcu_dereference_protected(vq->private_data,
-lockdep_is_held(&vq->mutex));
+   sock = vq->private_data;
if (!sock)
return 0;
 
@@ -765,10 +763,9 @@ static struct socket *vhost_net_stop_vq(struct vhost_net 
*n,
struct socket *sock;
 
mutex_lock(&vq->mutex);
-   sock = rcu_dereference_protected(vq->private_data,
-lockdep_is_held(&vq->mutex));
+   sock = vq->private_data;
vhost_net_disable_vq(n, vq);
-   rcu_assign_pointer(vq->private_data, NULL);
+   vq->private_data = NULL;
mutex_unlock(&vq->mutex);
return sock;
 }
@@ -924,8 +921,7 @@ static long vhost_net_set_backend(struct vhost_net *n, 
unsigned index, int fd)
}
 
/* start polling new socket */
-   oldsock = rcu_dereference_protected(vq->private_data,
-   lockdep_is_held(&vq->mutex));
+   oldsock = vq->private_data;
if (sock != oldsock) {
ubufs = vhost_net_ubuf_alloc(vq,
 sock && vhost_sock_zcopy(sock));
@@ -935,7 +931,7 @@ static long vhost_net_set_backend(struct vhost_net *n, 
unsigned index, int fd)
}
 
vhost_net_disable_vq(n, vq);
-   rcu_assign_pointer(vq->private_data, sock);
+   vq->private_data = sock;
r = vhost_init_used(vq);
if (r)
goto err_used;
@@ -969,7 +965,7 @@ static long vhost_net_set_backend(struct vhost_net *n, 
unsigned index, int fd)
return 0;
 
 err_used:
-   rcu_assign_pointer(vq->private_data, oldsock);
+   vq->private_data = oldsock;
vhost_net_enable_vq(n, vq);
if (ubufs)
vhost_net_ubuf_put_and_wait(ubufs);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d78768b..de6d817 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1223,9 +1223,8 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
   sizeof(vs->vs_vhost_wwpn));
for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
vq = &vs->vqs[i].vq;
-   /* Flushing the vhost_work acts as synchronize_rcu */
mutex_lock(&vq->mutex);
-   rcu_assign_pointer(vq->private_data, vs_tpg);
+   vq->private_data = vs_tpg;
vhost_init_used(vq);
mutex_unlock(&vq->mutex);
}
@@ -1304,9 +1303,8 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
if (match) {
for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
vq = &vs->vqs[i].vq;
-   /* Flushing the vhost_work acts as synchronize_rcu */
mutex_lock(&vq->mutex);
-   rcu_assign_pointer(vq->private_data, NULL);
+   vq->private_data = NULL;
mutex_unlock(&vq->mutex);
}
}
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 435b911..5f23477 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -13,7 +13,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -139,9 +138,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;
 }
@@ -205,9 +203,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

[PATCH 3/4] vhost-scsi: Always access vq->private_data under vq mutex

2013-05-06 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 5531ebc..d78768b 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -896,19 +896,15 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
int head, ret;
u8 target;
 
+   mutex_lock(&vq->mutex);
/*
 * We can handle the vq only after the endpoint is setup by calling the
 * VHOST_SCSI_SET_ENDPOINT ioctl.
-*
-* TODO: Check that we are running from vhost_worker which acts
-* as read-side critical section for vhost kind of RCU.
-* See the comments in struct vhost_virtqueue in drivers/vhost/vhost.h
 */
-   vs_tpg = rcu_dereference_check(vq->private_data, 1);
+   vs_tpg = vq->private_data;
if (!vs_tpg)
-   return;
+   goto out;
 
-   mutex_lock(&vq->mutex);
vhost_disable_notify(&vs->dev, vq);
 
for (;;) {
@@ -1058,6 +1054,7 @@ err_free:
vhost_scsi_free_cmd(cmd);
 err_cmd:
vhost_scsi_send_bad_target(vs, vq, head, out);
+out:
mutex_unlock(&vq->mutex);
 }
 
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 2/4] vhost-test: Always access vq->private_data under vq mutex

2013-05-06 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/test.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index dc526eb..435b911 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -48,11 +48,12 @@ static void handle_vq(struct vhost_test *n)
size_t len, total_len = 0;
void *private;
 
-   private = rcu_dereference_check(vq->private_data, 1);
-   if (!private)
-   return;
 
mutex_lock(&vq->mutex);
+   private = vq->private_data;
+   if (!private)
+   goto out;
+
vhost_disable_notify(&n->dev, vq);
 
for (;;) {
@@ -89,7 +90,7 @@ static void handle_vq(struct vhost_test *n)
break;
}
}
-
+out:
mutex_unlock(&vq->mutex);
 }
 
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 1/4] vhost-net: Always access vq->private_data under vq mutex

2013-05-06 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/net.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 2b51e23..b616d9a 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -349,12 +349,11 @@ static void handle_tx(struct vhost_net *net)
struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
bool zcopy, zcopy_used;
 
-   /* TODO: check that we are running from vhost_worker? */
-   sock = rcu_dereference_check(vq->private_data, 1);
+   mutex_lock(&vq->mutex);
+   sock = vq->private_data;
if (!sock)
-   return;
+   goto out;
 
-   mutex_lock(&vq->mutex);
vhost_disable_notify(&net->dev, vq);
 
hdr_size = nvq->vhost_hlen;
@@ -463,7 +462,7 @@ static void handle_tx(struct vhost_net *net)
break;
}
}
-
+out:
mutex_unlock(&vq->mutex);
 }
 
@@ -572,14 +571,14 @@ static void handle_rx(struct vhost_net *net)
s16 headcount;
size_t vhost_hlen, sock_hlen;
size_t vhost_len, sock_len;
-   /* TODO: check that we are running from vhost_worker? */
-   struct socket *sock = rcu_dereference_check(vq->private_data, 1);
-
-   if (!sock)
-   return;
+   struct socket *sock;
 
mutex_lock(&vq->mutex);
+   sock = vq->private_data;
+   if (!sock)
+   goto out;
vhost_disable_notify(&net->dev, vq);
+
vhost_hlen = nvq->vhost_hlen;
sock_hlen = nvq->sock_hlen;
 
@@ -654,7 +653,7 @@ static void handle_rx(struct vhost_net *net)
break;
}
}
-
+out:
mutex_unlock(&vq->mutex);
 }
 
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 0/4] vhost private_data rcu removal

2013-05-06 Thread Asias He
Asias He (4):
  vhost-net: Always access vq->private_data under vq mutex
  vhost-test: Always access vq->private_data under vq mutex
  vhost-scsi: Always access vq->private_data under vq mutex
  vhost: Remove custom vhost rcu usage

 drivers/vhost/net.c   | 37 -
 drivers/vhost/scsi.c  | 17 ++---
 drivers/vhost/test.c  | 20 +---
 drivers/vhost/vhost.h | 10 ++
 4 files changed, 33 insertions(+), 51 deletions(-)

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] vhost-test: Make vhost/test.c work

2013-05-06 Thread Asias He
Fix it by:
1) switching to use the new device specific fields per vq
2) not including vhost.c, instead make vhost-test.ko depend on vhost.ko.
---
 drivers/vhost/test.c | 37 +
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 1ee45bc..dc526eb 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -18,7 +18,7 @@
 #include 
 
 #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. */
@@ -29,16 +29,20 @@ enum {
VHOST_TEST_VQ_MAX = 1,
 };
 
+struct vhost_test_virtqueue {
+   struct vhost_virtqueue vq;
+};
+
 struct vhost_test {
struct vhost_dev dev;
-   struct vhost_virtqueue vqs[VHOST_TEST_VQ_MAX];
+   struct vhost_test_virtqueue vqs[VHOST_TEST_VQ_MAX];
 };
 
 /* Expects to be always run from workqueue - which acts as
  * 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->dev.vqs[VHOST_TEST_VQ];
unsigned out, in;
int head;
size_t len, total_len = 0;
@@ -101,15 +105,23 @@ static void handle_vq_kick(struct vhost_work *work)
 static int vhost_test_open(struct inode *inode, struct file *f)
 {
struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL);
+   struct vhost_virtqueue **vqs;
struct vhost_dev *dev;
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;
-   n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
-   r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX);
+   vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ].vq;
+   n->vqs[VHOST_TEST_VQ].vq.handle_kick = handle_vq_kick;
+   r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
if (r < 0) {
kfree(n);
return r;
@@ -135,12 +147,12 @@ static void *vhost_test_stop_vq(struct vhost_test *n,
 
 static void vhost_test_stop(struct vhost_test *n, void **privatep)
 {
-   *privatep = vhost_test_stop_vq(n, n->vqs + VHOST_TEST_VQ);
+   *privatep = vhost_test_stop_vq(n, &n->vqs[VHOST_TEST_VQ].vq);
 }
 
 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].vq.poll);
 }
 
 static void vhost_test_flush(struct vhost_test *n)
@@ -159,6 +171,7 @@ static int vhost_test_release(struct inode *inode, struct 
file *f)
/* We do an extra flush before freeing memory,
 * since jobs can re-queue themselves. */
vhost_test_flush(n);
+   kfree(n->dev.vqs);
kfree(n);
return 0;
 }
@@ -179,14 +192,14 @@ static long vhost_test_run(struct vhost_test *n, int test)
 
for (index = 0; index < n->dev.nvqs; ++index) {
/* Verify that ring has been setup correctly. */
-   if (!vhost_vq_access_ok(&n->vqs[index])) {
+   if (!vhost_vq_access_ok(&n->vqs[index].vq)) {
r = -EFAULT;
goto err;
}
}
 
for (index = 0; index < n->dev.nvqs; ++index) {
-   vq = n->vqs + index;
+   vq = &n->vqs[index].vq;
mutex_lock(&vq->mutex);
priv = test ? n : NULL;
 
@@ -195,7 +208,7 @@ static long vhost_test_run(struct vhost_test *n, int test)

lockdep_is_held(&vq->mutex));
rcu_assign_pointer(vq->private_data, priv);
 
-   r = vhost_init_used(&n->vqs[index]);
+   r = vhost_init_used(&n->vqs[index].vq);
 
mutex_unlock(&vq->mutex);
 
@@ -268,14 +281,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:
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfou

[PATCH] vhost-scsi: Enable VIRTIO_RING_F_EVENT_IDX

2013-05-06 Thread Asias He
It is disabled as a workaround. Now userspace bits works fine with it.
So, let's enable it.

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d860b58..5531ebc 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -160,14 +160,8 @@ enum {
VHOST_SCSI_VQ_IO = 2,
 };
 
-/*
- * VIRTIO_RING_F_EVENT_IDX seems broken. Not sure the bug is in
- * kernel but disabling it helps.
- * TODO: debug and remove the workaround.
- */
 enum {
-   VHOST_SCSI_FEATURES = (VHOST_FEATURES & (~VIRTIO_RING_F_EVENT_IDX)) |
- (1ULL << VIRTIO_SCSI_F_HOTPLUG)
+   VHOST_SCSI_FEATURES = VHOST_FEATURES | (1ULL << VIRTIO_SCSI_F_HOTPLUG)
 };
 
 #define VHOST_SCSI_MAX_TARGET  256
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vhost: drop virtio_net.h dependency

2013-05-06 Thread Asias He
On Mon, May 06, 2013 at 01:37:34PM +0300, Michael S. Tsirkin wrote:
> There's no net specific code in vhost.c anymore,
> don't include the virtio_net.h header.

Did you push the it to your tree. I am not seeing it.

> Signed-off-by: Michael S. Tsirkin 
> ---
> 
> This is on top of Asias' patches, already queued so
> just FYI.
> 
>  drivers/vhost/vhost.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index de9441a..dcde269 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -13,7 +13,6 @@
>  
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> -- 
> MST

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2 00/11] vhost cleanups

2013-05-06 Thread Asias He
On Mon, May 06, 2013 at 04:15:35PM +0300, Michael S. Tsirkin wrote:
> On Mon, May 06, 2013 at 08:05:26PM +0800, Asias He wrote:
> > On Mon, May 06, 2013 at 01:07:46PM +0300, Michael S. Tsirkin wrote:
> > > On Mon, May 06, 2013 at 04:38:18PM +0800, Asias He wrote:
> > > > MST, This is on top of [PATCH 0/2] vhost-net fix ubuf.
> > > 
> > > Okay, how about making EVENT_IDX work for virtio-scsi?
> > > I'm guessing it's some messup with feature negotiation,
> > > that's what all event-idx bugs came down to so far.
> > 
> > Yes, IIRC, EVENT_IDX works for vhost-scsi now. Will cook a patch to
> > enable it. It should go 3.10, right?
> 
> If it's early in the cycle, I think it can.

Well, let's queue it for 3.11.

> > > > Asias He (11):
> > > >   vhost: Remove vhost_enable_zcopy in vhost.h
> > > >   vhost: Move VHOST_NET_FEATURES to net.c
> > > >   vhost: Make vhost a separate module
> > > >   vhost: Remove comments for hdr in vhost.h
> > > >   vhost: Simplify dev->vqs[i] access
> > > >   vhost-net: Cleanup vhost_ubuf and vhost_zcopy
> > > >   vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration
> > > >   vhost-scsi: Rename struct vhost_scsi *s to *vs
> > > >   vhost-scsi: Make func indention more consistent
> > > >   vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg
> > > >   vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd
> > > > 
> > > >  drivers/vhost/Kconfig  |   8 +
> > > >  drivers/vhost/Makefile |   3 +-
> > > >  drivers/vhost/net.c|  64 ---
> > > >  drivers/vhost/scsi.c   | 470 
> > > > ++---
> > > >  drivers/vhost/vhost.c  |  86 +++--
> > > >  drivers/vhost/vhost.h  |  11 +-
> > > >  6 files changed, 361 insertions(+), 281 deletions(-)
> > > > 
> > > > -- 
> > > > 1.8.1.4
> > 
> > -- 
> > Asias

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2 03/11] vhost: Make vhost a separate module

2013-05-06 Thread Asias He
On Mon, May 06, 2013 at 01:03:42PM +0300, Michael S. Tsirkin wrote:
> On Mon, May 06, 2013 at 04:38:21PM +0800, Asias He wrote:
> > Currently, vhost-net and vhost-scsi are sharing the vhost core code.
> > However, vhost-scsi shares the code by including the vhost.c file
> > directly.
> > 
> > Making vhost a separate module makes it is easier to share code with
> > other vhost devices.
> > 
> > Signed-off-by: Asias He 
> 
> Also this will break test.c, right? Let's fix it in the same
> commit too.

I will fix it up and remove the useless 'return'.

> > ---
> >  drivers/vhost/Kconfig  |  8 
> >  drivers/vhost/Makefile |  3 ++-
> >  drivers/vhost/scsi.c   |  1 -
> >  drivers/vhost/vhost.c  | 51 
> > +-
> >  drivers/vhost/vhost.h  |  2 ++
> >  5 files changed, 62 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> > index 8b9226d..017a1e8 100644
> > --- a/drivers/vhost/Kconfig
> > +++ b/drivers/vhost/Kconfig
> > @@ -1,6 +1,7 @@
> >  config VHOST_NET
> > tristate "Host kernel accelerator for virtio net"
> > depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP)
> > +   select VHOST
> > select VHOST_RING
> > ---help---
> >   This kernel module can be loaded in host kernel to accelerate
> > @@ -13,6 +14,7 @@ config VHOST_NET
> >  config VHOST_SCSI
> > tristate "VHOST_SCSI TCM fabric driver"
> > depends on TARGET_CORE && EVENTFD && m
> > +   select VHOST
> > select VHOST_RING
> > default n
> > ---help---
> > @@ -24,3 +26,9 @@ config VHOST_RING
> > ---help---
> >   This option is selected by any driver which needs to access
> >   the host side of a virtio ring.
> > +
> > +config VHOST
> > +   tristate
> > +   ---help---
> > + This option is selected by any driver which needs to access
> > + the core of vhost.
> > diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
> > index 654e9afb..e0441c3 100644
> > --- a/drivers/vhost/Makefile
> > +++ b/drivers/vhost/Makefile
> > @@ -1,7 +1,8 @@
> >  obj-$(CONFIG_VHOST_NET) += vhost_net.o
> > -vhost_net-y := vhost.o net.o
> > +vhost_net-y := net.o
> >  
> >  obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
> >  vhost_scsi-y := scsi.o
> >  
> >  obj-$(CONFIG_VHOST_RING) += vringh.o
> > +obj-$(CONFIG_VHOST)+= vhost.o
> > diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> > index 5179f7a..2dcb94a 100644
> > --- a/drivers/vhost/scsi.c
> > +++ b/drivers/vhost/scsi.c
> > @@ -49,7 +49,6 @@
> >  #include 
> >  #include 
> >  
> > -#include "vhost.c"
> >  #include "vhost.h"
> >  
> >  #define TCM_VHOST_VERSION  "v0.1"
> > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> > index de9441a..e406d5f 100644
> > --- a/drivers/vhost/vhost.c
> > +++ b/drivers/vhost/vhost.c
> > @@ -25,6 +25,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include "vhost.h"
> >  
> > @@ -66,6 +67,7 @@ void vhost_work_init(struct vhost_work *work, 
> > vhost_work_fn_t fn)
> > work->flushing = 0;
> > work->queue_seq = work->done_seq = 0;
> >  }
> > +EXPORT_SYMBOL_GPL(vhost_work_init);
> >  
> >  /* Init poll structure */
> >  void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
> > @@ -79,6 +81,7 @@ void vhost_poll_init(struct vhost_poll *poll, 
> > vhost_work_fn_t fn,
> >  
> > vhost_work_init(&poll->work, fn);
> >  }
> > +EXPORT_SYMBOL_GPL(vhost_poll_init);
> >  
> >  /* Start polling a file. We add ourselves to file's wait queue. The caller 
> > must
> >   * keep a reference to a file until after vhost_poll_stop is called. */
> > @@ -101,6 +104,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct 
> > file *file)
> >  
> > return ret;
> >  }
> > +EXPORT_SYMBOL_GPL(vhost_poll_start);
> >  
> >  /* Stop polling a file. After this function returns, it becomes safe to 
> > drop the
> >   * file reference. You must also flush afterwards. */
> > @@ -111,6 +115,7 @@ void vhost_poll_stop(struct vhost_poll *poll)
> > poll->wqh = NULL;
> > }
> >  }
> > +EXPORT_SYMBOL_GPL(vhost_poll_stop);
> &

Re: [PATCH] vhost: drop virtio_net.h dependency

2013-05-06 Thread Asias He
On Mon, May 06, 2013 at 01:37:34PM +0300, Michael S. Tsirkin wrote:
> There's no net specific code in vhost.c anymore,
> don't include the virtio_net.h header.
> 
> Signed-off-by: Michael S. Tsirkin 

Reviewed-by: Asias He 

> ---
> 
> This is on top of Asias' patches, already queued so
> just FYI.
> 
>  drivers/vhost/vhost.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index de9441a..dcde269 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -13,7 +13,6 @@
>  
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> -- 
> MST

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2 00/11] vhost cleanups

2013-05-06 Thread Asias He
On Mon, May 06, 2013 at 01:07:46PM +0300, Michael S. Tsirkin wrote:
> On Mon, May 06, 2013 at 04:38:18PM +0800, Asias He wrote:
> > MST, This is on top of [PATCH 0/2] vhost-net fix ubuf.
> 
> Okay, how about making EVENT_IDX work for virtio-scsi?
> I'm guessing it's some messup with feature negotiation,
> that's what all event-idx bugs came down to so far.

Yes, IIRC, EVENT_IDX works for vhost-scsi now. Will cook a patch to
enable it. It should go 3.10, right?

> > Asias He (11):
> >   vhost: Remove vhost_enable_zcopy in vhost.h
> >   vhost: Move VHOST_NET_FEATURES to net.c
> >   vhost: Make vhost a separate module
> >   vhost: Remove comments for hdr in vhost.h
> >   vhost: Simplify dev->vqs[i] access
> >   vhost-net: Cleanup vhost_ubuf and vhost_zcopy
> >   vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration
> >   vhost-scsi: Rename struct vhost_scsi *s to *vs
> >   vhost-scsi: Make func indention more consistent
> >   vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg
> >   vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd
> > 
> >  drivers/vhost/Kconfig  |   8 +
> >  drivers/vhost/Makefile |   3 +-
> >  drivers/vhost/net.c|  64 ---
> >  drivers/vhost/scsi.c   | 470 
> > ++---
> >  drivers/vhost/vhost.c  |  86 +++--
> >  drivers/vhost/vhost.h  |  11 +-
> >  6 files changed, 361 insertions(+), 281 deletions(-)
> > 
> > -- 
> > 1.8.1.4

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 11/11] vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd

2013-05-06 Thread Asias He
This way, we use cmd for struct tcm_vhost_cmd and evt for struct
tcm_vhost_cmd.

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 142 +--
 1 file changed, 71 insertions(+), 71 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 353145f..d860b58 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -499,28 +499,28 @@ static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd)
return 0;
 }
 
-static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd)
+static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *cmd)
 {
-   struct vhost_scsi *vs = tv_cmd->tvc_vhost;
+   struct vhost_scsi *vs = cmd->tvc_vhost;
 
-   llist_add(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
+   llist_add(&cmd->tvc_completion_list, &vs->vs_completion_list);
 
vhost_work_queue(&vs->dev, &vs->vs_completion_work);
 }
 
 static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd)
 {
-   struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
+   struct tcm_vhost_cmd *cmd = container_of(se_cmd,
struct tcm_vhost_cmd, tvc_se_cmd);
-   vhost_scsi_complete_cmd(tv_cmd);
+   vhost_scsi_complete_cmd(cmd);
return 0;
 }
 
 static int tcm_vhost_queue_status(struct se_cmd *se_cmd)
 {
-   struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
+   struct tcm_vhost_cmd *cmd = container_of(se_cmd,
struct tcm_vhost_cmd, tvc_se_cmd);
-   vhost_scsi_complete_cmd(tv_cmd);
+   vhost_scsi_complete_cmd(cmd);
return 0;
 }
 
@@ -561,24 +561,24 @@ tcm_vhost_allocate_evt(struct vhost_scsi *vs,
return evt;
 }
 
-static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
+static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *cmd)
 {
-   struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
+   struct se_cmd *se_cmd = &cmd->tvc_se_cmd;
 
/* TODO locking against target/backend threads? */
transport_generic_free_cmd(se_cmd, 1);
 
-   if (tv_cmd->tvc_sgl_count) {
+   if (cmd->tvc_sgl_count) {
u32 i;
-   for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
-   put_page(sg_page(&tv_cmd->tvc_sgl[i]));
+   for (i = 0; i < cmd->tvc_sgl_count; i++)
+   put_page(sg_page(&cmd->tvc_sgl[i]));
 
-   kfree(tv_cmd->tvc_sgl);
+   kfree(cmd->tvc_sgl);
}
 
-   tcm_vhost_put_inflight(tv_cmd->inflight);
+   tcm_vhost_put_inflight(cmd->inflight);
 
-   kfree(tv_cmd);
+   kfree(cmd);
 }
 
 static void
@@ -661,7 +661,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work 
*work)
vs_completion_work);
DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ);
struct virtio_scsi_cmd_resp v_rsp;
-   struct tcm_vhost_cmd *tv_cmd;
+   struct tcm_vhost_cmd *cmd;
struct llist_node *llnode;
struct se_cmd *se_cmd;
int ret, vq;
@@ -669,32 +669,32 @@ static void vhost_scsi_complete_cmd_work(struct 
vhost_work *work)
bitmap_zero(signal, VHOST_SCSI_MAX_VQ);
llnode = llist_del_all(&vs->vs_completion_list);
while (llnode) {
-   tv_cmd = llist_entry(llnode, struct tcm_vhost_cmd,
+   cmd = llist_entry(llnode, struct tcm_vhost_cmd,
 tvc_completion_list);
llnode = llist_next(llnode);
-   se_cmd = &tv_cmd->tvc_se_cmd;
+   se_cmd = &cmd->tvc_se_cmd;
 
pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
-   tv_cmd, se_cmd->residual_count, se_cmd->scsi_status);
+   cmd, se_cmd->residual_count, se_cmd->scsi_status);
 
memset(&v_rsp, 0, sizeof(v_rsp));
v_rsp.resid = se_cmd->residual_count;
/* TODO is status_qualifier field needed? */
v_rsp.status = se_cmd->scsi_status;
v_rsp.sense_len = se_cmd->scsi_sense_length;
-   memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf,
+   memcpy(v_rsp.sense, cmd->tvc_sense_buf,
   v_rsp.sense_len);
-   ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
+   ret = copy_to_user(cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
if (likely(ret == 0)) {
struct vhost_scsi_virtqueue *q;
-   vhost_add_used(tv_cmd->tvc_vq, tv_cmd->tvc_vq_desc, 0);
-   q = container_of(tv_cmd->tvc_vq, struct 
vhost_scsi_virtqueue, vq);
+   vhost_add_used(cmd->tvc_vq, cmd->tvc_vq_desc, 0);
+   q = container_of(cmd-&

[PATCH v2 10/11] vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg

2013-05-06 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 122 +--
 1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d9781ed..353145f 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -705,7 +705,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work 
*work)
 
 static struct tcm_vhost_cmd *
 vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq,
-   struct tcm_vhost_tpg *tv_tpg,
+   struct tcm_vhost_tpg *tpg,
struct virtio_scsi_cmd_req *v_req,
u32 exp_data_len,
int data_direction)
@@ -713,7 +713,7 @@ vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq,
struct tcm_vhost_cmd *tv_cmd;
struct tcm_vhost_nexus *tv_nexus;
 
-   tv_nexus = tv_tpg->tpg_nexus;
+   tv_nexus = tpg->tpg_nexus;
if (!tv_nexus) {
pr_err("Unable to locate active struct tcm_vhost_nexus\n");
return ERR_PTR(-EIO);
@@ -895,7 +895,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
 {
struct tcm_vhost_tpg **vs_tpg;
struct virtio_scsi_cmd_req v_req;
-   struct tcm_vhost_tpg *tv_tpg;
+   struct tcm_vhost_tpg *tpg;
struct tcm_vhost_cmd *tv_cmd;
u32 exp_data_len, data_first, data_num, data_direction;
unsigned out, in, i;
@@ -981,10 +981,10 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
 
/* Extract the tpgt */
target = v_req.lun[1];
-   tv_tpg = ACCESS_ONCE(vs_tpg[target]);
+   tpg = ACCESS_ONCE(vs_tpg[target]);
 
/* Target does not exist, fail the request */
-   if (unlikely(!tv_tpg)) {
+   if (unlikely(!tpg)) {
vhost_scsi_send_bad_target(vs, vq, head, out);
continue;
}
@@ -993,7 +993,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
for (i = 0; i < data_num; i++)
exp_data_len += vq->iov[data_first + i].iov_len;
 
-   tv_cmd = vhost_scsi_allocate_cmd(vq, tv_tpg, &v_req,
+   tv_cmd = vhost_scsi_allocate_cmd(vq, tpg, &v_req,
exp_data_len, data_direction);
if (IS_ERR(tv_cmd)) {
vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n",
@@ -1172,7 +1172,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
struct vhost_scsi_target *t)
 {
struct tcm_vhost_tport *tv_tport;
-   struct tcm_vhost_tpg *tv_tpg;
+   struct tcm_vhost_tpg *tpg;
struct tcm_vhost_tpg **vs_tpg;
struct vhost_virtqueue *vq;
int index, ret, i, len;
@@ -1199,32 +1199,32 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
if (vs->vs_tpg)
memcpy(vs_tpg, vs->vs_tpg, len);
 
-   list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
-   mutex_lock(&tv_tpg->tv_tpg_mutex);
-   if (!tv_tpg->tpg_nexus) {
-   mutex_unlock(&tv_tpg->tv_tpg_mutex);
+   list_for_each_entry(tpg, &tcm_vhost_list, tv_tpg_list) {
+   mutex_lock(&tpg->tv_tpg_mutex);
+   if (!tpg->tpg_nexus) {
+   mutex_unlock(&tpg->tv_tpg_mutex);
continue;
}
-   if (tv_tpg->tv_tpg_vhost_count != 0) {
-   mutex_unlock(&tv_tpg->tv_tpg_mutex);
+   if (tpg->tv_tpg_vhost_count != 0) {
+   mutex_unlock(&tpg->tv_tpg_mutex);
continue;
}
-   tv_tport = tv_tpg->tport;
+   tv_tport = tpg->tport;
 
if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
-   if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) {
+   if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
kfree(vs_tpg);
-   mutex_unlock(&tv_tpg->tv_tpg_mutex);
+   mutex_unlock(&tpg->tv_tpg_mutex);
ret = -EEXIST;
goto out;
}
-   tv_tpg->tv_tpg_vhost_count++;
-   tv_tpg->vhost_scsi = vs;
-   vs_tpg[tv_tpg->tport_tpgt] = tv_tpg;
+   tpg->tv_tpg_vhost_count++;
+   tpg->vhost_scsi = vs;
+   vs_tpg[tpg->tport_tpgt] = tpg;
smp_mb__after_atomic_inc();

[PATCH v2 09/11] vhost-scsi: Make func indention more consistent

2013-05-06 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 154 +--
 1 file changed, 88 insertions(+), 66 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d4798e1..d9781ed 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -333,11 +333,12 @@ static u32 tcm_vhost_get_default_depth(struct 
se_portal_group *se_tpg)
return 1;
 }
 
-static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
-   struct se_node_acl *se_nacl,
-   struct t10_pr_registration *pr_reg,
-   int *format_code,
-   unsigned char *buf)
+static u32
+tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl,
+ struct t10_pr_registration *pr_reg,
+ int *format_code,
+ unsigned char *buf)
 {
struct tcm_vhost_tpg *tpg = container_of(se_tpg,
struct tcm_vhost_tpg, se_tpg);
@@ -363,10 +364,11 @@ static u32 tcm_vhost_get_pr_transport_id(struct 
se_portal_group *se_tpg,
format_code, buf);
 }
 
-static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
-   struct se_node_acl *se_nacl,
-   struct t10_pr_registration *pr_reg,
-   int *format_code)
+static u32
+tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl,
+ struct t10_pr_registration *pr_reg,
+ int *format_code)
 {
struct tcm_vhost_tpg *tpg = container_of(se_tpg,
struct tcm_vhost_tpg, se_tpg);
@@ -392,10 +394,11 @@ static u32 tcm_vhost_get_pr_transport_id_len(struct 
se_portal_group *se_tpg,
format_code);
 }
 
-static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group 
*se_tpg,
-   const char *buf,
-   u32 *out_tid_len,
-   char **port_nexus_ptr)
+static char *
+tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
+   const char *buf,
+   u32 *out_tid_len,
+   char **port_nexus_ptr)
 {
struct tcm_vhost_tpg *tpg = container_of(se_tpg,
struct tcm_vhost_tpg, se_tpg);
@@ -421,8 +424,8 @@ static char *tcm_vhost_parse_pr_out_transport_id(struct 
se_portal_group *se_tpg,
port_nexus_ptr);
 }
 
-static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
-   struct se_portal_group *se_tpg)
+static struct se_node_acl *
+tcm_vhost_alloc_fabric_acl(struct se_portal_group *se_tpg)
 {
struct tcm_vhost_nacl *nacl;
 
@@ -435,8 +438,9 @@ static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
return &nacl->se_node_acl;
 }
 
-static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
-   struct se_node_acl *se_nacl)
+static void
+tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
+struct se_node_acl *se_nacl)
 {
struct tcm_vhost_nacl *nacl = container_of(se_nacl,
struct tcm_vhost_nacl, se_node_acl);
@@ -531,8 +535,9 @@ static void tcm_vhost_free_evt(struct vhost_scsi *vs, 
struct tcm_vhost_evt *evt)
kfree(evt);
 }
 
-static struct tcm_vhost_evt *tcm_vhost_allocate_evt(struct vhost_scsi *vs,
-   u32 event, u32 reason)
+static struct tcm_vhost_evt *
+tcm_vhost_allocate_evt(struct vhost_scsi *vs,
+  u32 event, u32 reason)
 {
struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
struct tcm_vhost_evt *evt;
@@ -576,8 +581,8 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd 
*tv_cmd)
kfree(tv_cmd);
 }
 
-static void tcm_vhost_do_evt_work(struct vhost_scsi *vs,
-   struct tcm_vhost_evt *evt)
+static void
+tcm_vhost_do_evt_work(struct vhost_scsi *vs, struct tcm_vhost_evt *evt)
 {
struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
struct virtio_scsi_event *event = &evt->event;
@@ -698,12 +703,12 @@ static void vhost_scsi_complete_cmd_work(struct 
vhost_work *work)
vhost_signal(&vs->dev, &vs->vqs[vq].vq);
 }
 
-static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
-   struct vhost_virtqueue *vq,
-   struct tcm_vhost_tpg *tv_tpg,
-   struct virtio_scsi_cmd_req *v_req,
-   u32 exp_data_len,
-   int data_direction)
+static struct tcm_vhost_cmd *
+vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq,
+   struct tcm_vhost_tpg *tv_tpg,
+   struct virtio_scsi_cmd_req *v_req,
+   u32 exp_data_len,
+   int data_direction)
 {
struct tcm_vhost_cmd *tv_cmd;
struct tcm_vhost_nexus *tv_nexus;
@@ -73

[PATCH v2 08/11] vhost-scsi: Rename struct vhost_scsi *s to *vs

2013-05-06 Thread Asias He
vs is used everywhere, make the naming more consistent.

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 56 ++--
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 02ddedd..d4798e1 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1342,63 +1342,63 @@ static int vhost_scsi_set_features(struct vhost_scsi 
*vs, u64 features)
 
 static int vhost_scsi_open(struct inode *inode, struct file *f)
 {
-   struct vhost_scsi *s;
+   struct vhost_scsi *vs;
struct vhost_virtqueue **vqs;
int r, i;
 
-   s = kzalloc(sizeof(*s), GFP_KERNEL);
-   if (!s)
+   vs = kzalloc(sizeof(*vs), GFP_KERNEL);
+   if (!vs)
return -ENOMEM;
 
vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL);
if (!vqs) {
-   kfree(s);
+   kfree(vs);
return -ENOMEM;
}
 
-   vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work);
-   vhost_work_init(&s->vs_event_work, tcm_vhost_evt_work);
+   vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work);
+   vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work);
 
-   s->vs_events_nr = 0;
-   s->vs_events_missed = false;
+   vs->vs_events_nr = 0;
+   vs->vs_events_missed = false;
 
-   vqs[VHOST_SCSI_VQ_CTL] = &s->vqs[VHOST_SCSI_VQ_CTL].vq;
-   vqs[VHOST_SCSI_VQ_EVT] = &s->vqs[VHOST_SCSI_VQ_EVT].vq;
-   s->vqs[VHOST_SCSI_VQ_CTL].vq.handle_kick = vhost_scsi_ctl_handle_kick;
-   s->vqs[VHOST_SCSI_VQ_EVT].vq.handle_kick = vhost_scsi_evt_handle_kick;
+   vqs[VHOST_SCSI_VQ_CTL] = &vs->vqs[VHOST_SCSI_VQ_CTL].vq;
+   vqs[VHOST_SCSI_VQ_EVT] = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
+   vs->vqs[VHOST_SCSI_VQ_CTL].vq.handle_kick = vhost_scsi_ctl_handle_kick;
+   vs->vqs[VHOST_SCSI_VQ_EVT].vq.handle_kick = vhost_scsi_evt_handle_kick;
for (i = VHOST_SCSI_VQ_IO; i < VHOST_SCSI_MAX_VQ; i++) {
-   vqs[i] = &s->vqs[i].vq;
-   s->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
+   vqs[i] = &vs->vqs[i].vq;
+   vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
}
-   r = vhost_dev_init(&s->dev, vqs, VHOST_SCSI_MAX_VQ);
+   r = vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ);
 
-   tcm_vhost_init_inflight(s, NULL);
+   tcm_vhost_init_inflight(vs, NULL);
 
if (r < 0) {
kfree(vqs);
-   kfree(s);
+   kfree(vs);
return r;
}
 
-   f->private_data = s;
+   f->private_data = vs;
return 0;
 }
 
 static int vhost_scsi_release(struct inode *inode, struct file *f)
 {
-   struct vhost_scsi *s = f->private_data;
+   struct vhost_scsi *vs = f->private_data;
struct vhost_scsi_target t;
 
-   mutex_lock(&s->dev.mutex);
-   memcpy(t.vhost_wwpn, s->vs_vhost_wwpn, sizeof(t.vhost_wwpn));
-   mutex_unlock(&s->dev.mutex);
-   vhost_scsi_clear_endpoint(s, &t);
-   vhost_dev_stop(&s->dev);
-   vhost_dev_cleanup(&s->dev, false);
+   mutex_lock(&vs->dev.mutex);
+   memcpy(t.vhost_wwpn, vs->vs_vhost_wwpn, sizeof(t.vhost_wwpn));
+   mutex_unlock(&vs->dev.mutex);
+   vhost_scsi_clear_endpoint(vs, &t);
+   vhost_dev_stop(&vs->dev);
+   vhost_dev_cleanup(&vs->dev, false);
/* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
-   vhost_scsi_flush(s);
-   kfree(s->dev.vqs);
-   kfree(s);
+   vhost_scsi_flush(vs);
+   kfree(vs->dev.vqs);
+   kfree(vs);
return 0;
 }
 
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 07/11] vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration

2013-05-06 Thread Asias He
It was needed when struct tcm_vhost_tpg is in tcm_vhost.h

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 2dcb94a..02ddedd 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -115,7 +115,6 @@ struct tcm_vhost_nacl {
struct se_node_acl se_node_acl;
 };
 
-struct vhost_scsi;
 struct tcm_vhost_tpg {
/* Vhost port target portal group tag for TCM */
u16 tport_tpgt;
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 06/11] vhost-net: Cleanup vhost_ubuf and vhost_zcopy

2013-05-06 Thread Asias He
- Rename vhost_ubuf to vhost_net_ubuf
- Rename vhost_zcopy_mask to vhost_net_zcopy_mask
- Make funcs static

Signed-off-by: Asias He 
---
 drivers/vhost/net.c | 58 +++--
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 06b2447..2b51e23 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -70,7 +70,7 @@ enum {
VHOST_NET_VQ_MAX = 2,
 };
 
-struct vhost_ubuf_ref {
+struct vhost_net_ubuf_ref {
struct kref kref;
wait_queue_head_t wait;
struct vhost_virtqueue *vq;
@@ -93,7 +93,7 @@ struct vhost_net_virtqueue {
struct ubuf_info *ubuf_info;
/* Reference counting for outstanding ubufs.
 * Protected by vq mutex. Writers must also take device mutex. */
-   struct vhost_ubuf_ref *ubufs;
+   struct vhost_net_ubuf_ref *ubufs;
 };
 
 struct vhost_net {
@@ -110,24 +110,25 @@ struct vhost_net {
bool tx_flush;
 };
 
-static unsigned vhost_zcopy_mask __read_mostly;
+static unsigned vhost_net_zcopy_mask __read_mostly;
 
-void vhost_enable_zcopy(int vq)
+static void vhost_net_enable_zcopy(int vq)
 {
-   vhost_zcopy_mask |= 0x1 << vq;
+   vhost_net_zcopy_mask |= 0x1 << vq;
 }
 
-static void vhost_zerocopy_done_signal(struct kref *kref)
+static void vhost_net_zerocopy_done_signal(struct kref *kref)
 {
-   struct vhost_ubuf_ref *ubufs = container_of(kref, struct vhost_ubuf_ref,
-   kref);
+   struct vhost_net_ubuf_ref *ubufs;
+
+   ubufs = container_of(kref, struct vhost_net_ubuf_ref, kref);
wake_up(&ubufs->wait);
 }
 
-struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *vq,
-   bool zcopy)
+static struct vhost_net_ubuf_ref *
+vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy)
 {
-   struct vhost_ubuf_ref *ubufs;
+   struct vhost_net_ubuf_ref *ubufs;
/* No zero copy backend? Nothing to count. */
if (!zcopy)
return NULL;
@@ -140,14 +141,14 @@ struct vhost_ubuf_ref *vhost_ubuf_alloc(struct 
vhost_virtqueue *vq,
return ubufs;
 }
 
-void vhost_ubuf_put(struct vhost_ubuf_ref *ubufs)
+static void vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs)
 {
-   kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
+   kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
 }
 
-void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
+static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
 {
-   kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
+   kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
kfree(ubufs);
 }
@@ -159,7 +160,7 @@ static void vhost_net_clear_ubuf_info(struct vhost_net *n)
int i;
 
for (i = 0; i < n->dev.nvqs; ++i) {
-   zcopy = vhost_zcopy_mask & (0x1 << i);
+   zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (zcopy)
kfree(n->vqs[i].ubuf_info);
}
@@ -171,7 +172,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
int i;
 
for (i = 0; i < n->dev.nvqs; ++i) {
-   zcopy = vhost_zcopy_mask & (0x1 << i);
+   zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (!zcopy)
continue;
n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) *
@@ -183,7 +184,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
 
 err:
while (i--) {
-   zcopy = vhost_zcopy_mask & (0x1 << i);
+   zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (!zcopy)
continue;
kfree(n->vqs[i].ubuf_info);
@@ -305,7 +306,7 @@ static int vhost_zerocopy_signal_used(struct vhost_net *net,
 
 static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
 {
-   struct vhost_ubuf_ref *ubufs = ubuf->ctx;
+   struct vhost_net_ubuf_ref *ubufs = ubuf->ctx;
struct vhost_virtqueue *vq = ubufs->vq;
int cnt = atomic_read(&ubufs->kref.refcount);
 
@@ -322,7 +323,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, 
bool success)
/* set len to mark this desc buffers done DMA */
vq->heads[ubuf->desc].len = success ?
VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN;
-   vhost_ubuf_put(ubufs);
+   vhost_net_ubuf_put(ubufs);
 }
 
 /* Expects to be always run from workqueue - which acts as
@@ -345,7 +346,7 @@ static void handle_tx(struct vhost_net *net)
int err;
size_t hdr_size;
struct socket *sock;
-   struct vhost_ubuf_ref *uninitialized_var(ubufs);
+   struct vhost_ne

[PATCH v2 05/11] vhost: Simplify dev->vqs[i] access

2013-05-06 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/vhost.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index e406d5f..74bc779 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -260,17 +260,16 @@ static void vhost_vq_free_iovecs(struct vhost_virtqueue 
*vq)
 /* Helper to allocate iovec buffers for all vqs. */
 static long vhost_dev_alloc_iovecs(struct vhost_dev *dev)
 {
+   struct vhost_virtqueue *vq;
int i;
 
for (i = 0; i < dev->nvqs; ++i) {
-   dev->vqs[i]->indirect = kmalloc(sizeof *dev->vqs[i]->indirect *
-  UIO_MAXIOV, GFP_KERNEL);
-   dev->vqs[i]->log = kmalloc(sizeof *dev->vqs[i]->log * 
UIO_MAXIOV,
- GFP_KERNEL);
-   dev->vqs[i]->heads = kmalloc(sizeof *dev->vqs[i]->heads *
-   UIO_MAXIOV, GFP_KERNEL);
-   if (!dev->vqs[i]->indirect || !dev->vqs[i]->log ||
-   !dev->vqs[i]->heads)
+   vq = dev->vqs[i];
+   vq->indirect = kmalloc(sizeof *vq->indirect * UIO_MAXIOV,
+  GFP_KERNEL);
+   vq->log = kmalloc(sizeof *vq->log * UIO_MAXIOV, GFP_KERNEL);
+   vq->heads = kmalloc(sizeof *vq->heads * UIO_MAXIOV, GFP_KERNEL);
+   if (!vq->indirect || !vq->log || !vq->heads)
goto err_nomem;
}
return 0;
@@ -292,6 +291,7 @@ static void vhost_dev_free_iovecs(struct vhost_dev *dev)
 long vhost_dev_init(struct vhost_dev *dev,
struct vhost_virtqueue **vqs, int nvqs)
 {
+   struct vhost_virtqueue *vq;
int i;
 
dev->vqs = vqs;
@@ -306,15 +306,16 @@ long vhost_dev_init(struct vhost_dev *dev,
dev->worker = NULL;
 
for (i = 0; i < dev->nvqs; ++i) {
-   dev->vqs[i]->log = NULL;
-   dev->vqs[i]->indirect = NULL;
-   dev->vqs[i]->heads = NULL;
-   dev->vqs[i]->dev = dev;
-   mutex_init(&dev->vqs[i]->mutex);
-   vhost_vq_reset(dev, dev->vqs[i]);
-   if (dev->vqs[i]->handle_kick)
-   vhost_poll_init(&dev->vqs[i]->poll,
-   dev->vqs[i]->handle_kick, POLLIN, dev);
+   vq = dev->vqs[i];
+   vq->log = NULL;
+   vq->indirect = NULL;
+   vq->heads = NULL;
+   vq->dev = dev;
+   mutex_init(&vq->mutex);
+   vhost_vq_reset(dev, vq);
+   if (vq->handle_kick)
+   vhost_poll_init(&vq->poll, vq->handle_kick,
+   POLLIN, dev);
}
 
return 0;
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 04/11] vhost: Remove comments for hdr in vhost.h

2013-05-06 Thread Asias He
It is supposed to be removed when hdr is moved into vhost_net_virtqueue.

Signed-off-by: Asias He 
---
 drivers/vhost/vhost.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 94a80eb..51aeb5f 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -101,9 +101,6 @@ struct vhost_virtqueue {
u64 log_addr;
 
struct iovec iov[UIO_MAXIOV];
-   /* hdr is used to store the virtio header.
-* Since each iovec has >= 1 byte length, we never need more than
-* header length entries to store the header. */
struct iovec *indirect;
struct vring_used_elem *heads;
/* We use a kind of RCU to access private pointer.
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 03/11] vhost: Make vhost a separate module

2013-05-06 Thread Asias He
Currently, vhost-net and vhost-scsi are sharing the vhost core code.
However, vhost-scsi shares the code by including the vhost.c file
directly.

Making vhost a separate module makes it is easier to share code with
other vhost devices.

Signed-off-by: Asias He 
---
 drivers/vhost/Kconfig  |  8 
 drivers/vhost/Makefile |  3 ++-
 drivers/vhost/scsi.c   |  1 -
 drivers/vhost/vhost.c  | 51 +-
 drivers/vhost/vhost.h  |  2 ++
 5 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 8b9226d..017a1e8 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -1,6 +1,7 @@
 config VHOST_NET
tristate "Host kernel accelerator for virtio net"
depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP)
+   select VHOST
select VHOST_RING
---help---
  This kernel module can be loaded in host kernel to accelerate
@@ -13,6 +14,7 @@ config VHOST_NET
 config VHOST_SCSI
tristate "VHOST_SCSI TCM fabric driver"
depends on TARGET_CORE && EVENTFD && m
+   select VHOST
select VHOST_RING
default n
---help---
@@ -24,3 +26,9 @@ config VHOST_RING
---help---
  This option is selected by any driver which needs to access
  the host side of a virtio ring.
+
+config VHOST
+   tristate
+   ---help---
+ This option is selected by any driver which needs to access
+ the core of vhost.
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
index 654e9afb..e0441c3 100644
--- a/drivers/vhost/Makefile
+++ b/drivers/vhost/Makefile
@@ -1,7 +1,8 @@
 obj-$(CONFIG_VHOST_NET) += vhost_net.o
-vhost_net-y := vhost.o net.o
+vhost_net-y := net.o
 
 obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
 vhost_scsi-y := scsi.o
 
 obj-$(CONFIG_VHOST_RING) += vringh.o
+obj-$(CONFIG_VHOST)+= vhost.o
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 5179f7a..2dcb94a 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -49,7 +49,6 @@
 #include 
 #include 
 
-#include "vhost.c"
 #include "vhost.h"
 
 #define TCM_VHOST_VERSION  "v0.1"
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index de9441a..e406d5f 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vhost.h"
 
@@ -66,6 +67,7 @@ void vhost_work_init(struct vhost_work *work, vhost_work_fn_t 
fn)
work->flushing = 0;
work->queue_seq = work->done_seq = 0;
 }
+EXPORT_SYMBOL_GPL(vhost_work_init);
 
 /* Init poll structure */
 void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
@@ -79,6 +81,7 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t 
fn,
 
vhost_work_init(&poll->work, fn);
 }
+EXPORT_SYMBOL_GPL(vhost_poll_init);
 
 /* Start polling a file. We add ourselves to file's wait queue. The caller must
  * keep a reference to a file until after vhost_poll_stop is called. */
@@ -101,6 +104,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file 
*file)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(vhost_poll_start);
 
 /* Stop polling a file. After this function returns, it becomes safe to drop 
the
  * file reference. You must also flush afterwards. */
@@ -111,6 +115,7 @@ void vhost_poll_stop(struct vhost_poll *poll)
poll->wqh = NULL;
}
 }
+EXPORT_SYMBOL_GPL(vhost_poll_stop);
 
 static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
unsigned seq)
@@ -123,7 +128,7 @@ static bool vhost_work_seq_done(struct vhost_dev *dev, 
struct vhost_work *work,
return left <= 0;
 }
 
-static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
+void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
 {
unsigned seq;
int flushing;
@@ -138,6 +143,7 @@ static void vhost_work_flush(struct vhost_dev *dev, struct 
vhost_work *work)
spin_unlock_irq(&dev->work_lock);
BUG_ON(flushing < 0);
 }
+EXPORT_SYMBOL_GPL(vhost_work_flush);
 
 /* Flush any work that has been scheduled. When calling this, don't hold any
  * locks that are also used by the callback. */
@@ -145,6 +151,7 @@ void vhost_poll_flush(struct vhost_poll *poll)
 {
vhost_work_flush(poll->dev, &poll->work);
 }
+EXPORT_SYMBOL_GPL(vhost_poll_flush);
 
 void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
 {
@@ -158,11 +165,13 @@ void vhost_work_queue(struct vhost_dev *dev, struct 
vhost_work *work)
}
spin_unlock_irqrestore(&dev->work_lock, flags);
 }
+EXPORT_SYMBOL_GPL(vhost_work_queue);
 
 void vhost_poll_queue(struct vhost_poll *poll)
 {
vhost_work_queue(poll->dev, &poll->work);
 }
+

[PATCH v2 02/11] vhost: Move VHOST_NET_FEATURES to net.c

2013-05-06 Thread Asias He
vhost.h should not depend on device specific marcos like
VHOST_NET_F_VIRTIO_NET_HDR and VIRTIO_NET_F_MRG_RXBUF.

Signed-off-by: Asias He 
---
 drivers/vhost/net.c   | 6 ++
 drivers/vhost/vhost.h | 3 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 354665a..06b2447 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -59,6 +59,12 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"
 #define VHOST_DMA_IS_DONE(len) ((len) >= VHOST_DMA_DONE_LEN)
 
 enum {
+   VHOST_NET_FEATURES = VHOST_FEATURES |
+(1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
+(1ULL << VIRTIO_NET_F_MRG_RXBUF),
+};
+
+enum {
VHOST_NET_VQ_RX = 0,
VHOST_NET_VQ_TX = 1,
VHOST_NET_VQ_MAX = 2,
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 076c9ac..6bf81a9 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -178,9 +178,6 @@ enum {
 (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
 (1ULL << VIRTIO_RING_F_EVENT_IDX) |
 (1ULL << VHOST_F_LOG_ALL),
-   VHOST_NET_FEATURES = VHOST_FEATURES |
-(1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
-(1ULL << VIRTIO_NET_F_MRG_RXBUF),
 };
 
 static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 01/11] vhost: Remove vhost_enable_zcopy in vhost.h

2013-05-06 Thread Asias He
It is net.c specific.

Signed-off-by: Asias He 
---
 drivers/vhost/vhost.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index cc23bc4..076c9ac 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -192,7 +192,4 @@ static inline int vhost_has_feature(struct vhost_dev *dev, 
int bit)
acked_features = rcu_dereference_index_check(dev->acked_features, 1);
return acked_features & (1 << bit);
 }
-
-void vhost_enable_zcopy(int vq);
-
 #endif
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 00/11] vhost cleanups

2013-05-06 Thread Asias He
MST, This is on top of [PATCH 0/2] vhost-net fix ubuf.

Asias He (11):
  vhost: Remove vhost_enable_zcopy in vhost.h
  vhost: Move VHOST_NET_FEATURES to net.c
  vhost: Make vhost a separate module
  vhost: Remove comments for hdr in vhost.h
  vhost: Simplify dev->vqs[i] access
  vhost-net: Cleanup vhost_ubuf and vhost_zcopy
  vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration
  vhost-scsi: Rename struct vhost_scsi *s to *vs
  vhost-scsi: Make func indention more consistent
  vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg
  vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd

 drivers/vhost/Kconfig  |   8 +
 drivers/vhost/Makefile |   3 +-
 drivers/vhost/net.c|  64 ---
 drivers/vhost/scsi.c   | 470 ++---
 drivers/vhost/vhost.c  |  86 +++--
 drivers/vhost/vhost.h  |  11 +-
 6 files changed, 361 insertions(+), 281 deletions(-)

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 4/4] vhost-net: Cleanup vhost_ubuf adn vhost_zcopy

2013-05-06 Thread Asias He
On Mon, May 6, 2013 at 4:17 PM, Michael S. Tsirkin  wrote:
> Typo a/adn/and/

Yes.  Catched  this up and and fixed already.

>
> On Fri, May 03, 2013 at 02:25:18PM +0800, Asias He wrote:
>> - Rename vhost_ubuf to vhost_net_ubuf
>> - Rename vhost_zcopy_mask to vhost_net_zcopy_mask
>> - Make funcs static
>>
>> Signed-off-by: Asias He 
>> ---
>>  drivers/vhost/net.c | 58 
>> +++--
>>  1 file changed, 30 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>> index eb73217..4548c0b 100644
>> --- a/drivers/vhost/net.c
>> +++ b/drivers/vhost/net.c
>> @@ -70,7 +70,7 @@ enum {
>>   VHOST_NET_VQ_MAX = 2,
>>  };
>>
>> -struct vhost_ubuf_ref {
>> +struct vhost_net_ubuf_ref {
>>   struct kref kref;
>>   wait_queue_head_t wait;
>>   struct vhost_virtqueue *vq;
>> @@ -93,7 +93,7 @@ struct vhost_net_virtqueue {
>>   struct ubuf_info *ubuf_info;
>>   /* Reference counting for outstanding ubufs.
>>* Protected by vq mutex. Writers must also take device mutex. */
>> - struct vhost_ubuf_ref *ubufs;
>> + struct vhost_net_ubuf_ref *ubufs;
>>  };
>>
>>  struct vhost_net {
>> @@ -110,24 +110,25 @@ struct vhost_net {
>>   bool tx_flush;
>>  };
>>
>> -static unsigned vhost_zcopy_mask __read_mostly;
>> +static unsigned vhost_net_zcopy_mask __read_mostly;
>>
>> -void vhost_enable_zcopy(int vq)
>> +static void vhost_net_enable_zcopy(int vq)
>>  {
>> - vhost_zcopy_mask |= 0x1 << vq;
>> + vhost_net_zcopy_mask |= 0x1 << vq;
>>  }
>>
>> -static void vhost_zerocopy_done_signal(struct kref *kref)
>> +static void vhost_net_zerocopy_done_signal(struct kref *kref)
>>  {
>> - struct vhost_ubuf_ref *ubufs = container_of(kref, struct 
>> vhost_ubuf_ref,
>> - kref);
>> + struct vhost_net_ubuf_ref *ubufs;
>> +
>> + ubufs = container_of(kref, struct vhost_net_ubuf_ref, kref);
>>   wake_up(&ubufs->wait);
>>  }
>>
>> -struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *vq,
>> - bool zcopy)
>> +static struct vhost_net_ubuf_ref *
>> +vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy)
>>  {
>> - struct vhost_ubuf_ref *ubufs;
>> + struct vhost_net_ubuf_ref *ubufs;
>>   /* No zero copy backend? Nothing to count. */
>>   if (!zcopy)
>>   return NULL;
>> @@ -140,14 +141,14 @@ struct vhost_ubuf_ref *vhost_ubuf_alloc(struct 
>> vhost_virtqueue *vq,
>>   return ubufs;
>>  }
>>
>> -void vhost_ubuf_put(struct vhost_ubuf_ref *ubufs)
>> +static void vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs)
>>  {
>> - kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
>> + kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
>>  }
>>
>> -void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
>> +static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
>>  {
>> - kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
>> + kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
>>   wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
>>   kfree(ubufs);
>>  }
>> @@ -159,7 +160,7 @@ static void vhost_net_clear_ubuf_info(struct vhost_net 
>> *n)
>>   int i;
>>
>>   for (i = 0; i < n->dev.nvqs; ++i) {
>> - zcopy = vhost_zcopy_mask & (0x1 << i);
>> + zcopy = vhost_net_zcopy_mask & (0x1 << i);
>>   if (zcopy)
>>   kfree(n->vqs[i].ubuf_info);
>>   }
>> @@ -171,7 +172,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
>>   int i;
>>
>>   for (i = 0; i < n->dev.nvqs; ++i) {
>> - zcopy = vhost_zcopy_mask & (0x1 << i);
>> + zcopy = vhost_net_zcopy_mask & (0x1 << i);
>>   if (!zcopy)
>>   continue;
>>   n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) *
>> @@ -183,7 +184,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
>>
>>  err:
>>   while (i--) {
>> - zcopy = vhost_zcopy_mask & (0x1 << i);
>> + zcopy = vhost_net_zcopy_mask & (0x1 << i);
>

Re: [PATCH 0/3] vhost cleanups and separate module

2013-05-06 Thread Asias He
Hello Rusty, 

On Mon, May 06, 2013 at 03:41:36PM +0930, Rusty Russell wrote:
> Asias He  writes:
> > Asias He (3):
> >   vhost: Remove vhost_enable_zcopy in vhost.h
> >   vhost: Move VHOST_NET_FEATURES to net.c
> >   vhost: Make vhost a separate module
> 
> I like these cleanups, MST pleasee apply.
> 
> I have some other cleanups which are on hold for the moment pending
> MST's vhost_net simplification.  MST, how's that going?

Do you mean patches in your rusty/vringh branch? I want to do the frame
assumption conversion for vhost-scsi on top of the vringh series.

> Thanks,
> Rusty.

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 3/4] vhost-net: Free ubuf when vhost_dev_ioctl fails

2013-05-05 Thread Asias He
On Sun, May 05, 2013 at 04:50:07PM +0300, Michael S. Tsirkin wrote:
> On Fri, May 03, 2013 at 02:25:17PM +0800, Asias He wrote:
> > Free ubuf when vhost_dev_ioctl for VHOST_SET_OWNER fails.
> > 
> > Signed-off-by: Asias He 
> > ---
> >  drivers/vhost/net.c | 20 ++--
> >  1 file changed, 18 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> > index b2f6b41..eb73217 100644
> > --- a/drivers/vhost/net.c
> > +++ b/drivers/vhost/net.c
> > @@ -152,6 +152,19 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref 
> > *ubufs)
> > kfree(ubufs);
> >  }
> >  
> > +static void vhost_net_clear_ubuf_info(struct vhost_net *n)
> > +{
> > +
> > +   bool zcopy;
> > +   int i;
> > +
> > +   for (i = 0; i < n->dev.nvqs; ++i) {
> > +   zcopy = vhost_zcopy_mask & (0x1 << i);
> > +   if (zcopy)
> > +   kfree(n->vqs[i].ubuf_info);
> > +   }
> > +}
> > +
> >  int vhost_net_set_ubuf_info(struct vhost_net *n)
> >  {
> > bool zcopy;
> > @@ -1069,10 +1082,13 @@ static long vhost_net_ioctl(struct file *f, 
> > unsigned int ioctl,
> > goto out;
> > }
> > r = vhost_dev_ioctl(&n->dev, ioctl, argp);
> > -   if (r == -ENOIOCTLCMD)
> > +   if (r == -ENOIOCTLCMD) {
> > r = vhost_vring_ioctl(&n->dev, ioctl, argp);
> > -   else
> > +   } else {
> > +   if (r < 0 && ioctl == VHOST_SET_OWNER)
> > +   vhost_net_clear_ubuf_info(n);
> > vhost_net_flush(n);
> > +   }
> 
> This is becoming too complex.
> Let's just export vhost_dev_set_owner from vhost.c
> and have a separate case statement for VHOST_SET_OWNER.

done.

> 
> Also - could you please send a separate series
> with bugfixes, so I can apply for 3.10?
> Cleanups I will queue for 3.11.

done.

> Thanks!
> 
> >  out:
> > mutex_unlock(&n->dev.mutex);
> > return r;
> > -- 
> > 1.8.1.4

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 2/2] vhost-net: Free ubuf when vhost_dev_set_owner fails

2013-05-05 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/net.c | 38 --
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index a3645bd..354665a 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -146,6 +146,19 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
kfree(ubufs);
 }
 
+static void vhost_net_clear_ubuf_info(struct vhost_net *n)
+{
+
+   bool zcopy;
+   int i;
+
+   for (i = 0; i < n->dev.nvqs; ++i) {
+   zcopy = vhost_zcopy_mask & (0x1 << i);
+   if (zcopy)
+   kfree(n->vqs[i].ubuf_info);
+   }
+}
+
 int vhost_net_set_ubuf_info(struct vhost_net *n)
 {
bool zcopy;
@@ -1027,6 +1040,23 @@ static int vhost_net_set_features(struct vhost_net *n, 
u64 features)
return 0;
 }
 
+static long vhost_net_set_owner(struct vhost_net *n)
+{
+   int r;
+
+   mutex_lock(&n->dev.mutex);
+   r = vhost_net_set_ubuf_info(n);
+   if (r)
+   goto out;
+   r = vhost_dev_set_owner(&n->dev);
+   if (r)
+   vhost_net_clear_ubuf_info(n);
+   vhost_net_flush(n);
+out:
+   mutex_unlock(&n->dev.mutex);
+   return r;
+}
+
 static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
unsigned long arg)
 {
@@ -1055,19 +1085,15 @@ static long vhost_net_ioctl(struct file *f, unsigned 
int ioctl,
return vhost_net_set_features(n, features);
case VHOST_RESET_OWNER:
return vhost_net_reset_owner(n);
+   case VHOST_SET_OWNER:
+   return vhost_net_set_owner(n);
default:
mutex_lock(&n->dev.mutex);
-   if (ioctl == VHOST_SET_OWNER) {
-   r = vhost_net_set_ubuf_info(n);
-   if (r)
-   goto out;
-   }
r = vhost_dev_ioctl(&n->dev, ioctl, argp);
if (r == -ENOIOCTLCMD)
r = vhost_vring_ioctl(&n->dev, ioctl, argp);
else
vhost_net_flush(n);
-out:
mutex_unlock(&n->dev.mutex);
return r;
}
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 1/2] vhost: Export vhost_dev_set_owner

2013-05-05 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/vhost.c | 2 +-
 drivers/vhost/vhost.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 749b5ab..de9441a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -344,7 +344,7 @@ static int vhost_attach_cgroups(struct vhost_dev *dev)
 }
 
 /* Caller should have device mutex */
-static long vhost_dev_set_owner(struct vhost_dev *dev)
+long vhost_dev_set_owner(struct vhost_dev *dev)
 {
struct task_struct *worker;
int err;
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index b58f4ae..cc23bc4 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -135,6 +135,7 @@ struct vhost_dev {
 };
 
 long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, int 
nvqs);
+long vhost_dev_set_owner(struct vhost_dev *dev);
 long vhost_dev_check_owner(struct vhost_dev *);
 struct vhost_memory *vhost_dev_reset_owner_prepare(void);
 void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_memory *);
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 0/2] vhost-net fix ubuf

2013-05-05 Thread Asias He
Asias He (2):
  vhost: Export vhost_dev_set_owner
  vhost-net: Free ubuf when vhost_dev_set_owner fails

 drivers/vhost/net.c   | 38 --
 drivers/vhost/vhost.c |  2 +-
 drivers/vhost/vhost.h |  1 +
 3 files changed, 34 insertions(+), 7 deletions(-)

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 5/5] vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd

2013-05-03 Thread Asias He
This way, we use cmd for struct tcm_vhost_cmd and evt for struct
tcm_vhost_cmd.

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 142 +--
 1 file changed, 71 insertions(+), 71 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 353145f..d860b58 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -499,28 +499,28 @@ static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd)
return 0;
 }
 
-static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd)
+static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *cmd)
 {
-   struct vhost_scsi *vs = tv_cmd->tvc_vhost;
+   struct vhost_scsi *vs = cmd->tvc_vhost;
 
-   llist_add(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
+   llist_add(&cmd->tvc_completion_list, &vs->vs_completion_list);
 
vhost_work_queue(&vs->dev, &vs->vs_completion_work);
 }
 
 static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd)
 {
-   struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
+   struct tcm_vhost_cmd *cmd = container_of(se_cmd,
struct tcm_vhost_cmd, tvc_se_cmd);
-   vhost_scsi_complete_cmd(tv_cmd);
+   vhost_scsi_complete_cmd(cmd);
return 0;
 }
 
 static int tcm_vhost_queue_status(struct se_cmd *se_cmd)
 {
-   struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
+   struct tcm_vhost_cmd *cmd = container_of(se_cmd,
struct tcm_vhost_cmd, tvc_se_cmd);
-   vhost_scsi_complete_cmd(tv_cmd);
+   vhost_scsi_complete_cmd(cmd);
return 0;
 }
 
@@ -561,24 +561,24 @@ tcm_vhost_allocate_evt(struct vhost_scsi *vs,
return evt;
 }
 
-static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
+static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *cmd)
 {
-   struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
+   struct se_cmd *se_cmd = &cmd->tvc_se_cmd;
 
/* TODO locking against target/backend threads? */
transport_generic_free_cmd(se_cmd, 1);
 
-   if (tv_cmd->tvc_sgl_count) {
+   if (cmd->tvc_sgl_count) {
u32 i;
-   for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
-   put_page(sg_page(&tv_cmd->tvc_sgl[i]));
+   for (i = 0; i < cmd->tvc_sgl_count; i++)
+   put_page(sg_page(&cmd->tvc_sgl[i]));
 
-   kfree(tv_cmd->tvc_sgl);
+   kfree(cmd->tvc_sgl);
}
 
-   tcm_vhost_put_inflight(tv_cmd->inflight);
+   tcm_vhost_put_inflight(cmd->inflight);
 
-   kfree(tv_cmd);
+   kfree(cmd);
 }
 
 static void
@@ -661,7 +661,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work 
*work)
vs_completion_work);
DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ);
struct virtio_scsi_cmd_resp v_rsp;
-   struct tcm_vhost_cmd *tv_cmd;
+   struct tcm_vhost_cmd *cmd;
struct llist_node *llnode;
struct se_cmd *se_cmd;
int ret, vq;
@@ -669,32 +669,32 @@ static void vhost_scsi_complete_cmd_work(struct 
vhost_work *work)
bitmap_zero(signal, VHOST_SCSI_MAX_VQ);
llnode = llist_del_all(&vs->vs_completion_list);
while (llnode) {
-   tv_cmd = llist_entry(llnode, struct tcm_vhost_cmd,
+   cmd = llist_entry(llnode, struct tcm_vhost_cmd,
 tvc_completion_list);
llnode = llist_next(llnode);
-   se_cmd = &tv_cmd->tvc_se_cmd;
+   se_cmd = &cmd->tvc_se_cmd;
 
pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
-   tv_cmd, se_cmd->residual_count, se_cmd->scsi_status);
+   cmd, se_cmd->residual_count, se_cmd->scsi_status);
 
memset(&v_rsp, 0, sizeof(v_rsp));
v_rsp.resid = se_cmd->residual_count;
/* TODO is status_qualifier field needed? */
v_rsp.status = se_cmd->scsi_status;
v_rsp.sense_len = se_cmd->scsi_sense_length;
-   memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf,
+   memcpy(v_rsp.sense, cmd->tvc_sense_buf,
   v_rsp.sense_len);
-   ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
+   ret = copy_to_user(cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
if (likely(ret == 0)) {
struct vhost_scsi_virtqueue *q;
-   vhost_add_used(tv_cmd->tvc_vq, tv_cmd->tvc_vq_desc, 0);
-   q = container_of(tv_cmd->tvc_vq, struct 
vhost_scsi_virtqueue, vq);
+   vhost_add_used(cmd->tvc_vq, cmd->tvc_vq_desc, 0);
+   q = container_of(cmd-&

[PATCH 4/5] vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg

2013-05-03 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 122 +--
 1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d9781ed..353145f 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -705,7 +705,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work 
*work)
 
 static struct tcm_vhost_cmd *
 vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq,
-   struct tcm_vhost_tpg *tv_tpg,
+   struct tcm_vhost_tpg *tpg,
struct virtio_scsi_cmd_req *v_req,
u32 exp_data_len,
int data_direction)
@@ -713,7 +713,7 @@ vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq,
struct tcm_vhost_cmd *tv_cmd;
struct tcm_vhost_nexus *tv_nexus;
 
-   tv_nexus = tv_tpg->tpg_nexus;
+   tv_nexus = tpg->tpg_nexus;
if (!tv_nexus) {
pr_err("Unable to locate active struct tcm_vhost_nexus\n");
return ERR_PTR(-EIO);
@@ -895,7 +895,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
 {
struct tcm_vhost_tpg **vs_tpg;
struct virtio_scsi_cmd_req v_req;
-   struct tcm_vhost_tpg *tv_tpg;
+   struct tcm_vhost_tpg *tpg;
struct tcm_vhost_cmd *tv_cmd;
u32 exp_data_len, data_first, data_num, data_direction;
unsigned out, in, i;
@@ -981,10 +981,10 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
 
/* Extract the tpgt */
target = v_req.lun[1];
-   tv_tpg = ACCESS_ONCE(vs_tpg[target]);
+   tpg = ACCESS_ONCE(vs_tpg[target]);
 
/* Target does not exist, fail the request */
-   if (unlikely(!tv_tpg)) {
+   if (unlikely(!tpg)) {
vhost_scsi_send_bad_target(vs, vq, head, out);
continue;
}
@@ -993,7 +993,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
for (i = 0; i < data_num; i++)
exp_data_len += vq->iov[data_first + i].iov_len;
 
-   tv_cmd = vhost_scsi_allocate_cmd(vq, tv_tpg, &v_req,
+   tv_cmd = vhost_scsi_allocate_cmd(vq, tpg, &v_req,
exp_data_len, data_direction);
if (IS_ERR(tv_cmd)) {
vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n",
@@ -1172,7 +1172,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
struct vhost_scsi_target *t)
 {
struct tcm_vhost_tport *tv_tport;
-   struct tcm_vhost_tpg *tv_tpg;
+   struct tcm_vhost_tpg *tpg;
struct tcm_vhost_tpg **vs_tpg;
struct vhost_virtqueue *vq;
int index, ret, i, len;
@@ -1199,32 +1199,32 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
if (vs->vs_tpg)
memcpy(vs_tpg, vs->vs_tpg, len);
 
-   list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
-   mutex_lock(&tv_tpg->tv_tpg_mutex);
-   if (!tv_tpg->tpg_nexus) {
-   mutex_unlock(&tv_tpg->tv_tpg_mutex);
+   list_for_each_entry(tpg, &tcm_vhost_list, tv_tpg_list) {
+   mutex_lock(&tpg->tv_tpg_mutex);
+   if (!tpg->tpg_nexus) {
+   mutex_unlock(&tpg->tv_tpg_mutex);
continue;
}
-   if (tv_tpg->tv_tpg_vhost_count != 0) {
-   mutex_unlock(&tv_tpg->tv_tpg_mutex);
+   if (tpg->tv_tpg_vhost_count != 0) {
+   mutex_unlock(&tpg->tv_tpg_mutex);
continue;
}
-   tv_tport = tv_tpg->tport;
+   tv_tport = tpg->tport;
 
if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
-   if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) {
+   if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
kfree(vs_tpg);
-   mutex_unlock(&tv_tpg->tv_tpg_mutex);
+   mutex_unlock(&tpg->tv_tpg_mutex);
ret = -EEXIST;
goto out;
}
-   tv_tpg->tv_tpg_vhost_count++;
-   tv_tpg->vhost_scsi = vs;
-   vs_tpg[tv_tpg->tport_tpgt] = tv_tpg;
+   tpg->tv_tpg_vhost_count++;
+   tpg->vhost_scsi = vs;
+   vs_tpg[tpg->tport_tpgt] = tpg;
smp_mb__after_atomic_inc();

[PATCH 3/5] vhost-scsi: Make func indention more consistent

2013-05-03 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 154 +--
 1 file changed, 88 insertions(+), 66 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d4798e1..d9781ed 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -333,11 +333,12 @@ static u32 tcm_vhost_get_default_depth(struct 
se_portal_group *se_tpg)
return 1;
 }
 
-static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
-   struct se_node_acl *se_nacl,
-   struct t10_pr_registration *pr_reg,
-   int *format_code,
-   unsigned char *buf)
+static u32
+tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl,
+ struct t10_pr_registration *pr_reg,
+ int *format_code,
+ unsigned char *buf)
 {
struct tcm_vhost_tpg *tpg = container_of(se_tpg,
struct tcm_vhost_tpg, se_tpg);
@@ -363,10 +364,11 @@ static u32 tcm_vhost_get_pr_transport_id(struct 
se_portal_group *se_tpg,
format_code, buf);
 }
 
-static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
-   struct se_node_acl *se_nacl,
-   struct t10_pr_registration *pr_reg,
-   int *format_code)
+static u32
+tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl,
+ struct t10_pr_registration *pr_reg,
+ int *format_code)
 {
struct tcm_vhost_tpg *tpg = container_of(se_tpg,
struct tcm_vhost_tpg, se_tpg);
@@ -392,10 +394,11 @@ static u32 tcm_vhost_get_pr_transport_id_len(struct 
se_portal_group *se_tpg,
format_code);
 }
 
-static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group 
*se_tpg,
-   const char *buf,
-   u32 *out_tid_len,
-   char **port_nexus_ptr)
+static char *
+tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
+   const char *buf,
+   u32 *out_tid_len,
+   char **port_nexus_ptr)
 {
struct tcm_vhost_tpg *tpg = container_of(se_tpg,
struct tcm_vhost_tpg, se_tpg);
@@ -421,8 +424,8 @@ static char *tcm_vhost_parse_pr_out_transport_id(struct 
se_portal_group *se_tpg,
port_nexus_ptr);
 }
 
-static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
-   struct se_portal_group *se_tpg)
+static struct se_node_acl *
+tcm_vhost_alloc_fabric_acl(struct se_portal_group *se_tpg)
 {
struct tcm_vhost_nacl *nacl;
 
@@ -435,8 +438,9 @@ static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
return &nacl->se_node_acl;
 }
 
-static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
-   struct se_node_acl *se_nacl)
+static void
+tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
+struct se_node_acl *se_nacl)
 {
struct tcm_vhost_nacl *nacl = container_of(se_nacl,
struct tcm_vhost_nacl, se_node_acl);
@@ -531,8 +535,9 @@ static void tcm_vhost_free_evt(struct vhost_scsi *vs, 
struct tcm_vhost_evt *evt)
kfree(evt);
 }
 
-static struct tcm_vhost_evt *tcm_vhost_allocate_evt(struct vhost_scsi *vs,
-   u32 event, u32 reason)
+static struct tcm_vhost_evt *
+tcm_vhost_allocate_evt(struct vhost_scsi *vs,
+  u32 event, u32 reason)
 {
struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
struct tcm_vhost_evt *evt;
@@ -576,8 +581,8 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd 
*tv_cmd)
kfree(tv_cmd);
 }
 
-static void tcm_vhost_do_evt_work(struct vhost_scsi *vs,
-   struct tcm_vhost_evt *evt)
+static void
+tcm_vhost_do_evt_work(struct vhost_scsi *vs, struct tcm_vhost_evt *evt)
 {
struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
struct virtio_scsi_event *event = &evt->event;
@@ -698,12 +703,12 @@ static void vhost_scsi_complete_cmd_work(struct 
vhost_work *work)
vhost_signal(&vs->dev, &vs->vqs[vq].vq);
 }
 
-static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
-   struct vhost_virtqueue *vq,
-   struct tcm_vhost_tpg *tv_tpg,
-   struct virtio_scsi_cmd_req *v_req,
-   u32 exp_data_len,
-   int data_direction)
+static struct tcm_vhost_cmd *
+vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq,
+   struct tcm_vhost_tpg *tv_tpg,
+   struct virtio_scsi_cmd_req *v_req,
+   u32 exp_data_len,
+   int data_direction)
 {
struct tcm_vhost_cmd *tv_cmd;
struct tcm_vhost_nexus *tv_nexus;
@@ -73

[PATCH 2/5] vhost-scsi: Rename struct vhost_scsi *s to *vs

2013-05-03 Thread Asias He
vs is used everywhere, make the naming more consistent.

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 56 ++--
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 02ddedd..d4798e1 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1342,63 +1342,63 @@ static int vhost_scsi_set_features(struct vhost_scsi 
*vs, u64 features)
 
 static int vhost_scsi_open(struct inode *inode, struct file *f)
 {
-   struct vhost_scsi *s;
+   struct vhost_scsi *vs;
struct vhost_virtqueue **vqs;
int r, i;
 
-   s = kzalloc(sizeof(*s), GFP_KERNEL);
-   if (!s)
+   vs = kzalloc(sizeof(*vs), GFP_KERNEL);
+   if (!vs)
return -ENOMEM;
 
vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL);
if (!vqs) {
-   kfree(s);
+   kfree(vs);
return -ENOMEM;
}
 
-   vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work);
-   vhost_work_init(&s->vs_event_work, tcm_vhost_evt_work);
+   vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work);
+   vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work);
 
-   s->vs_events_nr = 0;
-   s->vs_events_missed = false;
+   vs->vs_events_nr = 0;
+   vs->vs_events_missed = false;
 
-   vqs[VHOST_SCSI_VQ_CTL] = &s->vqs[VHOST_SCSI_VQ_CTL].vq;
-   vqs[VHOST_SCSI_VQ_EVT] = &s->vqs[VHOST_SCSI_VQ_EVT].vq;
-   s->vqs[VHOST_SCSI_VQ_CTL].vq.handle_kick = vhost_scsi_ctl_handle_kick;
-   s->vqs[VHOST_SCSI_VQ_EVT].vq.handle_kick = vhost_scsi_evt_handle_kick;
+   vqs[VHOST_SCSI_VQ_CTL] = &vs->vqs[VHOST_SCSI_VQ_CTL].vq;
+   vqs[VHOST_SCSI_VQ_EVT] = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
+   vs->vqs[VHOST_SCSI_VQ_CTL].vq.handle_kick = vhost_scsi_ctl_handle_kick;
+   vs->vqs[VHOST_SCSI_VQ_EVT].vq.handle_kick = vhost_scsi_evt_handle_kick;
for (i = VHOST_SCSI_VQ_IO; i < VHOST_SCSI_MAX_VQ; i++) {
-   vqs[i] = &s->vqs[i].vq;
-   s->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
+   vqs[i] = &vs->vqs[i].vq;
+   vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
}
-   r = vhost_dev_init(&s->dev, vqs, VHOST_SCSI_MAX_VQ);
+   r = vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ);
 
-   tcm_vhost_init_inflight(s, NULL);
+   tcm_vhost_init_inflight(vs, NULL);
 
if (r < 0) {
kfree(vqs);
-   kfree(s);
+   kfree(vs);
return r;
}
 
-   f->private_data = s;
+   f->private_data = vs;
return 0;
 }
 
 static int vhost_scsi_release(struct inode *inode, struct file *f)
 {
-   struct vhost_scsi *s = f->private_data;
+   struct vhost_scsi *vs = f->private_data;
struct vhost_scsi_target t;
 
-   mutex_lock(&s->dev.mutex);
-   memcpy(t.vhost_wwpn, s->vs_vhost_wwpn, sizeof(t.vhost_wwpn));
-   mutex_unlock(&s->dev.mutex);
-   vhost_scsi_clear_endpoint(s, &t);
-   vhost_dev_stop(&s->dev);
-   vhost_dev_cleanup(&s->dev, false);
+   mutex_lock(&vs->dev.mutex);
+   memcpy(t.vhost_wwpn, vs->vs_vhost_wwpn, sizeof(t.vhost_wwpn));
+   mutex_unlock(&vs->dev.mutex);
+   vhost_scsi_clear_endpoint(vs, &t);
+   vhost_dev_stop(&vs->dev);
+   vhost_dev_cleanup(&vs->dev, false);
/* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
-   vhost_scsi_flush(s);
-   kfree(s->dev.vqs);
-   kfree(s);
+   vhost_scsi_flush(vs);
+   kfree(vs->dev.vqs);
+   kfree(vs);
return 0;
 }
 
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 1/5] vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration

2013-05-03 Thread Asias He
It was needed when struct tcm_vhost_tpg is in tcm_vhost.h

Signed-off-by: Asias He 
---
 drivers/vhost/scsi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 2dcb94a..02ddedd 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -115,7 +115,6 @@ struct tcm_vhost_nacl {
struct se_node_acl se_node_acl;
 };
 
-struct vhost_scsi;
 struct tcm_vhost_tpg {
/* Vhost port target portal group tag for TCM */
u16 tport_tpgt;
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 0/5] vhost-scsi cleanup

2013-05-03 Thread Asias He
Asias He (5):
  vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration
  vhost-scsi: Rename struct vhost_scsi *s to *vs
  vhost-scsi: Make func indention more consistent
  vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg
  vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd

 drivers/vhost/scsi.c | 469 +++
 1 file changed, 245 insertions(+), 224 deletions(-)

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 4/4] vhost-net: Cleanup vhost_ubuf adn vhost_zcopy

2013-05-02 Thread Asias He
- Rename vhost_ubuf to vhost_net_ubuf
- Rename vhost_zcopy_mask to vhost_net_zcopy_mask
- Make funcs static

Signed-off-by: Asias He 
---
 drivers/vhost/net.c | 58 +++--
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index eb73217..4548c0b 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -70,7 +70,7 @@ enum {
VHOST_NET_VQ_MAX = 2,
 };
 
-struct vhost_ubuf_ref {
+struct vhost_net_ubuf_ref {
struct kref kref;
wait_queue_head_t wait;
struct vhost_virtqueue *vq;
@@ -93,7 +93,7 @@ struct vhost_net_virtqueue {
struct ubuf_info *ubuf_info;
/* Reference counting for outstanding ubufs.
 * Protected by vq mutex. Writers must also take device mutex. */
-   struct vhost_ubuf_ref *ubufs;
+   struct vhost_net_ubuf_ref *ubufs;
 };
 
 struct vhost_net {
@@ -110,24 +110,25 @@ struct vhost_net {
bool tx_flush;
 };
 
-static unsigned vhost_zcopy_mask __read_mostly;
+static unsigned vhost_net_zcopy_mask __read_mostly;
 
-void vhost_enable_zcopy(int vq)
+static void vhost_net_enable_zcopy(int vq)
 {
-   vhost_zcopy_mask |= 0x1 << vq;
+   vhost_net_zcopy_mask |= 0x1 << vq;
 }
 
-static void vhost_zerocopy_done_signal(struct kref *kref)
+static void vhost_net_zerocopy_done_signal(struct kref *kref)
 {
-   struct vhost_ubuf_ref *ubufs = container_of(kref, struct vhost_ubuf_ref,
-   kref);
+   struct vhost_net_ubuf_ref *ubufs;
+
+   ubufs = container_of(kref, struct vhost_net_ubuf_ref, kref);
wake_up(&ubufs->wait);
 }
 
-struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *vq,
-   bool zcopy)
+static struct vhost_net_ubuf_ref *
+vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy)
 {
-   struct vhost_ubuf_ref *ubufs;
+   struct vhost_net_ubuf_ref *ubufs;
/* No zero copy backend? Nothing to count. */
if (!zcopy)
return NULL;
@@ -140,14 +141,14 @@ struct vhost_ubuf_ref *vhost_ubuf_alloc(struct 
vhost_virtqueue *vq,
return ubufs;
 }
 
-void vhost_ubuf_put(struct vhost_ubuf_ref *ubufs)
+static void vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs)
 {
-   kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
+   kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
 }
 
-void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
+static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
 {
-   kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
+   kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
kfree(ubufs);
 }
@@ -159,7 +160,7 @@ static void vhost_net_clear_ubuf_info(struct vhost_net *n)
int i;
 
for (i = 0; i < n->dev.nvqs; ++i) {
-   zcopy = vhost_zcopy_mask & (0x1 << i);
+   zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (zcopy)
kfree(n->vqs[i].ubuf_info);
}
@@ -171,7 +172,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
int i;
 
for (i = 0; i < n->dev.nvqs; ++i) {
-   zcopy = vhost_zcopy_mask & (0x1 << i);
+   zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (!zcopy)
continue;
n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) *
@@ -183,7 +184,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
 
 err:
while (i--) {
-   zcopy = vhost_zcopy_mask & (0x1 << i);
+   zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (!zcopy)
continue;
kfree(n->vqs[i].ubuf_info);
@@ -305,7 +306,7 @@ static int vhost_zerocopy_signal_used(struct vhost_net *net,
 
 static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
 {
-   struct vhost_ubuf_ref *ubufs = ubuf->ctx;
+   struct vhost_net_ubuf_ref *ubufs = ubuf->ctx;
struct vhost_virtqueue *vq = ubufs->vq;
int cnt = atomic_read(&ubufs->kref.refcount);
 
@@ -322,7 +323,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, 
bool success)
/* set len to mark this desc buffers done DMA */
vq->heads[ubuf->desc].len = success ?
VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN;
-   vhost_ubuf_put(ubufs);
+   vhost_net_ubuf_put(ubufs);
 }
 
 /* Expects to be always run from workqueue - which acts as
@@ -345,7 +346,7 @@ static void handle_tx(struct vhost_net *net)
int err;
size_t hdr_size;
struct socket *sock;
-   struct vhost_ubuf_ref *uninitialized_var(ubufs);
+   struct vhost_ne

[PATCH 3/4] vhost-net: Free ubuf when vhost_dev_ioctl fails

2013-05-02 Thread Asias He
Free ubuf when vhost_dev_ioctl for VHOST_SET_OWNER fails.

Signed-off-by: Asias He 
---
 drivers/vhost/net.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index b2f6b41..eb73217 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -152,6 +152,19 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
kfree(ubufs);
 }
 
+static void vhost_net_clear_ubuf_info(struct vhost_net *n)
+{
+
+   bool zcopy;
+   int i;
+
+   for (i = 0; i < n->dev.nvqs; ++i) {
+   zcopy = vhost_zcopy_mask & (0x1 << i);
+   if (zcopy)
+   kfree(n->vqs[i].ubuf_info);
+   }
+}
+
 int vhost_net_set_ubuf_info(struct vhost_net *n)
 {
bool zcopy;
@@ -1069,10 +1082,13 @@ static long vhost_net_ioctl(struct file *f, unsigned 
int ioctl,
goto out;
}
r = vhost_dev_ioctl(&n->dev, ioctl, argp);
-   if (r == -ENOIOCTLCMD)
+   if (r == -ENOIOCTLCMD) {
r = vhost_vring_ioctl(&n->dev, ioctl, argp);
-   else
+   } else {
+   if (r < 0 && ioctl == VHOST_SET_OWNER)
+   vhost_net_clear_ubuf_info(n);
vhost_net_flush(n);
+   }
 out:
mutex_unlock(&n->dev.mutex);
return r;
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 2/4] vhost: Simplify dev->vqs[i] access

2013-05-02 Thread Asias He
Signed-off-by: Asias He 
---
 drivers/vhost/vhost.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 73100fe..0003bab 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -260,17 +260,16 @@ static void vhost_vq_free_iovecs(struct vhost_virtqueue 
*vq)
 /* Helper to allocate iovec buffers for all vqs. */
 static long vhost_dev_alloc_iovecs(struct vhost_dev *dev)
 {
+   struct vhost_virtqueue *vq;
int i;
 
for (i = 0; i < dev->nvqs; ++i) {
-   dev->vqs[i]->indirect = kmalloc(sizeof *dev->vqs[i]->indirect *
-  UIO_MAXIOV, GFP_KERNEL);
-   dev->vqs[i]->log = kmalloc(sizeof *dev->vqs[i]->log * 
UIO_MAXIOV,
- GFP_KERNEL);
-   dev->vqs[i]->heads = kmalloc(sizeof *dev->vqs[i]->heads *
-   UIO_MAXIOV, GFP_KERNEL);
-   if (!dev->vqs[i]->indirect || !dev->vqs[i]->log ||
-   !dev->vqs[i]->heads)
+   vq = dev->vqs[i];
+   vq->indirect = kmalloc(sizeof *vq->indirect * UIO_MAXIOV,
+  GFP_KERNEL);
+   vq->log = kmalloc(sizeof *vq->log * UIO_MAXIOV, GFP_KERNEL);
+   vq->heads = kmalloc(sizeof *vq->heads * UIO_MAXIOV, GFP_KERNEL);
+   if (!vq->indirect || !vq->log || !vq->heads)
goto err_nomem;
}
return 0;
@@ -292,6 +291,7 @@ static void vhost_dev_free_iovecs(struct vhost_dev *dev)
 long vhost_dev_init(struct vhost_dev *dev,
struct vhost_virtqueue **vqs, int nvqs)
 {
+   struct vhost_virtqueue *vq;
int i;
 
dev->vqs = vqs;
@@ -306,15 +306,16 @@ long vhost_dev_init(struct vhost_dev *dev,
dev->worker = NULL;
 
for (i = 0; i < dev->nvqs; ++i) {
-   dev->vqs[i]->log = NULL;
-   dev->vqs[i]->indirect = NULL;
-   dev->vqs[i]->heads = NULL;
-   dev->vqs[i]->dev = dev;
-   mutex_init(&dev->vqs[i]->mutex);
-   vhost_vq_reset(dev, dev->vqs[i]);
-   if (dev->vqs[i]->handle_kick)
-   vhost_poll_init(&dev->vqs[i]->poll,
-   dev->vqs[i]->handle_kick, POLLIN, dev);
+   vq = dev->vqs[i];
+   vq->log = NULL;
+   vq->indirect = NULL;
+   vq->heads = NULL;
+   vq->dev = dev;
+   mutex_init(&vq->mutex);
+   vhost_vq_reset(dev, vq);
+   if (vq->handle_kick)
+   vhost_poll_init(&vq->poll, vq->handle_kick,
+   POLLIN, dev);
}
 
return 0;
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 1/4] vhost: Remove comments for hdr in vhost.h

2013-05-02 Thread Asias He
It is supposed to be removed when hdr is moved into vhost_net_virtqueue.

Signed-off-by: Asias He 
---
 drivers/vhost/vhost.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 6fefebf..f9045b4 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -101,9 +101,6 @@ struct vhost_virtqueue {
u64 log_addr;
 
struct iovec iov[UIO_MAXIOV];
-   /* hdr is used to store the virtio header.
-* Since each iovec has >= 1 byte length, we never need more than
-* header length entries to store the header. */
struct iovec *indirect;
struct vring_used_elem *heads;
/* We use a kind of RCU to access private pointer.
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 0/4] vhost and vhost-net cleanups

2013-05-02 Thread Asias He
Asias He (4):
  vhost: Remove comments for hdr in vhost.h
  vhost: Simplify dev->vqs[i] access
  vhost-net: Free ubuf when vhost_dev_ioctl fails
  vhost-net: Cleanup vhost_ubuf adn vhost_zcopy

 drivers/vhost/net.c   | 76 +++
 drivers/vhost/vhost.c | 35 
 drivers/vhost/vhost.h |  3 --
 3 files changed, 65 insertions(+), 49 deletions(-)

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 3/3] vhost: Make vhost a separate module

2013-05-02 Thread Asias He
Currently, vhost-net and vhost-scsi are sharing the vhost core code.
However, vhost-scsi shares the code by including the vhost.c file
directly.

Making vhost a separate module makes it is easier to share code with
other vhost devices.

Signed-off-by: Asias He 
---
 drivers/vhost/Kconfig  |  8 
 drivers/vhost/Makefile |  3 ++-
 drivers/vhost/scsi.c   |  1 -
 drivers/vhost/vhost.c  | 50 +-
 drivers/vhost/vhost.h  |  2 ++
 5 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 8b9226d..017a1e8 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -1,6 +1,7 @@
 config VHOST_NET
tristate "Host kernel accelerator for virtio net"
depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP)
+   select VHOST
select VHOST_RING
---help---
  This kernel module can be loaded in host kernel to accelerate
@@ -13,6 +14,7 @@ config VHOST_NET
 config VHOST_SCSI
tristate "VHOST_SCSI TCM fabric driver"
depends on TARGET_CORE && EVENTFD && m
+   select VHOST
select VHOST_RING
default n
---help---
@@ -24,3 +26,9 @@ config VHOST_RING
---help---
  This option is selected by any driver which needs to access
  the host side of a virtio ring.
+
+config VHOST
+   tristate
+   ---help---
+ This option is selected by any driver which needs to access
+ the core of vhost.
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
index 654e9afb..e0441c3 100644
--- a/drivers/vhost/Makefile
+++ b/drivers/vhost/Makefile
@@ -1,7 +1,8 @@
 obj-$(CONFIG_VHOST_NET) += vhost_net.o
-vhost_net-y := vhost.o net.o
+vhost_net-y := net.o
 
 obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o
 vhost_scsi-y := scsi.o
 
 obj-$(CONFIG_VHOST_RING) += vringh.o
+obj-$(CONFIG_VHOST)+= vhost.o
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 5179f7a..2dcb94a 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -49,7 +49,6 @@
 #include 
 #include 
 
-#include "vhost.c"
 #include "vhost.h"
 
 #define TCM_VHOST_VERSION  "v0.1"
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 749b5ab..73100fe 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vhost.h"
 
@@ -66,6 +67,7 @@ void vhost_work_init(struct vhost_work *work, vhost_work_fn_t 
fn)
work->flushing = 0;
work->queue_seq = work->done_seq = 0;
 }
+EXPORT_SYMBOL_GPL(vhost_work_init);
 
 /* Init poll structure */
 void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
@@ -79,6 +81,7 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t 
fn,
 
vhost_work_init(&poll->work, fn);
 }
+EXPORT_SYMBOL_GPL(vhost_poll_init);
 
 /* Start polling a file. We add ourselves to file's wait queue. The caller must
  * keep a reference to a file until after vhost_poll_stop is called. */
@@ -101,6 +104,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file 
*file)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(vhost_poll_start);
 
 /* Stop polling a file. After this function returns, it becomes safe to drop 
the
  * file reference. You must also flush afterwards. */
@@ -111,6 +115,7 @@ void vhost_poll_stop(struct vhost_poll *poll)
poll->wqh = NULL;
}
 }
+EXPORT_SYMBOL_GPL(vhost_poll_stop);
 
 static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
unsigned seq)
@@ -123,7 +128,7 @@ static bool vhost_work_seq_done(struct vhost_dev *dev, 
struct vhost_work *work,
return left <= 0;
 }
 
-static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
+void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
 {
unsigned seq;
int flushing;
@@ -138,6 +143,7 @@ static void vhost_work_flush(struct vhost_dev *dev, struct 
vhost_work *work)
spin_unlock_irq(&dev->work_lock);
BUG_ON(flushing < 0);
 }
+EXPORT_SYMBOL_GPL(vhost_work_flush);
 
 /* Flush any work that has been scheduled. When calling this, don't hold any
  * locks that are also used by the callback. */
@@ -145,6 +151,7 @@ void vhost_poll_flush(struct vhost_poll *poll)
 {
vhost_work_flush(poll->dev, &poll->work);
 }
+EXPORT_SYMBOL_GPL(vhost_poll_flush);
 
 void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
 {
@@ -158,11 +165,13 @@ void vhost_work_queue(struct vhost_dev *dev, struct 
vhost_work *work)
}
spin_unlock_irqrestore(&dev->work_lock, flags);
 }
+EXPORT_SYMBOL_GPL(vhost_work_queue);
 
 void vhost_poll_queue(struct vhost_poll *poll)
 {
vhost_work_queue(poll->dev, &poll->work);
 }
+

[PATCH 2/3] vhost: Move VHOST_NET_FEATURES to net.c

2013-05-02 Thread Asias He
vhost.h should not depend on device specific marcos like
VHOST_NET_F_VIRTIO_NET_HDR and VIRTIO_NET_F_MRG_RXBUF.

Signed-off-by: Asias He 
---
 drivers/vhost/net.c   | 6 ++
 drivers/vhost/vhost.h | 3 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index a3645bd..b2f6b41 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -59,6 +59,12 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"
 #define VHOST_DMA_IS_DONE(len) ((len) >= VHOST_DMA_DONE_LEN)
 
 enum {
+   VHOST_NET_FEATURES = VHOST_FEATURES |
+(1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
+(1ULL << VIRTIO_NET_F_MRG_RXBUF),
+};
+
+enum {
VHOST_NET_VQ_RX = 0,
VHOST_NET_VQ_TX = 1,
VHOST_NET_VQ_MAX = 2,
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 4330209..cc9ebf0 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -177,9 +177,6 @@ enum {
 (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
 (1ULL << VIRTIO_RING_F_EVENT_IDX) |
 (1ULL << VHOST_F_LOG_ALL),
-   VHOST_NET_FEATURES = VHOST_FEATURES |
-(1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
-(1ULL << VIRTIO_NET_F_MRG_RXBUF),
 };
 
 static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 1/3] vhost: Remove vhost_enable_zcopy in vhost.h

2013-05-02 Thread Asias He
It is net.c specific.

Signed-off-by: Asias He 
---
 drivers/vhost/vhost.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index b58f4ae..4330209 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -191,7 +191,4 @@ static inline int vhost_has_feature(struct vhost_dev *dev, 
int bit)
acked_features = rcu_dereference_index_check(dev->acked_features, 1);
return acked_features & (1 << bit);
 }
-
-void vhost_enable_zcopy(int vq);
-
 #endif
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 0/3] vhost cleanups and separate module

2013-05-02 Thread Asias He
Asias He (3):
  vhost: Remove vhost_enable_zcopy in vhost.h
  vhost: Move VHOST_NET_FEATURES to net.c
  vhost: Make vhost a separate module

 drivers/vhost/Kconfig  |  8 
 drivers/vhost/Makefile |  3 ++-
 drivers/vhost/net.c|  6 ++
 drivers/vhost/scsi.c   |  1 -
 drivers/vhost/vhost.c  | 50 +-
 drivers/vhost/vhost.h  |  8 ++--
 6 files changed, 67 insertions(+), 9 deletions(-)

-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v6 2/2] tcm_vhost: Wait for pending requests in vhost_scsi_flush()

2013-05-01 Thread Asias He
On Sun, Apr 28, 2013 at 03:11:49PM +0300, Michael S. Tsirkin wrote:
> On Sun, Apr 28, 2013 at 06:55:20PM +0800, Asias He wrote:
> > On Sun, Apr 28, 2013 at 12:27:15PM +0300, Michael S. Tsirkin wrote:
> > > On Sun, Apr 28, 2013 at 04:52:08PM +0800, Asias He wrote:
> > > > On Sun, Apr 28, 2013 at 11:24:00AM +0300, Michael S. Tsirkin wrote:
> > > > > On Sun, Apr 28, 2013 at 03:48:23PM +0800, Asias He wrote:
> > > > > > On Sat, Apr 27, 2013 at 10:40:41PM +0300, Michael S. Tsirkin wrote:
> > > > > > > On Sat, Apr 27, 2013 at 11:16:49AM +0800, Asias He wrote:
> > > > > > > > Unlike tcm_vhost_evt requests, tcm_vhost_cmd requests are 
> > > > > > > > passed to the
> > > > > > > > target core system, we can not make sure all the pending 
> > > > > > > > requests will
> > > > > > > > be finished by flushing the virt queue.
> > > > > > > > 
> > > > > > > > In this patch, we do refcount for every tcm_vhost_cmd requests 
> > > > > > > > to make
> > > > > > > > vhost_scsi_flush() wait for all the pending requests issued 
> > > > > > > > before the
> > > > > > > > flush operation to be finished.
> > > > > > > > 
> > > > > > > > This is useful when we call vhost_scsi_clear_endpoint() to stop
> > > > > > > > tcm_vhost. No new requests will be passed to target core system 
> > > > > > > > because
> > > > > > > > we clear the endpoint by setting vs_tpg to NULL. And we wait 
> > > > > > > > for all the
> > > > > > > > old requests. These guarantee no requests will be leaked and 
> > > > > > > > existing
> > > > > > > > requests will be completed.
> > > > > > > > 
> > > > > > > > Signed-off-by: Asias He 
> > > > > > > > ---
> > > > > > > >  drivers/vhost/tcm_vhost.c | 90 
> > > > > > > > ++-
> > > > > > > >  drivers/vhost/tcm_vhost.h |  3 ++
> > > > > > > >  2 files changed, 92 insertions(+), 1 deletion(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/vhost/tcm_vhost.c 
> > > > > > > > b/drivers/vhost/tcm_vhost.c
> > > > > > > > index 99d3480..afb5308 100644
> > > > > > > > --- a/drivers/vhost/tcm_vhost.c
> > > > > > > > +++ b/drivers/vhost/tcm_vhost.c
> > > > > > > > @@ -74,8 +74,19 @@ enum {
> > > > > > > >  #define VHOST_SCSI_MAX_VQ  128
> > > > > > > >  #define VHOST_SCSI_MAX_EVENT   128
> > > > > > > >  
> > > > > > > > +struct vhost_scsi_inflight {
> > > > > > > > +   /* Wait for the flush operation to finish */
> > > > > > > > +   struct completion comp;
> > > > > > > > +   /* Refcount for the inflight reqs */
> > > > > > > > +   struct kref kref;
> > > > > > > > +};
> > > > > > > > +
> > > > > > > >  struct vhost_scsi_virtqueue {
> > > > > > > > struct vhost_virtqueue vq;
> > > > > > > > +   /* Track inflight reqs, protected by vq->mutex */
> > > > > > > 
> > > > > > > Actually, it's protected by dev mutex: you drop
> > > > > > > vq mutex before flush.
> > > > > > 
> > > > > > It is protected by both dev mutex and vq mutex.
> > > > > > 
> > > > > > take vq mutex -> vhost_scsi_allocate_cmd -> tcm_vhost_get_inflight 
> > > > > > ->
> > > > > > access inflights[] and inflight_idx.
> > > > > > 
> > > > > > The dev mutex guarantees only one flush operation is in progress.
> > > > > 
> > > > > That's what I am saying. but vq mutex does nothing for inflights,
> > > > > it merely protects inflight_idx.
> > > > 
> > > > Well, what do you want to proceed here, drop the comment? 
> > > 
> > > Say something like
> > > "dev mutex guaran

Re: [PATCH 0/3] vhost-scsi: file renames

2013-05-01 Thread Asias He
On Thu, May 02, 2013 at 04:45:30AM +0300, Michael S. Tsirkin wrote:
> This reorgs the files a bit, renaming tcm_vhost to
> vhost_scsi as that's how userspace refers to it.
> While at it, cleanup some leftovers from when it was a
> staging driver.
> 
> Signed-off-by: Michael S. Tsirkin 

Reviewed-by: Asias He 

> 
> Michael S. Tsirkin (3):
>   vhost: src file renames
>   tcm_vhost: header split up
>   vhost_scsi: module rename
> 
>  drivers/vhost/Kconfig |  10 ++-
>  drivers/vhost/Kconfig.tcm |   6 --
>  drivers/vhost/Makefile|   3 +-
>  drivers/vhost/{tcm_vhost.c => scsi.c} | 115 ++---
>  drivers/vhost/tcm_vhost.h | 131 
> --
>  include/uapi/linux/vhost.h|  28 
>  6 files changed, 143 insertions(+), 150 deletions(-)
>  delete mode 100644 drivers/vhost/Kconfig.tcm
>  rename drivers/vhost/{tcm_vhost.c => scsi.c} (94%)
>  delete mode 100644 drivers/vhost/tcm_vhost.h
> 
> -- 
> MST

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] tcm_vhost: Add vhost_scsi as an alias for tcm_vhost

2013-05-01 Thread Asias He
On Wed, May 01, 2013 at 09:42:22AM +0300, Michael S. Tsirkin wrote:
> On Sat, Apr 27, 2013 at 11:42:09AM +0800, Asias He wrote:
> > Signed-off-by: Asias He 
> 
> 
> Nicholas, thoughts?
> How about we move tcm_vhost.c to scsi.c
> call module vhost_scsi and add tcm_vhost as an alias?

This is even better ;-)

> If not - want this alias in?
> 
> > ---
> >  drivers/vhost/tcm_vhost.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
> > index 1677238..bddc39a 100644
> > --- a/drivers/vhost/tcm_vhost.c
> > +++ b/drivers/vhost/tcm_vhost.c
> > @@ -1928,5 +1928,6 @@ static void tcm_vhost_exit(void)
> >  
> >  MODULE_DESCRIPTION("TCM_VHOST series fabric driver");
> >  MODULE_LICENSE("GPL");
> > +MODULE_ALIAS("vhost_scsi");
> >  module_init(tcm_vhost_init);
> >  module_exit(tcm_vhost_exit);
> > -- 
> > 1.8.1.4

-- 
Asias
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v6 2/2] tcm_vhost: Wait for pending requests in vhost_scsi_flush()

2013-04-28 Thread Asias He
On Sun, Apr 28, 2013 at 12:27:15PM +0300, Michael S. Tsirkin wrote:
> On Sun, Apr 28, 2013 at 04:52:08PM +0800, Asias He wrote:
> > On Sun, Apr 28, 2013 at 11:24:00AM +0300, Michael S. Tsirkin wrote:
> > > On Sun, Apr 28, 2013 at 03:48:23PM +0800, Asias He wrote:
> > > > On Sat, Apr 27, 2013 at 10:40:41PM +0300, Michael S. Tsirkin wrote:
> > > > > On Sat, Apr 27, 2013 at 11:16:49AM +0800, Asias He wrote:
> > > > > > Unlike tcm_vhost_evt requests, tcm_vhost_cmd requests are passed to 
> > > > > > the
> > > > > > target core system, we can not make sure all the pending requests 
> > > > > > will
> > > > > > be finished by flushing the virt queue.
> > > > > > 
> > > > > > In this patch, we do refcount for every tcm_vhost_cmd requests to 
> > > > > > make
> > > > > > vhost_scsi_flush() wait for all the pending requests issued before 
> > > > > > the
> > > > > > flush operation to be finished.
> > > > > > 
> > > > > > This is useful when we call vhost_scsi_clear_endpoint() to stop
> > > > > > tcm_vhost. No new requests will be passed to target core system 
> > > > > > because
> > > > > > we clear the endpoint by setting vs_tpg to NULL. And we wait for 
> > > > > > all the
> > > > > > old requests. These guarantee no requests will be leaked and 
> > > > > > existing
> > > > > > requests will be completed.
> > > > > > 
> > > > > > Signed-off-by: Asias He 
> > > > > > ---
> > > > > >  drivers/vhost/tcm_vhost.c | 90 
> > > > > > ++-
> > > > > >  drivers/vhost/tcm_vhost.h |  3 ++
> > > > > >  2 files changed, 92 insertions(+), 1 deletion(-)
> > > > > > 
> > > > > > diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
> > > > > > index 99d3480..afb5308 100644
> > > > > > --- a/drivers/vhost/tcm_vhost.c
> > > > > > +++ b/drivers/vhost/tcm_vhost.c
> > > > > > @@ -74,8 +74,19 @@ enum {
> > > > > >  #define VHOST_SCSI_MAX_VQ  128
> > > > > >  #define VHOST_SCSI_MAX_EVENT   128
> > > > > >  
> > > > > > +struct vhost_scsi_inflight {
> > > > > > +   /* Wait for the flush operation to finish */
> > > > > > +   struct completion comp;
> > > > > > +   /* Refcount for the inflight reqs */
> > > > > > +   struct kref kref;
> > > > > > +};
> > > > > > +
> > > > > >  struct vhost_scsi_virtqueue {
> > > > > > struct vhost_virtqueue vq;
> > > > > > +   /* Track inflight reqs, protected by vq->mutex */
> > > > > 
> > > > > Actually, it's protected by dev mutex: you drop
> > > > > vq mutex before flush.
> > > > 
> > > > It is protected by both dev mutex and vq mutex.
> > > > 
> > > > take vq mutex -> vhost_scsi_allocate_cmd -> tcm_vhost_get_inflight ->
> > > > access inflights[] and inflight_idx.
> > > > 
> > > > The dev mutex guarantees only one flush operation is in progress.
> > > 
> > > That's what I am saying. but vq mutex does nothing for inflights,
> > > it merely protects inflight_idx.
> > 
> > Well, what do you want to proceed here, drop the comment? 
> 
> Say something like
> "dev mutex guarantees only one flush operation is in progress".
> 
> > > > > > +   struct vhost_scsi_inflight inflights[2];
> > > > > > +   /* Indicate current inflight in use, protected by vq->mutex */
> > > > > > +   int inflight_idx;
> > > > > >  };
> > > > > >  
> > > > > 
> > > > > I'd be happier with a dynamically allocated inflights,
> > > > > and simply pass it in to vhost_scsi_flush.
> > > > > I guess we can do this in a follow-up cleanup.
> > > > 
> > > > No way to 100% guarantee the allocation will success, even if using
> > > > mempool. So we need to check allocation failure anyway.
> > > > 
> > > > With dynamic allocation, we can allocate inflight and check before we do
> 

Re: [PATCH v6 2/2] tcm_vhost: Wait for pending requests in vhost_scsi_flush()

2013-04-28 Thread Asias He
On Sun, Apr 28, 2013 at 11:24:00AM +0300, Michael S. Tsirkin wrote:
> On Sun, Apr 28, 2013 at 03:48:23PM +0800, Asias He wrote:
> > On Sat, Apr 27, 2013 at 10:40:41PM +0300, Michael S. Tsirkin wrote:
> > > On Sat, Apr 27, 2013 at 11:16:49AM +0800, Asias He wrote:
> > > > Unlike tcm_vhost_evt requests, tcm_vhost_cmd requests are passed to the
> > > > target core system, we can not make sure all the pending requests will
> > > > be finished by flushing the virt queue.
> > > > 
> > > > In this patch, we do refcount for every tcm_vhost_cmd requests to make
> > > > vhost_scsi_flush() wait for all the pending requests issued before the
> > > > flush operation to be finished.
> > > > 
> > > > This is useful when we call vhost_scsi_clear_endpoint() to stop
> > > > tcm_vhost. No new requests will be passed to target core system because
> > > > we clear the endpoint by setting vs_tpg to NULL. And we wait for all the
> > > > old requests. These guarantee no requests will be leaked and existing
> > > > requests will be completed.
> > > > 
> > > > Signed-off-by: Asias He 
> > > > ---
> > > >  drivers/vhost/tcm_vhost.c | 90 
> > > > ++-
> > > >  drivers/vhost/tcm_vhost.h |  3 ++
> > > >  2 files changed, 92 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
> > > > index 99d3480..afb5308 100644
> > > > --- a/drivers/vhost/tcm_vhost.c
> > > > +++ b/drivers/vhost/tcm_vhost.c
> > > > @@ -74,8 +74,19 @@ enum {
> > > >  #define VHOST_SCSI_MAX_VQ  128
> > > >  #define VHOST_SCSI_MAX_EVENT   128
> > > >  
> > > > +struct vhost_scsi_inflight {
> > > > +   /* Wait for the flush operation to finish */
> > > > +   struct completion comp;
> > > > +   /* Refcount for the inflight reqs */
> > > > +   struct kref kref;
> > > > +};
> > > > +
> > > >  struct vhost_scsi_virtqueue {
> > > > struct vhost_virtqueue vq;
> > > > +   /* Track inflight reqs, protected by vq->mutex */
> > > 
> > > Actually, it's protected by dev mutex: you drop
> > > vq mutex before flush.
> > 
> > It is protected by both dev mutex and vq mutex.
> > 
> > take vq mutex -> vhost_scsi_allocate_cmd -> tcm_vhost_get_inflight ->
> > access inflights[] and inflight_idx.
> > 
> > The dev mutex guarantees only one flush operation is in progress.
> 
> That's what I am saying. but vq mutex does nothing for inflights,
> it merely protects inflight_idx.

Well, what do you want to proceed here, drop the comment? 

> > > > +   struct vhost_scsi_inflight inflights[2];
> > > > +   /* Indicate current inflight in use, protected by vq->mutex */
> > > > +   int inflight_idx;
> > > >  };
> > > >  
> > > 
> > > I'd be happier with a dynamically allocated inflights,
> > > and simply pass it in to vhost_scsi_flush.
> > > I guess we can do this in a follow-up cleanup.
> > 
> > No way to 100% guarantee the allocation will success, even if using
> > mempool. So we need to check allocation failure anyway.
> > 
> > With dynamic allocation, we can allocate inflight and check before we do
> > anything in the vhost_scsi_flush calling chain. Now we have 4 places
> > calling vhost_scsi_flush. We need to add error handing code everywhere.
> > 
> > 1) vhost_scsi_release
> > 2) vhost_scsi_set_endpoint
> > 3) vhost_scsi_clear_endpoint
> > 4) vhost_scsi_set_features
> > 
> > IMO, The static one works better.
> 
> Error handling is a standard easily understandable thing.
> A custom locking scheme - not at all. Even when we think it's right,
> above we are still arguing how to properly document it.

Allocating it dynamically or not does not changing the locking scheme,
no? 

> > > >  struct vhost_scsi {
> > > > @@ -111,6 +122,59 @@ static int iov_num_pages(struct iovec *iov)
> > > >((unsigned long)iov->iov_base & PAGE_MASK)) >> 
> > > > PAGE_SHIFT;
> > > >  }
> > > >  
> > > > +void tcm_vhost_done_inflight(struct kref *kref)
> > > > +{
> > > > +   struct vhost_scsi_inflight *inflight;
> > > > +
> > > > + 

Re: [PATCH v6 2/2] tcm_vhost: Wait for pending requests in vhost_scsi_flush()

2013-04-28 Thread Asias He
On Sat, Apr 27, 2013 at 10:40:41PM +0300, Michael S. Tsirkin wrote:
> On Sat, Apr 27, 2013 at 11:16:49AM +0800, Asias He wrote:
> > Unlike tcm_vhost_evt requests, tcm_vhost_cmd requests are passed to the
> > target core system, we can not make sure all the pending requests will
> > be finished by flushing the virt queue.
> > 
> > In this patch, we do refcount for every tcm_vhost_cmd requests to make
> > vhost_scsi_flush() wait for all the pending requests issued before the
> > flush operation to be finished.
> > 
> > This is useful when we call vhost_scsi_clear_endpoint() to stop
> > tcm_vhost. No new requests will be passed to target core system because
> > we clear the endpoint by setting vs_tpg to NULL. And we wait for all the
> > old requests. These guarantee no requests will be leaked and existing
> > requests will be completed.
> > 
> > Signed-off-by: Asias He 
> > ---
> >  drivers/vhost/tcm_vhost.c | 90 
> > ++-
> >  drivers/vhost/tcm_vhost.h |  3 ++
> >  2 files changed, 92 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
> > index 99d3480..afb5308 100644
> > --- a/drivers/vhost/tcm_vhost.c
> > +++ b/drivers/vhost/tcm_vhost.c
> > @@ -74,8 +74,19 @@ enum {
> >  #define VHOST_SCSI_MAX_VQ  128
> >  #define VHOST_SCSI_MAX_EVENT   128
> >  
> > +struct vhost_scsi_inflight {
> > +   /* Wait for the flush operation to finish */
> > +   struct completion comp;
> > +   /* Refcount for the inflight reqs */
> > +   struct kref kref;
> > +};
> > +
> >  struct vhost_scsi_virtqueue {
> > struct vhost_virtqueue vq;
> > +   /* Track inflight reqs, protected by vq->mutex */
> 
> Actually, it's protected by dev mutex: you drop
> vq mutex before flush.

It is protected by both dev mutex and vq mutex.

take vq mutex -> vhost_scsi_allocate_cmd -> tcm_vhost_get_inflight ->
access inflights[] and inflight_idx.

The dev mutex guarantees only one flush operation is in progress.

> > +   struct vhost_scsi_inflight inflights[2];
> > +   /* Indicate current inflight in use, protected by vq->mutex */
> > +   int inflight_idx;
> >  };
> >  
> 
> I'd be happier with a dynamically allocated inflights,
> and simply pass it in to vhost_scsi_flush.
> I guess we can do this in a follow-up cleanup.

No way to 100% guarantee the allocation will success, even if using
mempool. So we need to check allocation failure anyway.

With dynamic allocation, we can allocate inflight and check before we do
anything in the vhost_scsi_flush calling chain. Now we have 4 places
calling vhost_scsi_flush. We need to add error handing code everywhere.

1) vhost_scsi_release
2) vhost_scsi_set_endpoint
3) vhost_scsi_clear_endpoint
4) vhost_scsi_set_features

IMO, The static one works better.

> >  struct vhost_scsi {
> > @@ -111,6 +122,59 @@ static int iov_num_pages(struct iovec *iov)
> >((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT;
> >  }
> >  
> > +void tcm_vhost_done_inflight(struct kref *kref)
> > +{
> > +   struct vhost_scsi_inflight *inflight;
> > +
> > +   inflight = container_of(kref, struct vhost_scsi_inflight, kref);
> > +   complete(&inflight->comp);
> > +}
> > +
> > +static void tcm_vhost_init_inflight(struct vhost_scsi *vs,
> > +   struct vhost_scsi_inflight *old_inflight[])
> > +{
> > +   struct vhost_scsi_inflight *new_inflight;
> > +   struct vhost_virtqueue *vq;
> > +   int idx, i;
> > +
> > +   for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
> > +   vq = &vs->vqs[i].vq;
> > +
> > +   mutex_lock(&vq->mutex);
> > +
> > +   /* store old infight */
> > +   idx = vs->vqs[i].inflight_idx;
> > +   if (old_inflight)
> > +   old_inflight[i] = &vs->vqs[i].inflights[idx];
> > +
> > +   /* setup new infight */
> > +   vs->vqs[i].inflight_idx = idx ^ 1;
> > +   new_inflight = &vs->vqs[i].inflights[idx ^ 1];
> > +   kref_init(&new_inflight->kref);
> > +   init_completion(&new_inflight->comp);
> > +
> > +   mutex_unlock(&vq->mutex);
> > +   }
> > +}
> > +
> > +static struct vhost_scsi_inflight *
> > +tcm_vhost_get_inflight(struct vhost_virtqueue *vq)
> > +{
> > +   struct vhost_scsi_inflight *inflight;
> > +   struct vhost_scsi_virtqu

[PATCH] vhost: Move vhost-net zerocopy support fields to net.c

2013-04-27 Thread Asias He
On top of 'vhost: Allow device specific fields per vq', we can move device
specific fields to device virt queue from vhost virt queue.

Signed-off-by: Asias He 
---
 drivers/vhost/net.c   | 164 +++---
 drivers/vhost/vhost.c |  57 +-
 drivers/vhost/vhost.h |  22 ---
 3 files changed, 142 insertions(+), 101 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 683d9a1..c194045 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -70,8 +70,24 @@ enum vhost_net_poll_state {
VHOST_NET_POLL_STOPPED = 2,
 };
 
+struct vhost_ubuf_ref {
+   struct kref kref;
+   wait_queue_head_t wait;
+   struct vhost_virtqueue *vq;
+};
+
 struct vhost_net_virtqueue {
struct vhost_virtqueue vq;
+   /* vhost zerocopy support fields below: */
+   /* last used idx for outstanding DMA zerocopy buffers */
+   int upend_idx;
+   /* first used idx for DMA done zerocopy buffers */
+   int done_idx;
+   /* an array of userspace buffers info */
+   struct ubuf_info *ubuf_info;
+   /* Reference counting for outstanding ubufs.
+* Protected by vq mutex. Writers must also take device mutex. */
+   struct vhost_ubuf_ref *ubufs;
 };
 
 struct vhost_net {
@@ -92,6 +108,88 @@ struct vhost_net {
bool tx_flush;
 };
 
+static unsigned vhost_zcopy_mask __read_mostly;
+
+void vhost_enable_zcopy(int vq)
+{
+   vhost_zcopy_mask |= 0x1 << vq;
+}
+
+static void vhost_zerocopy_done_signal(struct kref *kref)
+{
+   struct vhost_ubuf_ref *ubufs = container_of(kref, struct vhost_ubuf_ref,
+   kref);
+   wake_up(&ubufs->wait);
+}
+
+struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *vq,
+   bool zcopy)
+{
+   struct vhost_ubuf_ref *ubufs;
+   /* No zero copy backend? Nothing to count. */
+   if (!zcopy)
+   return NULL;
+   ubufs = kmalloc(sizeof(*ubufs), GFP_KERNEL);
+   if (!ubufs)
+   return ERR_PTR(-ENOMEM);
+   kref_init(&ubufs->kref);
+   init_waitqueue_head(&ubufs->wait);
+   ubufs->vq = vq;
+   return ubufs;
+}
+
+void vhost_ubuf_put(struct vhost_ubuf_ref *ubufs)
+{
+   kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
+}
+
+void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)
+{
+   kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
+   wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
+   kfree(ubufs);
+}
+
+int vhost_net_set_ubuf_info(struct vhost_net *n)
+{
+   bool zcopy;
+   int i;
+
+   for (i = 0; i < n->dev.nvqs; ++i) {
+   zcopy = vhost_zcopy_mask & (0x1 << i);
+   if (!zcopy)
+   continue;
+   n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) *
+ UIO_MAXIOV, GFP_KERNEL);
+   if  (!n->vqs[i].ubuf_info)
+   goto err;
+   }
+   return 0;
+
+err:
+   while (i--) {
+   zcopy = vhost_zcopy_mask & (0x1 << i);
+   if (!zcopy)
+   continue;
+   kfree(n->vqs[i].ubuf_info);
+   }
+   return -ENOMEM;
+}
+
+void vhost_net_reset_ubuf_info(struct vhost_net *n)
+{
+   int i;
+
+   for (i = 0; i < VHOST_NET_VQ_MAX; i++) {
+   n->vqs[i].done_idx = 0;
+   n->vqs[i].upend_idx = 0;
+   n->vqs[i].ubufs = NULL;
+   kfree(n->vqs[i].ubuf_info);
+   n->vqs[i].ubuf_info = NULL;
+   }
+
+}
+
 static void vhost_net_tx_packet(struct vhost_net *net)
 {
++net->tx_packets;
@@ -189,10 +287,12 @@ static int tx_poll_start(struct vhost_net *net, struct 
socket *sock)
 static int vhost_zerocopy_signal_used(struct vhost_net *net,
  struct vhost_virtqueue *vq)
 {
+   struct vhost_net_virtqueue *nvq =
+   container_of(vq, struct vhost_net_virtqueue, vq);
int i;
int j = 0;
 
-   for (i = vq->done_idx; i != vq->upend_idx; i = (i + 1) % UIO_MAXIOV) {
+   for (i = nvq->done_idx; i != nvq->upend_idx; i = (i + 1) % UIO_MAXIOV) {
if (vq->heads[i].len == VHOST_DMA_FAILED_LEN)
vhost_net_tx_err(net);
if (VHOST_DMA_IS_DONE(vq->heads[i].len)) {
@@ -204,7 +304,7 @@ static int vhost_zerocopy_signal_used(struct vhost_net *net,
break;
}
if (j)
-   vq->done_idx = i;
+   nvq->done_idx = i;
return j;
 }
 
@@ -235,6 +335,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, 
bool success)
 static void handle_tx(struct vhost_net *net)
 {
struct vhost_virtqueue 

  1   2   3   4   5   >