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

2014-07-04 Thread Asias He
.
  
  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


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

2014-07-04 Thread Asias He
From: Asias He as...@redhat.com

Signed-off-by: Asias He as...@redhat.com
---
 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 2/7] VSOCK: Add dgram_skb to vsock_sock

2014-07-04 Thread Asias He
From: Asias He as...@redhat.com

Signed-off-by: Asias He as...@redhat.com
---
 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 7/7] Disable debug

2014-07-04 Thread Asias He
From: Asias He as...@redhat.com

Signed-off-by: Asias He as...@redhat.com
---
 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 6/7] VSOCK: Add Makefile and Kconfig

2014-07-04 Thread Asias He
From: Asias He as...@redhat.com

Enable virtio-vsock and vhost-vsock.

Signed-off-by: Asias He as...@redhat.com
---
 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 5/7] VSOCK: Introduce vhost-vsock.ko

2014-07-04 Thread Asias He
From: Asias He as...@redhat.com

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

Signed-off-by: Asias He as...@redhat.com
---
 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 as...@redhat.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include linux/miscdevice.h
+#include linux/module.h
+#include linux/mutex.h
+#include net/sock.h
+#include linux/virtio_vsock.h
+#include linux/vhost.h
+
+#include net/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 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);
+   vsock-total_tx_buf -= pkt-len;
+
+   sk = sk_vsock(pkt-trans-vsk

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

2014-07-04 Thread Asias He
From: Asias He as...@redhat.com

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

Signed-off-by: Asias He as...@redhat.com
---
 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 as...@redhat.com
+ *
+ * Some of the code is take from Gerd Hoffmann kra...@redhat.com's
+ * early virtio-vsock proof-of-concept bits.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include linux/spinlock.h
+#include linux/module.h
+#include linux/list.h
+#include linux/virtio.h
+#include linux/virtio_ids.h
+#include linux/virtio_config.h
+#include linux/virtio_vsock.h
+#include net/sock.h
+#include linux/mutex.h
+#include net/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;
+   /* 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);
+   while ((ret

[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 as...@redhat.com
---
 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 n...@linux-iscsi.org
 
 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 stefa...@redhat.com
 Cc: Michael S. Tsirkin m...@redhat.com
 Cc: Asias He as...@redhat.com
 Cc: sta...@vger.kernel.org # 3.6+
 Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org

Reviewed-by: Asias He as...@redhat.com

 ---
  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 alo...@stratoscale.com
 Signed-off-by: Michael S. Tsirkin m...@redhat.com

Reviewed-by: Asias He as...@redhat.com

 ---
 
 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


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 as...@redhat.com
 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 as...@redhat.com
 
 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 as...@redhat.com
---
 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 linux/eventfd.h
 #include linux/vhost.h
-#include linux/socket.h /* memcpy_fromiovec */
 #include linux/mm.h
 #include linux/mmu_context.h
 #include linux/miscdevice.h
-- 
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: [8179b29f] __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:[8179b29f]  [8179b29f] 
__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:
  [8179b37d] virtscsi_set_affinity+0x2d/0x40
  [8179b3b6] virtscsi_remove_vqs+0x26/0x50
  [8179c7d2] virtscsi_remove+0x82/0xa0
  [814cb6b2] virtio_dev_remove+0x22/0x70
  [8167ca49] __device_release_driver+0x69/0xd0
  [8167cb9d] device_release_driver+0x2d/0x40
  [8167bb96] bus_remove_device+0x116/0x150
  [81679936] device_del+0x126/0x1e0
  [81679a06] device_unregister+0x16/0x30
  [814cb889] unregister_virtio_device+0x19/0x30
  [814cdad6] virtio_pci_remove+0x36/0x80
  [81464ae7] pci_device_remove+0x37/0x70
  [8167ca49] __device_release_driver+0x69/0xd0
  [8167cb9d] device_release_driver+0x2d/0x40
  [8167bb96] bus_remove_device+0x116/0x150
  [81679936] device_del+0x126/0x1e0
  [8145edfc] pci_stop_bus_device+0x9c/0xb0
  [8145f036] pci_stop_and_remove_bus_device+0x16/0x30
  [81474a9e] acpiphp_disable_slot+0x8e/0x150
  [81474f6a] hotplug_event_func+0xba/0x1a0
  [814906c8] ? acpi_os_release_object+0xe/0x12
  [81475911] _handle_hotplug_event_func+0x31/0x70
  [810b5333] process_one_work+0x183/0x500
  [810b66e2] worker_thread+0x122/0x400
  [810b65c0] ? manage_workers+0x2d0/0x2d0
  [810bc5de] kthread+0xce/0xe0
  [810bc510] ? kthread_freezable_should_stop+0x70/0x70
  [81ca045c] ret_from_fork+0x7c/0xb0
  [810bc510] ? 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  [8179b29f] __virtscsi_set_affinity+0x6f/0x120
  RSP 88007bfe5a38
 CR2: 0020
 ---[ end trace 99679331a3775f48 ]---

CC: sta...@vger.kernel.org
Signed-off-by: Asias He as...@redhat.com
---
 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 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 as...@redhat.com

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 linux/llist.h
  #include linux/bitmap.h
  
 -#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 linux/slab.h
  #include linux/kthread.h
  #include linux/cgroup.h
 +#include linux/module.h
  
  #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

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 m...@redhat.com

Acked-by: Asias He as...@redhat.com

 ---
  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 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 sasha.le...@oracle.com
 Cc: Rusty Russell ru...@rustcorp.com.au
 Cc: Michael S. Tsirkin m...@redhat.com
 Signed-off-by: Jason Wang jasow...@redhat.com

Reviewed-by: Asias He as...@redhat.com

 ---
  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 as...@redhat.com
 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 0/5] Introduce VM Sockets virtio transport

2013-06-28 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.
 
 __u32   len;
 __u8type;
 __u8op;
 __u8shut;
 
 Please add padding to align all field naturally.

ok.

 __u64   fwd_cnt;
 __u64   buf_alloc;
 
 Is a 64 bit counter really needed? 64 bit math
 has portability limitations and performance overhead on many
 architectures.

Good point, but 32 bit tx_cnt and fwd_cnt counter overflow very easily
since it contains the total number of bytes ever transferred. If we can
to use 32 bit counter, we need to figure out how to handle overflow. (64
bit can overflow as well.)

buf_alloc can be 32 bit.

 } __packed;
 
 Packing produces terrible code in many compilers.
 Please avoid packed structures on data path, instead,
 pad structures explicitly to align all fields naturally.

We have packed structures on scsi:

include/linux/virtio_scsi.h

 
  
  src_cid and dst_cid: specify

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

2013-06-28 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 as...@redhat.com
  ---
   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 as...@redhat.com, 2013
  + */
  +
  +#ifndef _LINUX_VIRTIO_VSOCK_H
  +#define _LINUX_VIRTIO_VSOCK_H
  +
  +#include uapi/linux/virtio_vsock.h
  +#include linux/socket.h
  +#include net/sock.h
  +
  +#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

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

2013-06-28 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 as...@redhat.com
 
 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 as...@redhat.com
  + *
  + * This work is licensed under the terms of the GNU GPL, version 2.
  + */
  +#include linux/miscdevice.h
  +#include linux/module.h
  +#include linux/mutex.h
  +#include net/sock.h
  +#include linux/virtio_vsock.h
  +#include linux/vhost.h
  +
  +#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);
  +   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 */
 
 Pls fix. memcpy_from_iovec is not harder.

Do we have this helper

[RFC 0/5] Introduce VM Sockets virtio transport

2013-06-27 Thread Asias He
.

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


[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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 as...@redhat.com, 2013
+ */
+
+#ifndef _LINUX_VIRTIO_VSOCK_H
+#define _LINUX_VIRTIO_VSOCK_H
+
+#include uapi/linux/virtio_vsock.h
+#include linux/socket.h
+#include net/sock.h
+
+#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

[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 as...@redhat.com
---
 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 as...@redhat.com
+ *
+ * Some of the code is take from Gerd Hoffmann kra...@redhat.com's
+ * early virtio-vsock proof-of-concept bits.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include linux/spinlock.h
+#include linux/module.h
+#include linux/list.h
+#include linux/virtio.h
+#include linux/virtio_ids.h
+#include linux/virtio_config.h
+#include linux/virtio_vsock.h
+#include net/sock.h
+#include linux/mutex.h
+#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;
+   struct virtio_vsock_pkt *pkt;
+   struct scatterlist sg[2

[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 as...@redhat.com
---
 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 as...@redhat.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+#include linux/miscdevice.h
+#include linux/module.h
+#include linux/mutex.h
+#include net/sock.h
+#include linux/virtio_vsock.h
+#include linux/vhost.h
+
+#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_transport_free_pkt(pkt);
+   }
+   vhost_signal(vsock-dev, vq);
+   mutex_unlock(vq-mutex);
+}
+
+static void vhost_transport_send_pkt_work(struct

[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 as...@redhat.com
---
 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


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


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 m...@redhat.com

Acked-by: Asias He as...@redhat.com

 ---
 
 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 wenchaoli...@gmail.com

Acked-by: Asias He as...@redhat.com

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 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 as...@redhat.com 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 linux/llist.h
  #include linux/bitmap.h
  
 -#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-15 Thread Asias He
On Wed, May 15, 2013 at 02:47:53PM +0930, Rusty Russell wrote:
 Asias He as...@redhat.com 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 Thu, May 16, 2013 at 09:05:38AM +0930, Rusty Russell wrote:
 Nicholas A. Bellinger n...@linux-iscsi.org writes:
  On Wed, 2013-05-15 at 14:47 +0930, Rusty Russell wrote:
  Asias He as...@redhat.com 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 Thu, May 16, 2013 at 01:04:58PM +0930, Rusty Russell wrote:
 Asias He as...@redhat.com writes:
  On Wed, May 15, 2013 at 02:47:53PM +0930, Rusty Russell wrote:
  Asias He as...@redhat.com 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 ru...@rustcorp.com.au
 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 rdun...@infradead.org
 Signed-off-by: Rusty Russell ru...@rustcorp.com.au
 
 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 linux/uaccess.h
 +#include linux/export.h
 +#include linux/uio.h
 +
 +/*
 + *   Copy iovec to kernel. Returns -EFAULT on error.
 + *
 + *   Note: this modifies the original iovec.
 + */
 +
 +int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
 +{
 + while (len  0) {
 + if (iov-iov_len) {
 + int copy = min_t(unsigned int, len, iov-iov_len);
 + if (copy_from_user(kdata, iov-iov_base, copy))
 + return -EFAULT;
 + len -= copy;
 + kdata += copy;
 + iov-iov_base += copy;
 + iov-iov_len -= copy;
 + }
 + iov++;
 + }
 +
 + return 0;
 +}
 +EXPORT_SYMBOL(memcpy_fromiovec);
 +
 diff --git a/net/core/iovec.c b/net/core/iovec.c
 index 7e7aeb0..d81257f 100644
 --- a/net/core

[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 rdun...@infradead.org
Signed-off-by: Asias He as...@redhat.com
---
 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] 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 rdun...@infradead.org
  Signed-off-by: Asias He as...@redhat.com
 
 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 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 as...@redhat.com
---

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 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 linux/slab.h
 
 #include test.h
-#include vhost.c
+#include vhost.h
 
 /* Max number of bytes transferred before requeueing the job.
  * Using this limit prevents one virtqueue from starving others. */
@@ -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) {
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

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 as...@redhat.com
  ---
  
  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 m...@redhat.com
 
 ---
 
 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


[PATCH] vhost-scsi: Enable VIRTIO_RING_F_EVENT_IDX

2013-05-07 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 as...@redhat.com
---
 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


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

2013-05-07 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 linux/slab.h
 
 #include test.h
-#include vhost.c
+#include vhost.h
 
 /* Max number of bytes transferred before requeueing the job.
  * Using this limit prevents one virtqueue from starving others. */
@@ -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

[PATCH 0/4] vhost private_data rcu removal

2013-05-07 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 1/4] vhost-net: Always access vq-private_data under vq mutex

2013-05-07 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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 3/4] vhost-scsi: Always access vq-private_data under vq mutex

2013-05-07 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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 4/4] vhost: Remove custom vhost rcu usage

2013-05-07 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 as...@redhat.com
---
 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 linux/moduleparam.h
 #include linux/mutex.h
 #include linux/workqueue.h
-#include linux/rcupdate.h
 #include linux/file.h
 #include linux/slab.h
 
@@ -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 linux/module.h
 #include linux/mutex.h
 #include linux/workqueue.h
-#include linux/rcupdate.h
 #include linux/file.h
 #include linux/slab.h
 
@@ -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_is_held(vq-mutex));
-   rcu_assign_pointer

[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: [81c0721e] _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:[81c0721e]  [81c0721e] _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:
 [810ac5c5] __queue_work+0x45/0x2d0
 [810ac8fe] queue_work_on+0x8e/0xa0
 [810ac949] queue_work+0x19/0x20
 [81009b6b] irqfd_deactivate+0x4b/0x60
 [8100a69d] kvm_irqfd+0x39d/0x580
 [81007a27] kvm_vm_ioctl+0x207/0x5b0
 [810c9545] ? update_curr+0xf5/0x180
 [811b66e8] do_vfs_ioctl+0x98/0x550
 [810c1f5e] ? finish_task_switch+0x4e/0xe0
 [81c054aa] ? __schedule+0x2ea/0x710
 [811b6bf7] sys_ioctl+0x57/0x90
 [8140ae9e] ? trace_hardirqs_on_thunk+0x3a/0x3c
 [81c0f602] 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 f0 66 0f c1 07 89 c2 
66 c1 ea 08 38 c2 74 0c 0f 1f 00 f3 90 0f
RIP  [81c0721e] _raw_spin_lock+0xe/0x30
RSP 880221721cc8
CR2: 
---[ end trace 13fb1e4b6e5ab21f ]---

Signed-off-by: Asias He as...@redhat.com
---
 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


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: [81c0721e] _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:[81c0721e]  [81c0721e] _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:
   [810ac5c5] __queue_work+0x45/0x2d0
   [810ac8fe] queue_work_on+0x8e/0xa0
   [810ac949] queue_work+0x19/0x20
   [81009b6b] irqfd_deactivate+0x4b/0x60
   [8100a69d] kvm_irqfd+0x39d/0x580
   [81007a27] kvm_vm_ioctl+0x207/0x5b0
   [810c9545] ? update_curr+0xf5/0x180
   [811b66e8] do_vfs_ioctl+0x98/0x550
   [810c1f5e] ? finish_task_switch+0x4e/0xe0
   [81c054aa] ? __schedule+0x2ea/0x710
   [811b6bf7] sys_ioctl+0x57/0x90
   [8140ae9e] ? trace_hardirqs_on_thunk+0x3a/0x3c
   [81c0f602] 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 f0 66 0f c1 
  07 89 c2 66 c1 ea 08 38 c2 74 0c 0f 1f 00 f3 90 0f
  RIP  [81c0721e] _raw_spin_lock+0xe/0x30
  RSP 880221721cc8
  CR2: 
  ---[ end trace 13fb1e4b6e5ab21f ]---
  
  Signed-off-by: Asias He as...@redhat.com
  ---
   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 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: [81c0721e] _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:[81c0721e]  [81c0721e] _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:
 [810ac5c5] __queue_work+0x45/0x2d0
 [810ac8fe] queue_work_on+0x8e/0xa0
 [810ac949] queue_work+0x19/0x20
 [81009b6b] irqfd_deactivate+0x4b/0x60
 [8100a69d] kvm_irqfd+0x39d/0x580
 [81007a27] kvm_vm_ioctl+0x207/0x5b0
 [810c9545] ? update_curr+0xf5/0x180
 [811b66e8] do_vfs_ioctl+0x98/0x550
 [810c1f5e] ? finish_task_switch+0x4e/0xe0
 [81c054aa] ? __schedule+0x2ea/0x710
 [811b6bf7] sys_ioctl+0x57/0x90
 [8140ae9e] ? trace_hardirqs_on_thunk+0x3a/0x3c
 [81c0f602] 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 f0 66 0f c1 07 89 c2 
66 c1 ea 08 38 c2 74 0c 0f 1f 00 f3 90 0f
RIP  [81c0721e] _raw_spin_lock+0xe/0x30
RSP 880221721cc8
CR2: 
---[ end trace 13fb1e4b6e5ab21f ]---

Signed-off-by: Asias He as...@redhat.com
---
 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 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 m...@redhat.com 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 as...@redhat.com
 ---
  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_net_ubuf_ref

[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


[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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 linux/llist.h
 #include linux/bitmap.h
 
-#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 linux/slab.h
 #include linux/kthread.h
 #include linux/cgroup.h
+#include linux/module.h
 
 #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);
 }
+EXPORT_SYMBOL_GPL(vhost_poll_queue);
 
 static void vhost_vq_reset(struct vhost_dev *dev

[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 as...@redhat.com
---
 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 05/11] vhost: Simplify dev-vqs[i] access

2013-05-06 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 09/11] vhost-scsi: Make func indention more consistent

2013-05-06 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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;
@@ -734,8 +739,11 @@ static struct tcm_vhost_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 as...@redhat.com
---
 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();
match = true;
}
-   mutex_unlock(tv_tpg-tv_tpg_mutex);
+   mutex_unlock(tpg-tv_tpg_mutex);
}
 
if (match) {
@@ -1262,7 +1262,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs

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


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 m...@redhat.com

Reviewed-by: Asias He as...@redhat.com

 ---
 
 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 linux/eventfd.h
  #include linux/vhost.h
 -#include linux/virtio_net.h
  #include linux/mm.h
  #include linux/mmu_context.h
  #include linux/miscdevice.h
 -- 
 MST

-- 
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 as...@redhat.com
 
 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 linux/llist.h
   #include linux/bitmap.h
   
  -#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 linux/slab.h
   #include linux/kthread.h
   #include linux/cgroup.h
  +#include linux/module.h
   
   #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

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] 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 m...@redhat.com
 ---
 
 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 linux/eventfd.h
  #include linux/vhost.h
 -#include linux/virtio_net.h
  #include linux/mm.h
  #include linux/mmu_context.h
  #include linux/miscdevice.h
 -- 
 MST

-- 
Asias
___
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 1/2] vhost: Export vhost_dev_set_owner

2013-05-05 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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 2/2] vhost-net: Free ubuf when vhost_dev_set_owner fails

2013-05-05 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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 0/4] vhost and vhost-net cleanups

2013-05-03 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 1/4] vhost: Remove comments for hdr in vhost.h

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

Signed-off-by: Asias He as...@redhat.com
---
 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 2/4] vhost: Simplify dev-vqs[i] access

2013-05-03 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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 3/4] vhost-net: Free ubuf when vhost_dev_ioctl fails

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

Signed-off-by: Asias He as...@redhat.com
---
 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 4/4] vhost-net: Cleanup vhost_ubuf adn vhost_zcopy

2013-05-03 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 as...@redhat.com
---
 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_net_ubuf_ref *uninitialized_var(ubufs);
bool zcopy, zcopy_used;
 
/* TODO: check that we are running from vhost_worker? */
@@ -441,7 +442,7 @@ static void handle_tx(struct vhost_net

[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 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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 3/5] vhost-scsi: Make func indention more consistent

2013-05-03 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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;
@@ -734,8 +739,11 @@ static struct tcm_vhost_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 as...@redhat.com
---
 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();
match = true;
}
-   mutex_unlock(tv_tpg-tv_tpg_mutex);
+   mutex_unlock(tpg-tv_tpg_mutex);
}
 
if (match) {
@@ -1262,7 +1262,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs

[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


[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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 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 as...@redhat.com
---
 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 linux/llist.h
 #include linux/bitmap.h
 
-#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 linux/slab.h
 #include linux/kthread.h
 #include linux/cgroup.h
+#include linux/module.h
 
 #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);
 }
+EXPORT_SYMBOL_GPL(vhost_poll_queue);
 
 static void vhost_vq_reset(struct vhost_dev *dev

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 as...@redhat.com
 
 
 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 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 as...@redhat.com
  ---
   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_virtqueue *svq;
  +
  +   svq = container_of(vq, struct vhost_scsi_virtqueue, vq);
  +   inflight = svq-inflights[svq-inflight_idx];
  +   kref_get(inflight-kref);
  +
  +   return inflight;
  +}
  +
  +static void tcm_vhost_put_inflight(struct vhost_scsi_inflight *inflight)
  +{
  +   kref_put(inflight-kref, tcm_vhost_done_inflight);
  +}
  +
   static int tcm_vhost_check_true(struct se_portal_group *se_tpg)
   {
  return 1;
  @@ -407,6 +471,8 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd 
  *tv_cmd)
  kfree(tv_cmd-tvc_sgl);
  }
   
  +   tcm_vhost_put_inflight(tv_cmd-inflight);
  +
  kfree(tv_cmd);
   }
   
  @@ -533,6 +599,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

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 as...@redhat.com
---
 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;
+
+   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

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 as...@redhat.com
  ---
   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
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? 
 
 It does, I think nothing else depends on vhost_scsi_flush being
 done under dev mutex.

Why is concurrent vhost_scsi_flush useful? Allocating it dynamically
can make you call vhost_scsi_flush simultaneously? I do not think so.

How will dynamic allocation change the locking scheme?

 Hmm we probably should add a comment saying called under
 dev mutex or on release path near vhost_scsi_flush.

   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

[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 as...@redhat.com
---
 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 *vq = net-vqs[VHOST_NET_VQ_TX].vq;
+   struct vhost_net_virtqueue *nvq = net-vqs[VHOST_NET_VQ_TX];
unsigned out, in, s;
int head;
struct msghdr msg

[PATCH v6 0/2] tcm_vhost flush

2013-04-26 Thread Asias He
Changes in v6:
- Allow device specific fields per vq
- Track cmd per vq
- Do not track evt
- Switch to static array for inflight allocation, completely get rid of the
  pain to handle inflight allocation failure.

Asias He (2):
  vhost: Allow device specific fields per vq
  tcm_vhost: Wait for pending requests in vhost_scsi_flush()

 drivers/vhost/net.c   |  60 +++
 drivers/vhost/tcm_vhost.c | 145 --
 drivers/vhost/tcm_vhost.h |   3 +
 drivers/vhost/vhost.c |  88 ++--
 drivers/vhost/vhost.h |   4 +-
 5 files changed, 212 insertions(+), 88 deletions(-)

-- 
1.8.1.4

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


[PATCH v6 1/2] vhost: Allow device specific fields per vq

2013-04-26 Thread Asias He
This is useful for any device who wants device specific fields per vq.
For example, tcm_vhost wants a per vq field to track requests which are
in flight on the vq. Also, on top of this we can add patches to move
things like ubufs from vhost.h out to net.c.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/net.c   | 60 +++-
 drivers/vhost/tcm_vhost.c | 55 +++--
 drivers/vhost/vhost.c | 88 +++
 drivers/vhost/vhost.h |  4 +--
 4 files changed, 120 insertions(+), 87 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ec6fb3f..683d9a1 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -70,9 +70,13 @@ enum vhost_net_poll_state {
VHOST_NET_POLL_STOPPED = 2,
 };
 
+struct vhost_net_virtqueue {
+   struct vhost_virtqueue vq;
+};
+
 struct vhost_net {
struct vhost_dev dev;
-   struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
+   struct vhost_net_virtqueue vqs[VHOST_NET_VQ_MAX];
struct vhost_poll poll[VHOST_NET_VQ_MAX];
/* Tells us whether we are polling a socket for TX.
 * We only do this when socket buffer fills up.
@@ -230,7 +234,7 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, 
bool success)
  * read-size critical section for our kind of RCU. */
 static void handle_tx(struct vhost_net *net)
 {
-   struct vhost_virtqueue *vq = net-dev.vqs[VHOST_NET_VQ_TX];
+   struct vhost_virtqueue *vq = net-vqs[VHOST_NET_VQ_TX].vq;
unsigned out, in, s;
int head;
struct msghdr msg = {
@@ -470,7 +474,7 @@ err:
  * read-size critical section for our kind of RCU. */
 static void handle_rx(struct vhost_net *net)
 {
-   struct vhost_virtqueue *vq = net-dev.vqs[VHOST_NET_VQ_RX];
+   struct vhost_virtqueue *vq = net-vqs[VHOST_NET_VQ_RX].vq;
unsigned uninitialized_var(in), log;
struct vhost_log *vq_log;
struct msghdr msg = {
@@ -612,17 +616,26 @@ static int vhost_net_open(struct inode *inode, struct 
file *f)
 {
struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL);
struct vhost_dev *dev;
+   struct vhost_virtqueue **vqs;
int r;
 
if (!n)
return -ENOMEM;
+   vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL);
+   if (!vqs) {
+   kfree(n);
+   return -ENOMEM;
+   }
 
dev = n-dev;
-   n-vqs[VHOST_NET_VQ_TX].handle_kick = handle_tx_kick;
-   n-vqs[VHOST_NET_VQ_RX].handle_kick = handle_rx_kick;
-   r = vhost_dev_init(dev, n-vqs, VHOST_NET_VQ_MAX);
+   vqs[VHOST_NET_VQ_TX] = n-vqs[VHOST_NET_VQ_TX].vq;
+   vqs[VHOST_NET_VQ_RX] = n-vqs[VHOST_NET_VQ_RX].vq;
+   n-vqs[VHOST_NET_VQ_TX].vq.handle_kick = handle_tx_kick;
+   n-vqs[VHOST_NET_VQ_RX].vq.handle_kick = handle_rx_kick;
+   r = vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX);
if (r  0) {
kfree(n);
+   kfree(vqs);
return r;
}
 
@@ -640,7 +653,7 @@ static void vhost_net_disable_vq(struct vhost_net *n,
 {
if (!vq-private_data)
return;
-   if (vq == n-vqs + VHOST_NET_VQ_TX) {
+   if (vq == n-vqs[VHOST_NET_VQ_TX].vq) {
tx_poll_stop(n);
n-tx_poll_state = VHOST_NET_POLL_DISABLED;
} else
@@ -657,7 +670,7 @@ static int vhost_net_enable_vq(struct vhost_net *n,
 lockdep_is_held(vq-mutex));
if (!sock)
return 0;
-   if (vq == n-vqs + VHOST_NET_VQ_TX) {
+   if (vq == n-vqs[VHOST_NET_VQ_TX].vq) {
n-tx_poll_state = VHOST_NET_POLL_STOPPED;
ret = tx_poll_start(n, sock);
} else
@@ -683,30 +696,30 @@ static struct socket *vhost_net_stop_vq(struct vhost_net 
*n,
 static void vhost_net_stop(struct vhost_net *n, struct socket **tx_sock,
   struct socket **rx_sock)
 {
-   *tx_sock = vhost_net_stop_vq(n, n-vqs + VHOST_NET_VQ_TX);
-   *rx_sock = vhost_net_stop_vq(n, n-vqs + VHOST_NET_VQ_RX);
+   *tx_sock = vhost_net_stop_vq(n, n-vqs[VHOST_NET_VQ_TX].vq);
+   *rx_sock = vhost_net_stop_vq(n, n-vqs[VHOST_NET_VQ_RX].vq);
 }
 
 static void vhost_net_flush_vq(struct vhost_net *n, int index)
 {
vhost_poll_flush(n-poll + index);
-   vhost_poll_flush(n-dev.vqs[index].poll);
+   vhost_poll_flush(n-vqs[index].vq.poll);
 }
 
 static void vhost_net_flush(struct vhost_net *n)
 {
vhost_net_flush_vq(n, VHOST_NET_VQ_TX);
vhost_net_flush_vq(n, VHOST_NET_VQ_RX);
-   if (n-dev.vqs[VHOST_NET_VQ_TX].ubufs) {
-   mutex_lock(n-dev.vqs[VHOST_NET_VQ_TX].mutex);
+   if (n-vqs[VHOST_NET_VQ_TX].vq.ubufs) {
+   mutex_lock(n-vqs[VHOST_NET_VQ_TX].vq.mutex);
n-tx_flush = true;
-   mutex_unlock(n-dev.vqs[VHOST_NET_VQ_TX].mutex

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

2013-04-26 Thread Asias He
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 as...@redhat.com
---
 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 */
+   struct vhost_scsi_inflight inflights[2];
+   /* Indicate current inflight in use, protected by vq-mutex */
+   int inflight_idx;
 };
 
 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_virtqueue *svq;
+
+   svq = container_of(vq, struct vhost_scsi_virtqueue, vq);
+   inflight = svq-inflights[svq-inflight_idx];
+   kref_get(inflight-kref);
+
+   return inflight;
+}
+
+static void tcm_vhost_put_inflight(struct vhost_scsi_inflight *inflight)
+{
+   kref_put(inflight-kref, tcm_vhost_done_inflight);
+}
+
 static int tcm_vhost_check_true(struct se_portal_group *se_tpg)
 {
return 1;
@@ -407,6 +471,8 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd 
*tv_cmd)
kfree(tv_cmd-tvc_sgl);
}
 
+   tcm_vhost_put_inflight(tv_cmd-inflight);
+
kfree(tv_cmd);
 }
 
@@ -533,6 +599,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 virtio_scsi_cmd_req *v_req,
u32 exp_data_len,
@@ -557,6 +624,7 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
tv_cmd-tvc_exp_data_len = exp_data_len;
tv_cmd-tvc_data_direction = data_direction;
tv_cmd-tvc_nexus = tv_nexus;
+   tv_cmd-inflight = tcm_vhost_get_inflight(vq);
 
return tv_cmd;
 }
@@ -812,7 +880,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
for (i = 0; i  data_num; i++)
exp_data_len += vq-iov[data_first + i].iov_len;
 
-   tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, v_req,
+   tv_cmd = vhost_scsi_allocate_cmd(vq, tv_tpg, v_req,
exp_data_len, data_direction);
if (IS_ERR(tv_cmd)) {
vq_err(vq, vhost_scsi_allocate_cmd failed %ld\n,
@@ -949,12 +1017,29 @@ static void vhost_scsi_flush_vq(struct vhost_scsi *vs, 
int index)
 
 static void vhost_scsi_flush(struct vhost_scsi *vs)
 {
+   struct vhost_scsi_inflight *old_inflight[VHOST_SCSI_MAX_VQ];
int i;
 
+   /* Init

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

2013-04-26 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 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

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


[PATCH v10 0/4] tcm_vhost hotplug

2013-04-25 Thread Asias He
Asias He (4):
  tcm_vhost: Refactor the lock nesting rule
  tcm_vhost: Add hotplug/hotunplug support
  tcm_vhost: Add ioctl to get and set events missed flag
  tcm_vhost: Enable VIRTIO_SCSI_F_HOTPLUG

 drivers/vhost/tcm_vhost.c | 262 +++---
 drivers/vhost/tcm_vhost.h |  13 +++
 2 files changed, 259 insertions(+), 16 deletions(-)

-- 
1.8.1.4

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


[PATCH v10 1/4] tcm_vhost: Refactor the lock nesting rule

2013-04-25 Thread Asias He
We want to use tcm_vhost_mutex to make sure hotplug/hotunplug will not
happen when set_endpoint/clear_endpoint is in process.

Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 957a0b9..822cd1f 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -808,6 +808,9 @@ static void vhost_scsi_flush(struct vhost_scsi *vs)
 /*
  * Called from vhost_scsi_ioctl() context to walk the list of available
  * tcm_vhost_tpg with an active struct tcm_vhost_nexus
+ *
+ *  The lock nesting rule is:
+ *tcm_vhost_mutex - vs-dev.mutex - tpg-tv_tpg_mutex - vq-mutex
  */
 static int vhost_scsi_set_endpoint(
struct vhost_scsi *vs,
@@ -820,26 +823,27 @@ static int vhost_scsi_set_endpoint(
int index, ret, i, len;
bool match = false;
 
+   mutex_lock(tcm_vhost_mutex);
mutex_lock(vs-dev.mutex);
+
/* Verify that ring has been setup correctly. */
for (index = 0; index  vs-dev.nvqs; ++index) {
/* Verify that ring has been setup correctly. */
if (!vhost_vq_access_ok(vs-vqs[index])) {
-   mutex_unlock(vs-dev.mutex);
-   return -EFAULT;
+   ret = -EFAULT;
+   goto out;
}
}
 
len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
vs_tpg = kzalloc(len, GFP_KERNEL);
if (!vs_tpg) {
-   mutex_unlock(vs-dev.mutex);
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto out;
}
if (vs-vs_tpg)
memcpy(vs_tpg, vs-vs_tpg, len);
 
-   mutex_lock(tcm_vhost_mutex);
list_for_each_entry(tv_tpg, tcm_vhost_list, tv_tpg_list) {
mutex_lock(tv_tpg-tv_tpg_mutex);
if (!tv_tpg-tpg_nexus) {
@@ -854,11 +858,10 @@ static int vhost_scsi_set_endpoint(
 
if (!strcmp(tv_tport-tport_name, t-vhost_wwpn)) {
if (vs-vs_tpg  vs-vs_tpg[tv_tpg-tport_tpgt]) {
-   mutex_unlock(tv_tpg-tv_tpg_mutex);
-   mutex_unlock(tcm_vhost_mutex);
-   mutex_unlock(vs-dev.mutex);
kfree(vs_tpg);
-   return -EEXIST;
+   mutex_unlock(tv_tpg-tv_tpg_mutex);
+   ret = -EEXIST;
+   goto out;
}
tv_tpg-tv_tpg_vhost_count++;
vs_tpg[tv_tpg-tport_tpgt] = tv_tpg;
@@ -867,7 +870,6 @@ static int vhost_scsi_set_endpoint(
}
mutex_unlock(tv_tpg-tv_tpg_mutex);
}
-   mutex_unlock(tcm_vhost_mutex);
 
if (match) {
memcpy(vs-vs_vhost_wwpn, t-vhost_wwpn,
@@ -893,7 +895,9 @@ static int vhost_scsi_set_endpoint(
kfree(vs-vs_tpg);
vs-vs_tpg = vs_tpg;
 
+out:
mutex_unlock(vs-dev.mutex);
+   mutex_unlock(tcm_vhost_mutex);
return ret;
 }
 
@@ -908,6 +912,7 @@ static int vhost_scsi_clear_endpoint(
int index, ret, i;
u8 target;
 
+   mutex_lock(tcm_vhost_mutex);
mutex_lock(vs-dev.mutex);
/* Verify that ring has been setup correctly. */
for (index = 0; index  vs-dev.nvqs; ++index) {
@@ -918,8 +923,8 @@ static int vhost_scsi_clear_endpoint(
}
 
if (!vs-vs_tpg) {
-   mutex_unlock(vs-dev.mutex);
-   return 0;
+   ret = 0;
+   goto err_dev;
}
 
for (i = 0; i  VHOST_SCSI_MAX_TARGET; i++) {
@@ -965,13 +970,14 @@ static int vhost_scsi_clear_endpoint(
kfree(vs-vs_tpg);
vs-vs_tpg = NULL;
mutex_unlock(vs-dev.mutex);
-
+   mutex_unlock(tcm_vhost_mutex);
return 0;
 
 err_tpg:
mutex_unlock(tv_tpg-tv_tpg_mutex);
 err_dev:
mutex_unlock(vs-dev.mutex);
+   mutex_unlock(tcm_vhost_mutex);
return ret;
 }
 
-- 
1.8.1.4

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


[PATCH v10 3/4] tcm_vhost: Add ioctl to get and set events missed flag

2013-04-25 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 17 +
 drivers/vhost/tcm_vhost.h |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 5340fd7..07217d8 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -1200,8 +1200,11 @@ static long vhost_scsi_ioctl(struct file *f, unsigned 
int ioctl,
struct vhost_scsi_target backend;
void __user *argp = (void __user *)arg;
u64 __user *featurep = argp;
+   u32 __user *eventsp = argp;
+   u32 events_missed;
u64 features;
int r, abi_version = VHOST_SCSI_ABI_VERSION;
+   struct vhost_virtqueue *vq = vs-vqs[VHOST_SCSI_VQ_EVT];
 
switch (ioctl) {
case VHOST_SCSI_SET_ENDPOINT:
@@ -1222,6 +1225,20 @@ static long vhost_scsi_ioctl(struct file *f, unsigned 
int ioctl,
if (copy_to_user(argp, abi_version, sizeof abi_version))
return -EFAULT;
return 0;
+   case VHOST_SCSI_SET_EVENTS_MISSED:
+   if (get_user(events_missed, eventsp))
+   return -EFAULT;
+   mutex_lock(vq-mutex);
+   vs-vs_events_missed = events_missed;
+   mutex_unlock(vq-mutex);
+   return 0;
+   case VHOST_SCSI_GET_EVENTS_MISSED:
+   mutex_lock(vq-mutex);
+   events_missed = vs-vs_events_missed;
+   mutex_unlock(vq-mutex);
+   if (put_user(events_missed, eventsp))
+   return -EFAULT;
+   return 0;
case VHOST_GET_FEATURES:
features = VHOST_SCSI_FEATURES;
if (copy_to_user(featurep, features, sizeof features))
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h
index a545a5b..514b9fd 100644
--- a/drivers/vhost/tcm_vhost.h
+++ b/drivers/vhost/tcm_vhost.h
@@ -123,3 +123,6 @@ struct vhost_scsi_target {
 #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct 
vhost_scsi_target)
 /* Changing this breaks userspace. */
 #define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
+/* Set and get the events missed flag */
+#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
+#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
-- 
1.8.1.4

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


[PATCH v10 4/4] tcm_vhost: Enable VIRTIO_SCSI_F_HOTPLUG

2013-04-25 Thread Asias He
Everything for hotplug is ready. Let's enable the feature bit.

Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 07217d8..1677238 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -66,7 +66,8 @@ enum {
  * TODO: debug and remove the workaround.
  */
 enum {
-   VHOST_SCSI_FEATURES = VHOST_FEATURES  (~VIRTIO_RING_F_EVENT_IDX)
+   VHOST_SCSI_FEATURES = (VHOST_FEATURES  (~VIRTIO_RING_F_EVENT_IDX)) |
+ (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 v10 2/4] tcm_vhost: Add hotplug/hotunplug support

2013-04-25 Thread Asias He
MST wants one without change history in commit log.

From 8996c9464fae1f28d0bd729677a3917d204990ec Mon Sep 17 00:00:00 2001
From: Asias He as...@redhat.com
Date: Thu, 25 Apr 2013 09:51:26 +0800
Subject: [PATCH v10 2/4] tcm_vhost: Add hotplug/hotunplug support

In commit 365a7150094 ([SCSI] virtio-scsi: hotplug support for
virtio-scsi), hotplug support is added to virtio-scsi.

This patch adds hotplug and hotunplug support to tcm_vhost.

You can create or delete a LUN in targetcli to hotplug or hotunplug a
LUN in guest.

Signed-off-by: Asias He as...@redhat.com
Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
---

Changes in v8:
- Use vq-mutex for event
- Drop tcm_vhost: Add helper to check if endpoint is setup
- Rename vs_events_dropped to vs_events_missed
- Init lun[] explicitly

Changes in v7:
- Add vhost_work_flush for vs-vs_event_work to this series

Changes in v6:
- Pass tcm_vhost_evt to tcm_vhost_do_evt_work

Changes in v5:
- Switch to int from u64 to vs_events_nr
- Set s-vs_events_dropped flag in tcm_vhost_allocate_evt
- Do not nest dev mutex within vq mutex
- Use vs_events_lock to protect vs_events_dropped and vs_events_nr
- Rebase to target/master

Changes in v4:
- Drop tcm_vhost_check_endpoint in tcm_vhost_send_evt
- Add tcm_vhost_check_endpoint in vhost_scsi_evt_handle_kick

Changes in v3:
- Separate the bug fix to another thread

Changes in v2:
- Remove code duplication in tcm_vhost_{hotplug,hotunplug}
- Fix racing of vs_events_nr
- Add flush fix patch to this series

 drivers/vhost/tcm_vhost.c | 210 +-
 drivers/vhost/tcm_vhost.h |  10 +++
 2 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 822cd1f..5340fd7 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -71,6 +71,7 @@ enum {
 
 #define VHOST_SCSI_MAX_TARGET  256
 #define VHOST_SCSI_MAX_VQ  128
+#define VHOST_SCSI_MAX_EVENT   128
 
 struct vhost_scsi {
/* Protected by vhost_scsi-dev.mutex */
@@ -82,6 +83,12 @@ struct vhost_scsi {
 
struct vhost_work vs_completion_work; /* cmd completion work item */
struct llist_head vs_completion_list; /* cmd completion queue */
+
+   struct vhost_work vs_event_work; /* evt injection work item */
+   struct llist_head vs_event_list; /* evt injection queue */
+
+   bool vs_events_missed; /* any missed events, protected by vq-mutex */
+   int vs_events_nr; /* num of pending events, protected by vq-mutex */
 };
 
 /* Local pointer to allocated TCM configfs fabric module */
@@ -349,6 +356,37 @@ static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
 }
 
+static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt 
*evt)
+{
+   vs-vs_events_nr--;
+   kfree(evt);
+}
+
+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];
+   struct tcm_vhost_evt *evt;
+
+   if (vs-vs_events_nr  VHOST_SCSI_MAX_EVENT) {
+   vs-vs_events_missed = true;
+   return NULL;
+   }
+
+   evt = kzalloc(sizeof(*evt), GFP_KERNEL);
+   if (!evt) {
+   vq_err(vq, Failed to allocate tcm_vhost_evt\n);
+   vs-vs_events_missed = true;
+   return NULL;
+   }
+
+   evt-event.event = event;
+   evt-event.reason = reason;
+   vs-vs_events_nr++;
+
+   return evt;
+}
+
 static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
 {
struct se_cmd *se_cmd = tv_cmd-tvc_se_cmd;
@@ -367,6 +405,75 @@ 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)
+{
+   struct vhost_virtqueue *vq = vs-vqs[VHOST_SCSI_VQ_EVT];
+   struct virtio_scsi_event *event = evt-event;
+   struct virtio_scsi_event __user *eventp;
+   unsigned out, in;
+   int head, ret;
+
+   if (!vq-private_data) {
+   vs-vs_events_missed = true;
+   return;
+   }
+
+again:
+   vhost_disable_notify(vs-dev, vq);
+   head = vhost_get_vq_desc(vs-dev, vq, vq-iov,
+   ARRAY_SIZE(vq-iov), out, in,
+   NULL, NULL);
+   if (head  0) {
+   vs-vs_events_missed = true;
+   return;
+   }
+   if (head == vq-num) {
+   if (vhost_enable_notify(vs-dev, vq))
+   goto again;
+   vs-vs_events_missed = true;
+   return;
+   }
+
+   if ((vq-iov[out].iov_len != sizeof(struct virtio_scsi_event))) {
+   vq_err(vq, Expecting virtio_scsi_event, got %zu bytes\n,
+   vq-iov[out].iov_len);
+   vs-vs_events_missed = true;
+   return;
+   }
+
+   if (vs-vs_events_missed

[PATCH v11 0/4] tcm_vhost hotplug

2013-04-25 Thread Asias He
Changes in v11
- Drop change log histroy in commit log

Changes in v10
- Drop comments about lun
- Add Enable VIRTIO_SCSI_F_HOTPLUG to this series

Changes in v9
- Drop tcm_vhost_check_feature
- Add Refactor the lock nesting rule to this sereis

Asias He (4):
  tcm_vhost: Refactor the lock nesting rule
  tcm_vhost: Add hotplug/hotunplug support
  tcm_vhost: Add ioctl to get and set events missed flag
  tcm_vhost: Enable VIRTIO_SCSI_F_HOTPLUG

 drivers/vhost/tcm_vhost.c | 262 +++---
 drivers/vhost/tcm_vhost.h |  13 +++
 2 files changed, 259 insertions(+), 16 deletions(-)

-- 
1.8.1.4

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


[PATCH v11 1/4] tcm_vhost: Refactor the lock nesting rule

2013-04-25 Thread Asias He
We want to use tcm_vhost_mutex to make sure hotplug/hotunplug will not
happen when set_endpoint/clear_endpoint is in process.

Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 957a0b9..822cd1f 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -808,6 +808,9 @@ static void vhost_scsi_flush(struct vhost_scsi *vs)
 /*
  * Called from vhost_scsi_ioctl() context to walk the list of available
  * tcm_vhost_tpg with an active struct tcm_vhost_nexus
+ *
+ *  The lock nesting rule is:
+ *tcm_vhost_mutex - vs-dev.mutex - tpg-tv_tpg_mutex - vq-mutex
  */
 static int vhost_scsi_set_endpoint(
struct vhost_scsi *vs,
@@ -820,26 +823,27 @@ static int vhost_scsi_set_endpoint(
int index, ret, i, len;
bool match = false;
 
+   mutex_lock(tcm_vhost_mutex);
mutex_lock(vs-dev.mutex);
+
/* Verify that ring has been setup correctly. */
for (index = 0; index  vs-dev.nvqs; ++index) {
/* Verify that ring has been setup correctly. */
if (!vhost_vq_access_ok(vs-vqs[index])) {
-   mutex_unlock(vs-dev.mutex);
-   return -EFAULT;
+   ret = -EFAULT;
+   goto out;
}
}
 
len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
vs_tpg = kzalloc(len, GFP_KERNEL);
if (!vs_tpg) {
-   mutex_unlock(vs-dev.mutex);
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto out;
}
if (vs-vs_tpg)
memcpy(vs_tpg, vs-vs_tpg, len);
 
-   mutex_lock(tcm_vhost_mutex);
list_for_each_entry(tv_tpg, tcm_vhost_list, tv_tpg_list) {
mutex_lock(tv_tpg-tv_tpg_mutex);
if (!tv_tpg-tpg_nexus) {
@@ -854,11 +858,10 @@ static int vhost_scsi_set_endpoint(
 
if (!strcmp(tv_tport-tport_name, t-vhost_wwpn)) {
if (vs-vs_tpg  vs-vs_tpg[tv_tpg-tport_tpgt]) {
-   mutex_unlock(tv_tpg-tv_tpg_mutex);
-   mutex_unlock(tcm_vhost_mutex);
-   mutex_unlock(vs-dev.mutex);
kfree(vs_tpg);
-   return -EEXIST;
+   mutex_unlock(tv_tpg-tv_tpg_mutex);
+   ret = -EEXIST;
+   goto out;
}
tv_tpg-tv_tpg_vhost_count++;
vs_tpg[tv_tpg-tport_tpgt] = tv_tpg;
@@ -867,7 +870,6 @@ static int vhost_scsi_set_endpoint(
}
mutex_unlock(tv_tpg-tv_tpg_mutex);
}
-   mutex_unlock(tcm_vhost_mutex);
 
if (match) {
memcpy(vs-vs_vhost_wwpn, t-vhost_wwpn,
@@ -893,7 +895,9 @@ static int vhost_scsi_set_endpoint(
kfree(vs-vs_tpg);
vs-vs_tpg = vs_tpg;
 
+out:
mutex_unlock(vs-dev.mutex);
+   mutex_unlock(tcm_vhost_mutex);
return ret;
 }
 
@@ -908,6 +912,7 @@ static int vhost_scsi_clear_endpoint(
int index, ret, i;
u8 target;
 
+   mutex_lock(tcm_vhost_mutex);
mutex_lock(vs-dev.mutex);
/* Verify that ring has been setup correctly. */
for (index = 0; index  vs-dev.nvqs; ++index) {
@@ -918,8 +923,8 @@ static int vhost_scsi_clear_endpoint(
}
 
if (!vs-vs_tpg) {
-   mutex_unlock(vs-dev.mutex);
-   return 0;
+   ret = 0;
+   goto err_dev;
}
 
for (i = 0; i  VHOST_SCSI_MAX_TARGET; i++) {
@@ -965,13 +970,14 @@ static int vhost_scsi_clear_endpoint(
kfree(vs-vs_tpg);
vs-vs_tpg = NULL;
mutex_unlock(vs-dev.mutex);
-
+   mutex_unlock(tcm_vhost_mutex);
return 0;
 
 err_tpg:
mutex_unlock(tv_tpg-tv_tpg_mutex);
 err_dev:
mutex_unlock(vs-dev.mutex);
+   mutex_unlock(tcm_vhost_mutex);
return ret;
 }
 
-- 
1.8.1.4

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


[PATCH v11 2/4] tcm_vhost: Add hotplug/hotunplug support

2013-04-25 Thread Asias He
In commit 365a7150094 ([SCSI] virtio-scsi: hotplug support for
virtio-scsi), hotplug support is added to virtio-scsi.

This patch adds hotplug and hotunplug support to tcm_vhost.

You can create or delete a LUN in targetcli to hotplug or hotunplug a
LUN in guest.

Signed-off-by: Asias He as...@redhat.com
Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 210 +-
 drivers/vhost/tcm_vhost.h |  10 +++
 2 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 822cd1f..5340fd7 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -71,6 +71,7 @@ enum {
 
 #define VHOST_SCSI_MAX_TARGET  256
 #define VHOST_SCSI_MAX_VQ  128
+#define VHOST_SCSI_MAX_EVENT   128
 
 struct vhost_scsi {
/* Protected by vhost_scsi-dev.mutex */
@@ -82,6 +83,12 @@ struct vhost_scsi {
 
struct vhost_work vs_completion_work; /* cmd completion work item */
struct llist_head vs_completion_list; /* cmd completion queue */
+
+   struct vhost_work vs_event_work; /* evt injection work item */
+   struct llist_head vs_event_list; /* evt injection queue */
+
+   bool vs_events_missed; /* any missed events, protected by vq-mutex */
+   int vs_events_nr; /* num of pending events, protected by vq-mutex */
 };
 
 /* Local pointer to allocated TCM configfs fabric module */
@@ -349,6 +356,37 @@ static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
 }
 
+static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt 
*evt)
+{
+   vs-vs_events_nr--;
+   kfree(evt);
+}
+
+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];
+   struct tcm_vhost_evt *evt;
+
+   if (vs-vs_events_nr  VHOST_SCSI_MAX_EVENT) {
+   vs-vs_events_missed = true;
+   return NULL;
+   }
+
+   evt = kzalloc(sizeof(*evt), GFP_KERNEL);
+   if (!evt) {
+   vq_err(vq, Failed to allocate tcm_vhost_evt\n);
+   vs-vs_events_missed = true;
+   return NULL;
+   }
+
+   evt-event.event = event;
+   evt-event.reason = reason;
+   vs-vs_events_nr++;
+
+   return evt;
+}
+
 static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
 {
struct se_cmd *se_cmd = tv_cmd-tvc_se_cmd;
@@ -367,6 +405,75 @@ 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)
+{
+   struct vhost_virtqueue *vq = vs-vqs[VHOST_SCSI_VQ_EVT];
+   struct virtio_scsi_event *event = evt-event;
+   struct virtio_scsi_event __user *eventp;
+   unsigned out, in;
+   int head, ret;
+
+   if (!vq-private_data) {
+   vs-vs_events_missed = true;
+   return;
+   }
+
+again:
+   vhost_disable_notify(vs-dev, vq);
+   head = vhost_get_vq_desc(vs-dev, vq, vq-iov,
+   ARRAY_SIZE(vq-iov), out, in,
+   NULL, NULL);
+   if (head  0) {
+   vs-vs_events_missed = true;
+   return;
+   }
+   if (head == vq-num) {
+   if (vhost_enable_notify(vs-dev, vq))
+   goto again;
+   vs-vs_events_missed = true;
+   return;
+   }
+
+   if ((vq-iov[out].iov_len != sizeof(struct virtio_scsi_event))) {
+   vq_err(vq, Expecting virtio_scsi_event, got %zu bytes\n,
+   vq-iov[out].iov_len);
+   vs-vs_events_missed = true;
+   return;
+   }
+
+   if (vs-vs_events_missed) {
+   event-event |= VIRTIO_SCSI_T_EVENTS_MISSED;
+   vs-vs_events_missed = false;
+   }
+
+   eventp = vq-iov[out].iov_base;
+   ret = __copy_to_user(eventp, event, sizeof(*event));
+   if (!ret)
+   vhost_add_used_and_signal(vs-dev, vq, head, 0);
+   else
+   vq_err(vq, Faulted on tcm_vhost_send_event\n);
+}
+
+static void tcm_vhost_evt_work(struct vhost_work *work)
+{
+   struct vhost_scsi *vs = container_of(work, struct vhost_scsi,
+   vs_event_work);
+   struct vhost_virtqueue *vq = vs-vqs[VHOST_SCSI_VQ_EVT];
+   struct tcm_vhost_evt *evt;
+   struct llist_node *llnode;
+
+   mutex_lock(vq-mutex);
+   llnode = llist_del_all(vs-vs_event_list);
+   while (llnode) {
+   evt = llist_entry(llnode, struct tcm_vhost_evt, list);
+   llnode = llist_next(llnode);
+   tcm_vhost_do_evt_work(vs, evt);
+   tcm_vhost_free_evt(vs, evt);
+   }
+   mutex_unlock(vq-mutex);
+}
+
 /* Fill in status and signal that we are done processing this command

[PATCH v11 3/4] tcm_vhost: Add ioctl to get and set events missed flag

2013-04-25 Thread Asias He
Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 17 +
 drivers/vhost/tcm_vhost.h |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 5340fd7..07217d8 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -1200,8 +1200,11 @@ static long vhost_scsi_ioctl(struct file *f, unsigned 
int ioctl,
struct vhost_scsi_target backend;
void __user *argp = (void __user *)arg;
u64 __user *featurep = argp;
+   u32 __user *eventsp = argp;
+   u32 events_missed;
u64 features;
int r, abi_version = VHOST_SCSI_ABI_VERSION;
+   struct vhost_virtqueue *vq = vs-vqs[VHOST_SCSI_VQ_EVT];
 
switch (ioctl) {
case VHOST_SCSI_SET_ENDPOINT:
@@ -1222,6 +1225,20 @@ static long vhost_scsi_ioctl(struct file *f, unsigned 
int ioctl,
if (copy_to_user(argp, abi_version, sizeof abi_version))
return -EFAULT;
return 0;
+   case VHOST_SCSI_SET_EVENTS_MISSED:
+   if (get_user(events_missed, eventsp))
+   return -EFAULT;
+   mutex_lock(vq-mutex);
+   vs-vs_events_missed = events_missed;
+   mutex_unlock(vq-mutex);
+   return 0;
+   case VHOST_SCSI_GET_EVENTS_MISSED:
+   mutex_lock(vq-mutex);
+   events_missed = vs-vs_events_missed;
+   mutex_unlock(vq-mutex);
+   if (put_user(events_missed, eventsp))
+   return -EFAULT;
+   return 0;
case VHOST_GET_FEATURES:
features = VHOST_SCSI_FEATURES;
if (copy_to_user(featurep, features, sizeof features))
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h
index a545a5b..514b9fd 100644
--- a/drivers/vhost/tcm_vhost.h
+++ b/drivers/vhost/tcm_vhost.h
@@ -123,3 +123,6 @@ struct vhost_scsi_target {
 #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct 
vhost_scsi_target)
 /* Changing this breaks userspace. */
 #define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
+/* Set and get the events missed flag */
+#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
+#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
-- 
1.8.1.4

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


[PATCH v11 4/4] tcm_vhost: Enable VIRTIO_SCSI_F_HOTPLUG

2013-04-25 Thread Asias He
Everything for hotplug is ready. Let's enable the feature bit.

Signed-off-by: Asias He as...@redhat.com
---
 drivers/vhost/tcm_vhost.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 07217d8..1677238 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -66,7 +66,8 @@ enum {
  * TODO: debug and remove the workaround.
  */
 enum {
-   VHOST_SCSI_FEATURES = VHOST_FEATURES  (~VIRTIO_RING_F_EVENT_IDX)
+   VHOST_SCSI_FEATURES = (VHOST_FEATURES  (~VIRTIO_RING_F_EVENT_IDX)) |
+ (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


  1   2   3   4   5   >