From: "Michael S. Tsirkin" <mst@redhat.com>
To: Antonios Motakis <a.motakis@virtualopensystems.com>
Cc: snabb-devel@googlegroups.com,
Anthony Liguori <aliguori@amazon.com>,
tech@virtualopensystems.com, Jason Wang <jasowang@redhat.com>,
Michael Tokarev <mjt@tls.msk.ru>,
qemu-devel@nongnu.org, n.nikolaev@virtualopensystems.com,
Markus Armbruster <armbru@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
lukego@gmail.com, Paolo Bonzini <pbonzini@redhat.com>,
Luiz Capitulino <lcapitulino@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v5 6/7] Add new vhost-user netdev backend
Date: Thu, 9 Jan 2014 18:14:01 +0200 [thread overview]
Message-ID: <20140109161401.GE3485@redhat.com> (raw)
In-Reply-To: <1389279601-1924-7-git-send-email-a.motakis@virtualopensystems.com>
On Thu, Jan 09, 2014 at 04:00:00PM +0100, Antonios Motakis wrote:
> Add a new QEMU netdev backend that is intended to invoke vhost_net
> with the vhost-user backend. Also decouple virtio-net from the tap
> backend.
>
> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
> Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com>
> ---
> hmp-commands.hx | 4 +-
> hw/net/vhost_net.c | 66 ++++++++++++++++++++++------
> hw/net/virtio-net.c | 42 ++++++++----------
> hw/virtio/vhost.c | 1 -
> include/net/vhost-user.h | 17 ++++++++
> include/net/vhost_net.h | 1 +
> net/Makefile.objs | 2 +-
> net/clients.h | 3 ++
> net/hub.c | 1 +
> net/net.c | 2 +
> net/vhost-user.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++
> qapi-schema.json | 18 +++++++-
> qemu-options.hx | 3 ++
> 13 files changed, 227 insertions(+), 44 deletions(-)
> create mode 100644 include/net/vhost-user.h
> create mode 100644 net/vhost-user.c
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index ebe8e78..d5a3774 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1190,7 +1190,7 @@ ETEXI
> {
> .name = "host_net_add",
> .args_type = "device:s,opts:s?",
> - .params = "tap|user|socket|vde|netmap|dump [options]",
> + .params = "tap|user|socket|vde|netmap|vhost-user|dump [options]",
> .help = "add host VLAN client",
> .mhandler.cmd = net_host_device_add,
> },
> @@ -1218,7 +1218,7 @@ ETEXI
> {
> .name = "netdev_add",
> .args_type = "netdev:O",
> - .params = "[user|tap|socket|hubport|netmap],id=str[,prop=value][,...]",
> + .params = "[user|tap|socket|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
> .help = "add host network device",
> .mhandler.cmd = hmp_netdev_add,
> },
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 3614e6c..e42f4d6 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -15,6 +15,7 @@
>
> #include "net/net.h"
> #include "net/tap.h"
> +#include "net/vhost-user.h"
>
> #include "hw/virtio/virtio-net.h"
> #include "net/vhost_net.h"
> @@ -174,15 +175,20 @@ static int vhost_net_start_one(struct vhost_net *net,
> goto fail_start;
> }
>
> - net->nc->info->poll(net->nc, false);
> - qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
> - file.fd = net->backend;
> - for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
> - const VhostOps *vhost_ops = net->dev.vhost_ops;
> - r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
> - if (r < 0) {
> - r = -errno;
> - goto fail;
> + if (net->nc->info->poll) {
> + net->nc->info->poll(net->nc, false);
> + }
> +
> + if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
> + qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
> + file.fd = net->backend;
> + for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
> + const VhostOps *vhost_ops = net->dev.vhost_ops;
> + r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
> + if (r < 0) {
> + r = -errno;
> + goto fail;
> + }
> }
> }
> return 0;
> @@ -193,7 +199,9 @@ fail:
> int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
> assert(r >= 0);
> }
> - net->nc->info->poll(net->nc, true);
> + if (net->nc->info->poll) {
> + net->nc->info->poll(net->nc, true);
> + }
> vhost_dev_stop(&net->dev, dev);
> fail_start:
> vhost_dev_disable_notifiers(&net->dev, dev);
> @@ -215,7 +223,9 @@ static void vhost_net_stop_one(struct vhost_net *net,
> int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
> assert(r >= 0);
> }
> - net->nc->info->poll(net->nc, true);
> + if (net->nc->info->poll) {
> + net->nc->info->poll(net->nc, true);
> + }
> vhost_dev_stop(&net->dev, dev);
> vhost_dev_disable_notifiers(&net->dev, dev);
> }
> @@ -235,7 +245,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
> }
>
> for (i = 0; i < total_queues; i++) {
> - r = vhost_net_start_one(tap_get_vhost_net(ncs[i].peer), dev, i * 2);
> + r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev, i * 2);
>
> if (r < 0) {
> goto err;
> @@ -252,7 +262,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
>
> err:
> while (--i >= 0) {
> - vhost_net_stop_one(tap_get_vhost_net(ncs[i].peer), dev);
> + vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
> }
> return r;
> }
> @@ -273,7 +283,7 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
> assert(r >= 0);
>
> for (i = 0; i < total_queues; i++) {
> - vhost_net_stop_one(tap_get_vhost_net(ncs[i].peer), dev);
> + vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
> }
> }
>
> @@ -293,6 +303,29 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> {
> vhost_virtqueue_mask(&net->dev, dev, idx, mask);
> }
> +
> +VHostNetState *get_vhost_net(NetClientState *nc)
> +{
> + VHostNetState *vhost_net = 0;
> +
> + if (!nc) {
> + return 0;
> + }
> +
> + switch (nc->info->type) {
> + case NET_CLIENT_OPTIONS_KIND_TAP:
> + vhost_net = tap_get_vhost_net(nc);
> + break;
> + case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
> + vhost_net = vhost_user_get_vhost_net(nc);
> + break;
> + default:
> + break;
> + }
> +
> + return vhost_net;
> +}
> +
> #else
> struct vhost_net *vhost_net_init(VhostNetOptions *options)
> {
> @@ -338,4 +371,9 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> int idx, bool mask)
> {
> }
> +
> +VHostNetState *get_vhost_net(NetClientState *nc)
> +{
> + return 0;
> +}
> #endif
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 3626608..d49ee82 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -105,14 +105,7 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
> NetClientState *nc = qemu_get_queue(n->nic);
> int queues = n->multiqueue ? n->max_queues : 1;
>
> - if (!nc->peer) {
> - return;
> - }
> - if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
> - return;
> - }
> -
> - if (!tap_get_vhost_net(nc->peer)) {
> + if (!get_vhost_net(nc->peer)) {
> return;
> }
>
> @@ -122,7 +115,7 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
> }
> if (!n->vhost_started) {
> int r;
> - if (!vhost_net_query(tap_get_vhost_net(nc->peer), vdev)) {
> + if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {
> return;
> }
> n->vhost_started = 1;
> @@ -325,11 +318,16 @@ static void peer_test_vnet_hdr(VirtIONet *n)
> return;
> }
>
> - if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
> - return;
> + switch (nc->peer->info->type) {
> + case NET_CLIENT_OPTIONS_KIND_TAP:
> + n->has_vnet_hdr = tap_has_vnet_hdr(nc->peer);
> + break;
> + case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
> + n->has_vnet_hdr = 0;
> + break;
> + default:
> + break;
> }
> -
> - n->has_vnet_hdr = tap_has_vnet_hdr(nc->peer);
> }
>
> static int peer_has_vnet_hdr(VirtIONet *n)
> @@ -437,13 +435,10 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
> features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
> }
>
> - if (!nc->peer || nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
> + if (!get_vhost_net(nc->peer)) {
> return features;
> }
> - if (!tap_get_vhost_net(nc->peer)) {
> - return features;
> - }
> - return vhost_net_get_features(tap_get_vhost_net(nc->peer), features);
> + return vhost_net_get_features(get_vhost_net(nc->peer), features);
> }
>
> static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
> @@ -507,13 +502,10 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
> for (i = 0; i < n->max_queues; i++) {
> NetClientState *nc = qemu_get_subqueue(n->nic, i);
>
> - if (!nc->peer || nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
> - continue;
> - }
> - if (!tap_get_vhost_net(nc->peer)) {
> + if (!get_vhost_net(nc->peer)) {
> continue;
> }
> - vhost_net_ack_features(tap_get_vhost_net(nc->peer), features);
> + vhost_net_ack_features(get_vhost_net(nc->peer), features);
> }
> }
>
> @@ -1443,7 +1435,7 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
> VirtIONet *n = VIRTIO_NET(vdev);
> NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
> assert(n->vhost_started);
> - return vhost_net_virtqueue_pending(tap_get_vhost_net(nc->peer), idx);
> + return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> }
>
> static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> @@ -1452,7 +1444,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> VirtIONet *n = VIRTIO_NET(vdev);
> NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
> assert(n->vhost_started);
> - vhost_net_virtqueue_mask(tap_get_vhost_net(nc->peer),
> + vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
> vdev, idx, mask);
> }
>
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index a1137e1..fe622fb 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -14,7 +14,6 @@
> */
>
> #include "hw/virtio/vhost.h"
> -#include "hw/virtio/vhost-backend.h"
> #include "hw/hw.h"
> #include "qemu/atomic.h"
> #include "qemu/range.h"
> diff --git a/include/net/vhost-user.h b/include/net/vhost-user.h
> new file mode 100644
> index 0000000..85109f6
> --- /dev/null
> +++ b/include/net/vhost-user.h
> @@ -0,0 +1,17 @@
> +/*
> + * vhost-user.h
> + *
> + * Copyright (c) 2013 Virtual Open Systems Sarl.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef VHOST_USER_H_
> +#define VHOST_USER_H_
> +
> +struct vhost_net;
> +struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc);
> +
> +#endif /* VHOST_USER_H_ */
> diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> index 1169562..abd3d0b 100644
> --- a/include/net/vhost_net.h
> +++ b/include/net/vhost_net.h
> @@ -31,4 +31,5 @@ void vhost_net_ack_features(VHostNetState *net, unsigned features);
> bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
> void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> int idx, bool mask);
> +VHostNetState *get_vhost_net(NetClientState *nc);
> #endif
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index c25fe69..301f6b6 100644
> --- a/net/Makefile.objs
> +++ b/net/Makefile.objs
> @@ -2,7 +2,7 @@ common-obj-y = net.o queue.o checksum.o util.o hub.o
> common-obj-y += socket.o
> common-obj-y += dump.o
> common-obj-y += eth.o
> -common-obj-$(CONFIG_POSIX) += tap.o
> +common-obj-$(CONFIG_POSIX) += tap.o vhost-user.o
> common-obj-$(CONFIG_LINUX) += tap-linux.o
> common-obj-$(CONFIG_WIN32) += tap-win32.o
> common-obj-$(CONFIG_BSD) += tap-bsd.o
> diff --git a/net/clients.h b/net/clients.h
> index 7322ff5..7f3d4ae 100644
> --- a/net/clients.h
> +++ b/net/clients.h
> @@ -57,4 +57,7 @@ int net_init_netmap(const NetClientOptions *opts, const char *name,
> NetClientState *peer);
> #endif
>
> +int net_init_vhost_user(const NetClientOptions *opts, const char *name,
> + NetClientState *peer);
> +
> #endif /* QEMU_NET_CLIENTS_H */
> diff --git a/net/hub.c b/net/hub.c
> index 33a99c9..7e0f2d6 100644
> --- a/net/hub.c
> +++ b/net/hub.c
> @@ -322,6 +322,7 @@ void net_hub_check_clients(void)
> case NET_CLIENT_OPTIONS_KIND_TAP:
> case NET_CLIENT_OPTIONS_KIND_SOCKET:
> case NET_CLIENT_OPTIONS_KIND_VDE:
> + case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
> has_host_dev = 1;
> break;
> default:
> diff --git a/net/net.c b/net/net.c
> index 9db88cc..0f057c5 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -734,6 +734,7 @@ static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
> [NET_CLIENT_OPTIONS_KIND_BRIDGE] = net_init_bridge,
> #endif
> [NET_CLIENT_OPTIONS_KIND_HUBPORT] = net_init_hubport,
> + [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user,
> };
>
>
> @@ -767,6 +768,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
> case NET_CLIENT_OPTIONS_KIND_BRIDGE:
> #endif
> case NET_CLIENT_OPTIONS_KIND_HUBPORT:
> + case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
> break;
>
> default:
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> new file mode 100644
> index 0000000..6fd5afc
> --- /dev/null
> +++ b/net/vhost-user.c
> @@ -0,0 +1,111 @@
> +/*
> + * vhost-user.c
> + *
> + * Copyright (c) 2013 Virtual Open Systems Sarl.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "clients.h"
> +#include "net/vhost_net.h"
> +#include "net/vhost-user.h"
> +#include "qemu/error-report.h"
> +
> +typedef struct VhostUserState {
> + NetClientState nc;
> + VHostNetState *vhost_net;
> + char *devpath;
> +} VhostUserState;
> +
> +VHostNetState *vhost_user_get_vhost_net(NetClientState *nc)
> +{
> + VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
> + assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
> + return s->vhost_net;
> +}
> +
> +static int vhost_user_running(VhostUserState *s)
> +{
> + return (s->vhost_net) ? 1 : 0;
> +}
> +
> +static int vhost_user_start(VhostUserState *s)
> +{
> + VhostNetOptions options;
> +
> + if (vhost_user_running(s)) {
> + return 1;
> + }
> +
> + options.backend_type = VHOST_BACKEND_TYPE_USER;
> + options.net_backend = &s->nc;
> + options.devpath = s->devpath;
> + options.devfd = -1;
> + options.force = 1;
> +
> + s->vhost_net = vhost_net_init(&options);
> +
> + return vhost_user_running(s) ? 0 : -1;
> +}
> +
> +static void vhost_user_stop(VhostUserState *s)
> +{
> + if (vhost_user_running(s)) {
> + vhost_net_cleanup(s->vhost_net);
> + }
> +
> + s->vhost_net = 0;
> +}
> +
> +static void vhost_user_cleanup(NetClientState *nc)
> +{
> + VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
> +
> + vhost_user_stop(s);
> + qemu_purge_queued_packets(nc);
> +}
> +
> +static NetClientInfo net_vhost_user_info = {
> + .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
> + .size = sizeof(VhostUserState),
> + .cleanup = vhost_user_cleanup,
> +};
> +
> +static int net_vhost_user_init(NetClientState *peer, const char *device,
> + const char *name, const char *filename)
> +{
> + NetClientState *nc;
> + VhostUserState *s;
> + int r;
> +
> + nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
> +
> + snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user to %s", filename);
> +
> + s = DO_UPCAST(VhostUserState, nc, nc);
> +
> + /* We don't provide a receive callback */
> + s->nc.receive_disabled = 1;
> +
> + s->devpath = g_strdup(filename);
> +
> + r = vhost_user_start(s);
> +
> + return r;
> +}
> +
> +int net_init_vhost_user(const NetClientOptions *opts, const char *name,
> + NetClientState *peer)
> +{
> + const char *file;
> + const NetdevVhostUserOptions *vhost_user;
> +
> + assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
> + vhost_user = opts->vhost_user;
> +
> + file = vhost_user->file;
> +
> + return net_vhost_user_init(peer, "vhost_user", name, file);
> +}
> diff --git a/qapi-schema.json b/qapi-schema.json
> index c3c939c..3101287 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3030,6 +3030,21 @@
> '*devname': 'str' } }
>
> ##
> +# @NetdevVhostUserOptions
> +#
> +# Vhost-user network backend
> +#
> +# @file: control socket path
> +#
> +# Since 2.0
> +##
> +{ 'type': 'NetdevVhostUserOptions',
> + 'data': {
> + 'file': 'str' } }
> +
> +##
> +
> +##
> # @NetClientOptions
> #
> # A discriminated record of network device traits.
> @@ -3047,7 +3062,8 @@
> 'dump': 'NetdevDumpOptions',
> 'bridge': 'NetdevBridgeOptions',
> 'hubport': 'NetdevHubPortOptions',
> - 'netmap': 'NetdevNetmapOptions' } }
> + 'netmap': 'NetdevNetmapOptions',
> + 'vhost-user': 'NetdevVhostUserOptions' } }
>
> ##
> # @NetLegacy
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 0d35c9c..edf25d0 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1419,6 +1419,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
> " VALE port (created on the fly) called 'name' ('nmname' is name of the \n"
> " netmap device, defaults to '/dev/netmap')\n"
> #endif
> + "-net vhost-user,file=name\n"
> + " connect to a unix domain socket implementing vhost-user backend\n"
I'm guessing this does not work, you really must use this with -netdev?
> "-net dump[,vlan=n][,file=f][,len=n]\n"
> " dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
> "-net none use it alone to have zero network devices. If no -net option\n"
> @@ -1436,6 +1438,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
> #ifdef CONFIG_NETMAP
> "netmap|"
> #endif
> + "vhost-user|"
> "socket|"
> "hubport],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL)
> STEXI
> --
> 1.8.3.2
>
next prev parent reply other threads:[~2014-01-09 16:14 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-09 14:59 [Qemu-devel] [PATCH v5 0/7] Vhost and vhost-net support for userspace based backends Antonios Motakis
2014-01-09 14:59 ` [Qemu-devel] [PATCH v5 1/7] Convert -mem-path to QemuOpts and add prealloc, share and unlink properties Antonios Motakis
2014-01-09 16:01 ` Michael S. Tsirkin
2014-01-10 11:05 ` Antonios Motakis
2014-01-10 12:31 ` Michael S. Tsirkin
2014-01-13 8:30 ` Edgar E. Iglesias
2014-01-09 14:59 ` [Qemu-devel] [PATCH v5 2/7] Decouple vhost from kernel interface Antonios Motakis
2014-01-09 14:59 ` [Qemu-devel] [PATCH v5 3/7] Add vhost-user skeleton Antonios Motakis
2014-01-09 14:59 ` [Qemu-devel] [PATCH v5 4/7] Add domain socket communication for vhost-user backend Antonios Motakis
2014-01-09 15:31 ` Michael S. Tsirkin
2014-01-10 11:09 ` Antonios Motakis
2014-01-09 14:59 ` [Qemu-devel] [PATCH v5 5/7] Add vhost-user calls implementation Antonios Motakis
2014-01-09 15:47 ` Michael S. Tsirkin
2014-01-10 11:07 ` Antonios Motakis
2014-01-09 15:00 ` [Qemu-devel] [PATCH v5 6/7] Add new vhost-user netdev backend Antonios Motakis
2014-01-09 16:14 ` Michael S. Tsirkin [this message]
2014-01-10 11:00 ` Antonios Motakis
2014-01-09 15:00 ` [Qemu-devel] [PATCH v5 7/7] Add vhost-user reconnection Antonios Motakis
2014-01-09 16:16 ` Michael S. Tsirkin
2014-01-10 10:59 ` Antonios Motakis
2014-01-10 12:29 ` Michael S. Tsirkin
2014-01-09 16:11 ` [Qemu-devel] [PATCH v5 0/7] Vhost and vhost-net support for userspace based backends Michael S. Tsirkin
2014-01-10 10:58 ` Antonios Motakis
2014-01-10 12:25 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140109161401.GE3485@redhat.com \
--to=mst@redhat.com \
--cc=a.motakis@virtualopensystems.com \
--cc=aliguori@amazon.com \
--cc=armbru@redhat.com \
--cc=jasowang@redhat.com \
--cc=lcapitulino@redhat.com \
--cc=lukego@gmail.com \
--cc=mjt@tls.msk.ru \
--cc=n.nikolaev@virtualopensystems.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=snabb-devel@googlegroups.com \
--cc=stefanha@redhat.com \
--cc=tech@virtualopensystems.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.