[PATCH 2/2] kvm tools: Add vhost-net support

2011-11-16 Thread Sasha Levin
This patch adds support to using the vhost-net device when using a tap backed
virtio-net device.

Activating vhost-net is done by appending a 'vhost=1' flag to the net device
configuration. For example:

'kvm run -n mode=tap,vhost=1'

Cc: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Sasha Levin levinsasha...@gmail.com
---
 tools/kvm/builtin-run.c|2 +
 tools/kvm/include/kvm/virtio-net.h |1 +
 tools/kvm/virtio/net.c |  120 +++-
 3 files changed, 122 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 13025db..3b00bf0 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -217,6 +217,8 @@ static int set_net_param(struct virtio_net_params *p, const 
char *param,
p-guest_ip = strdup(val);
} else if (strcmp(param, host_ip) == 0) {
p-host_ip = strdup(val);
+   } else if (strcmp(param, vhost) == 0) {
+   p-vhost = atoi(val);
}
 
return 0;
diff --git a/tools/kvm/include/kvm/virtio-net.h 
b/tools/kvm/include/kvm/virtio-net.h
index 58ae162..dade8cb 100644
--- a/tools/kvm/include/kvm/virtio-net.h
+++ b/tools/kvm/include/kvm/virtio-net.h
@@ -11,6 +11,7 @@ struct virtio_net_params {
char host_mac[6];
struct kvm *kvm;
int mode;
+   int vhost;
 };
 
 void virtio_net__init(const struct virtio_net_params *params);
diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index cee2b5b..58ca4ed 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -10,6 +10,7 @@
 #include kvm/guest_compat.h
 #include kvm/virtio-trans.h
 
+#include linux/vhost.h
 #include linux/virtio_net.h
 #include linux/if_tun.h
 #include linux/types.h
@@ -25,6 +26,7 @@
 #include sys/ioctl.h
 #include sys/types.h
 #include sys/wait.h
+#include sys/eventfd.h
 
 #define VIRTIO_NET_QUEUE_SIZE  128
 #define VIRTIO_NET_NUM_QUEUES  2
@@ -57,6 +59,7 @@ struct net_dev {
pthread_mutex_t io_tx_lock;
pthread_cond_t  io_tx_cond;
 
+   int vhost_fd;
int tap_fd;
chartap_name[IFNAMSIZ];
 
@@ -323,9 +326,12 @@ static void set_guest_features(struct kvm *kvm, void *dev, 
u32 features)
 
 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
 {
+   struct vhost_vring_state state = { .index = vq };
+   struct vhost_vring_addr addr;
struct net_dev *ndev = dev;
struct virt_queue *queue;
void *p;
+   int r;
 
compat__remove_message(compat_id);
 
@@ -335,9 +341,82 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 
pfn)
 
vring_init(queue-vring, VIRTIO_NET_QUEUE_SIZE, p, 
VIRTIO_PCI_VRING_ALIGN);
 
+   if (ndev-vhost_fd == 0)
+   return 0;
+
+   state.num = queue-vring.num;
+   r = ioctl(ndev-vhost_fd, VHOST_SET_VRING_NUM, state);
+   if (r  0)
+   die_perror(VHOST_SET_VRING_NUM failed);
+   state.num = 0;
+   r = ioctl(ndev-vhost_fd, VHOST_SET_VRING_BASE, state);
+   if (r  0)
+   die_perror(VHOST_SET_VRING_BASE failed);
+
+   addr = (struct vhost_vring_addr) {
+   .index = vq,
+   .desc_user_addr = (u64)(unsigned long)queue-vring.desc,
+   .avail_user_addr = (u64)(unsigned long)queue-vring.avail,
+   .used_user_addr = (u64)(unsigned long)queue-vring.used,
+   };
+
+   r = ioctl(ndev-vhost_fd, VHOST_SET_VRING_ADDR, addr);
+   if (r  0)
+   die_perror(VHOST_SET_VRING_ADDR failed);
+
return 0;
 }
 
+static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi)
+{
+   struct net_dev *ndev = dev;
+   struct kvm_irqfd irq;
+   struct vhost_vring_file file;
+   int r;
+
+   if (ndev-vhost_fd == 0)
+   return;
+
+   irq = (struct kvm_irqfd) {
+   .gsi= gsi,
+   .fd = eventfd(0, 0),
+   };
+   file = (struct vhost_vring_file) {
+   .index  = vq,
+   .fd = irq.fd,
+   };
+
+   r = ioctl(kvm-vm_fd, KVM_IRQFD, irq);
+   if (r  0)
+   die_perror(KVM_IRQFD failed);
+
+   r = ioctl(ndev-vhost_fd, VHOST_SET_VRING_CALL, file);
+   if (r  0)
+   die_perror(VHOST_SET_VRING_CALL failed);
+   file.fd = ndev-tap_fd;
+   r = ioctl(ndev-vhost_fd, VHOST_NET_SET_BACKEND, file);
+   if (r != 0)
+   die(VHOST_NET_SET_BACKEND failed %d, errno);
+
+}
+
+static void notify_vq_eventfd(struct kvm *kvm, void *dev, u32 vq, u32 efd)
+{
+   struct net_dev *ndev = dev;
+   struct vhost_vring_file file = {
+   .index  = vq,
+   .fd = efd,
+   };
+   int r;
+
+   if (ndev-vhost_fd == 0)
+   return;
+
+   r = ioctl(ndev-vhost_fd, 

Re: [PATCH 2/2] kvm tools: Add vhost-net support

2011-11-16 Thread Sasha Levin
On Wed, 2011-11-16 at 14:24 +0200, Sasha Levin wrote:
 This patch adds support to using the vhost-net device when using a tap backed
 virtio-net device.
 
 Activating vhost-net is done by appending a 'vhost=1' flag to the net device
 configuration. For example:
 
   'kvm run -n mode=tap,vhost=1'
 
 Cc: Michael S. Tsirkin m...@redhat.com
 Signed-off-by: Sasha Levin levinsasha...@gmail.com
 ---

I forgot to attach performance numbers to the changelog, so here they
are:

Short version
--

TCP Throughput: +29%
UDP Throughput: +10%
TCP Latency: -15%
UDP Latency: -12%


Long version
--

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
192.168.33.4 (192.168.33.4) port 0 AF_INET
Recv   SendSend  
Socket Socket  Message  Elapsed  
Size   SizeSize Time Throughput  
bytes  bytes   bytessecs.10^6bits/sec  

 87380  16384  1638410.004895.04

MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
192.168.33.4 (192.168.33.4) port 0 AF_INET
Socket  Message  Elapsed  Messages
SizeSize Time Okay Errors   Throughput
bytes   bytessecs#  #   10^6bits/sec

229376   65507   10.00  125287  06565.60
229376   10.00  106910   5602.57

MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to 192.168.33.4 (192.168.33.4) port 0 AF_INET : first burst 0
Local /Remote
Socket Size   Request  Resp.   Elapsed  Trans.
Send   Recv   Size SizeTime Rate 
bytes  Bytes  bytesbytes   secs.per sec   

16384  87380  11   10.0014811.55

MIGRATED UDP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to 192.168.33.4 (192.168.33.4) port 0 AF_INET : first burst 0
Local /Remote
Socket Size   Request  Resp.   Elapsed  Trans.
Send   Recv   Size SizeTime Rate 
bytes  Bytes  bytesbytes   secs.per sec   

229376 229376 11   10.0016000.44   
229376 229376

After:

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
192.168.33.4 (192.168.33.4) port 0 AF_INET
Recv   SendSend  
Socket Socket  Message  Elapsed  
Size   SizeSize Time Throughput  
bytes  bytes   bytessecs.10^6bits/sec  

 87380  16384  1638410.006340.74

MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
192.168.33.4 (192.168.33.4) port 0 AF_INET
Socket  Message  Elapsed  Messages
SizeSize Time Okay Errors   Throughput
bytes   bytessecs#  #   10^6bits/sec

229376   65507   10.00  131478  06890.09
229376   10.00  118136   6190.90

MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to 192.168.33.4 (192.168.33.4) port 0 AF_INET : first burst 0
Local /Remote
Socket Size   Request  Resp.   Elapsed  Trans.
Send   Recv   Size SizeTime Rate 
bytes  Bytes  bytesbytes   secs.per sec   

16384  87380  11   10.0017126.10

MIGRATED UDP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to 192.168.33.4 (192.168.33.4) port 0 AF_INET : first burst 0
Local /Remote
Socket Size   Request  Resp.   Elapsed  Trans.
Send   Recv   Size SizeTime Rate 
bytes  Bytes  bytesbytes   secs.per sec   

229376 229376 11   10.0017944.51

-- 

Sasha.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html