qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 5/5] vhost-user: Add new option to specify vhost-


From: Tetsuya Mukawa
Subject: [Qemu-devel] [PATCH v2 5/5] vhost-user: Add new option to specify vhost-user backend supports
Date: Mon, 22 Jun 2015 12:50:48 +0900

This patch adds 'backend_features' option for vhost-user backends.
If this option is specified, QEMU assumes vhost-user backends support
the features specified by user, and QEMU can start without vhost-user
backend.

Here are examples.
* QEMU is configured as vhost-user client.
 -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
 -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend-features=0x68000 \
 -device virtio-net-pci,netdev=net0 \

* QEMU is configured as vhost-user server.
 -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
 -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend-features=0x68000 \
 -device virtio-net-pci,netdev=net0 \

To know vhost-user backend features that the backend expects, please
specify 0xffffffff as backend-features, then invoke QEMU and check error log
like below.

  Lack of backend features. Expected 0xffffffff, but receives 0x68000

Above log indicates the backend features QEMU should be passed.

Signed-off-by: Tetsuya Mukawa <address@hidden>
---
 hw/net/vhost_net.c             |  6 +++++-
 hw/net/virtio-net.c            | 15 +++++++++++++++
 hw/scsi/vhost-scsi.c           |  2 +-
 hw/virtio/vhost-user.c         |  6 ++++++
 hw/virtio/vhost.c              |  3 ++-
 include/hw/virtio/vhost.h      |  3 ++-
 include/hw/virtio/virtio-net.h |  1 +
 include/net/net.h              |  3 +++
 include/net/vhost_net.h        |  1 +
 net/net.c                      |  9 +++++++++
 net/tap.c                      |  1 +
 net/vhost-user.c               | 19 +++++++++++++++++--
 qapi-schema.json               | 12 ++++++++++--
 qemu-options.hx                |  3 ++-
 14 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 9bd360b..b9425ea 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -162,8 +162,12 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     net->dev.vqs = net->vqs;
     net->dev.vq_index = net->nc->queue_index;
 
+    if (options->backend_features) {
+        net->dev.backend_features = options->backend_features;
+    }
+
     r = vhost_dev_init(&net->dev, options->opaque,
-                       options->backend_type);
+                       options->backend_type, options->backend_features);
     if (r < 0) {
         goto fail;
     }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index d728233..7138f4e 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -363,6 +363,18 @@ static int peer_has_ufo(VirtIONet *n)
     return n->has_ufo;
 }
 
+static uint64_t peer_backend_features(VirtIONet *n)
+{
+    if (!peer_has_vnet_hdr(n)) {
+        return 0;
+    }
+
+    n->backend_features =
+            qemu_backend_features(qemu_get_queue(n->nic)->peer);
+
+    return n->backend_features;
+}
+
 static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
                                        int version_1)
 {
@@ -467,6 +479,9 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, 
uint64_t features)
 
     if (!get_vhost_net(nc->peer)) {
         virtio_add_feature(&features, VIRTIO_F_VERSION_1);
+        if (peer_backend_features(n)) {
+            features = peer_backend_features(n);
+        }
         return features;
     }
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 1c389c4..1d7957c 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -246,7 +246,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error 
**errp)
     s->dev.backend_features = 0;
 
     ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
-                         VHOST_BACKEND_TYPE_KERNEL);
+                         VHOST_BACKEND_TYPE_KERNEL, 0);
     if (ret < 0) {
         error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
                    strerror(-ret));
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 2215c39..3caa1a0 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -315,6 +315,12 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned 
long int request,
                 error_report("Received bad msg size.");
                 goto close;
             }
+            if (dev->backend_features != (dev->backend_features & msg.u64)) {
+                error_report("Lack of backend features. "
+                            "Expected 0x%llx, but receives 0x%" PRIx64,
+                            dev->backend_features, msg.u64);
+                goto close;
+            }
             *((__u64 *) arg) = msg.u64;
             break;
         case VHOST_USER_GET_VRING_BASE:
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index a6dcc79..bbfc336 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -901,7 +901,8 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue 
*vq)
 }
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type)
+                   VhostBackendType backend_type,
+                   unsigned long long backend_features)
 {
     uint64_t features;
     int i, r;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index dd51050..074b36b 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -60,7 +60,8 @@ struct vhost_dev {
 };
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type);
+                   VhostBackendType backend_type,
+                   unsigned long long backend_features);
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 280dacf..871dc3c 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -70,6 +70,7 @@ typedef struct VirtIONet {
     size_t guest_hdr_len;
     uint32_t host_features;
     uint8_t has_ufo;
+    uint64_t backend_features;
     int mergeable_rx_bufs;
     uint8_t promisc;
     uint8_t allmulti;
diff --git a/include/net/net.h b/include/net/net.h
index 4306252..d4379d1 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -57,6 +57,7 @@ typedef void (SetOffload)(NetClientState *, int, int, int, 
int, int);
 typedef void (SetVnetHdrLen)(NetClientState *, int);
 typedef int (SetVnetLE)(NetClientState *, bool);
 typedef int (SetVnetBE)(NetClientState *, bool);
+typedef unsigned long long (BackendFeatures)(NetClientState *);
 
 typedef struct NetClientInfo {
     NetClientOptionsKind type;
@@ -77,6 +78,7 @@ typedef struct NetClientInfo {
     SetVnetHdrLen *set_vnet_hdr_len;
     SetVnetLE *set_vnet_le;
     SetVnetBE *set_vnet_be;
+    BackendFeatures *backend_features;
 } NetClientInfo;
 
 struct NetClientState {
@@ -140,6 +142,7 @@ bool qemu_has_ufo(NetClientState *nc);
 bool qemu_has_vnet_hdr(NetClientState *nc);
 bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
 void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
+unsigned long long qemu_backend_features(NetClientState *nc);
 void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
                       int ecn, int ufo);
 void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 840d4b1..0b19b4a 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -11,6 +11,7 @@ typedef struct VhostNetOptions {
     VhostBackendType backend_type;
     NetClientState *net_backend;
     void *opaque;
+    unsigned long long backend_features;
 } VhostNetOptions;
 
 struct vhost_net *vhost_net_init(VhostNetOptions *options);
diff --git a/net/net.c b/net/net.c
index 6dbd61a..4ad7a69 100644
--- a/net/net.c
+++ b/net/net.c
@@ -528,6 +528,15 @@ int qemu_set_vnet_be(NetClientState *nc, bool is_be)
     return nc->info->set_vnet_be(nc, is_be);
 }
 
+unsigned long long qemu_backend_features(NetClientState *nc)
+{
+    if (!nc || !nc->info->backend_features) {
+        return false;
+    }
+
+    return nc->info->backend_features(nc);
+}
+
 int qemu_can_send_packet(NetClientState *sender)
 {
     int vm_running = runstate_is_running();
diff --git a/net/tap.c b/net/tap.c
index bd01590..743c168 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -662,6 +662,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
 
         options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
         options.net_backend = &s->nc;
+        options.backend_features = tap->backend_features;
 
         if (tap->has_vhostfd || tap->has_vhostfds) {
             vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 58cd5dc..fd46e32 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -19,6 +19,7 @@ typedef struct VhostUserState {
     NetClientState nc;
     CharDriverState *chr;
     VHostNetState *vhost_net;
+    unsigned long long backend_features;
     int watch;
 } VhostUserState;
 
@@ -53,6 +54,7 @@ static int vhost_user_start(VhostUserState *s)
     options.backend_type = VHOST_BACKEND_TYPE_USER;
     options.net_backend = &s->nc;
     options.opaque = s->chr;
+    options.backend_features = s->backend_features;
 
     s->vhost_net = vhost_net_init(&options);
 
@@ -90,12 +92,22 @@ static bool vhost_user_has_ufo(NetClientState *nc)
     return true;
 }
 
+static unsigned long long vhost_user_backend_features(NetClientState *nc)
+{
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+
+    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
+
+    return s->backend_features;
+}
+
 static NetClientInfo net_vhost_user_info = {
         .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
         .size = sizeof(VhostUserState),
         .cleanup = vhost_user_cleanup,
         .has_vnet_hdr = vhost_user_has_vnet_hdr,
         .has_ufo = vhost_user_has_ufo,
+        .backend_features = vhost_user_backend_features,
 };
 
 static void net_vhost_link_down(VhostUserState *s, bool link_down)
@@ -152,7 +164,8 @@ static void net_vhost_user_event(void *opaque, int event)
 
 static int net_vhost_user_init(NetClientState *peer, const char *device,
                                const char *name, CharDriverState *chr,
-                               uint32_t queues)
+                               uint32_t queues,
+                               unsigned long long backend_features)
 {
     NetClientState *nc;
     VhostUserState *s;
@@ -170,6 +183,7 @@ static int net_vhost_user_init(NetClientState *peer, const 
char *device,
         s->nc.receive_disabled = 1;
         s->chr = chr;
         s->nc.queue_index = i;
+        s->backend_features = backend_features;
 
         qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s);
     }
@@ -279,5 +293,6 @@ int net_init_vhost_user(const NetClientOptions *opts, const 
char *name,
         queues = 1;
     }
 
-    return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
+    return net_vhost_user_init(peer, "vhost_user", name, chr, queues,
+                                vhost_user_opts->backend_features);
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index 106008c..88760e5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2262,6 +2262,9 @@
 #
 # @queues: #optional number of queues to be created for multiqueue capable tap
 #
+# @backend-features: #optional feature flag to support vhost user backend
+#                    (since 2.4)
+#
 # Since 1.2
 ##
 { 'struct': 'NetdevTapOptions',
@@ -2278,7 +2281,8 @@
     '*vhostfd':    'str',
     '*vhostfds':   'str',
     '*vhostforce': 'bool',
-    '*queues':     'uint32'} }
+    '*queues':     'uint32',
+    '*backend-features':'uint64'} }
 
 ##
 # @NetdevSocketOptions
@@ -2466,13 +2470,17 @@
 # @queues: #optional number of queues to be created for multiqueue vhost-user
 #          (default: 1) (Since 2.4)
 #
+# @backend-features: #optional feature flag to support vhost user backend
+#                    (default: 0) (since 2.4)
+#
 # Since 2.1
 ##
 { 'struct': 'NetdevVhostUserOptions',
   'data': {
     'chardev':        'str',
     '*vhostforce':    'bool',
-    '*queues':        'uint32' } }
+    '*queues':        'uint32',
+    '*backend-features':    'uint64' } }
 
 ##
 # @NetClientOptions
diff --git a/qemu-options.hx b/qemu-options.hx
index 7959dd0..69f13c2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1473,7 +1473,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
 #else
     "-netdev 
tap,id=str[,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]\n"
     "         
[,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off]\n"
-    "         
[,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]\n"
+    "         
[,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n][,backend-features=n]\n"
     "                configure a host TAP network backend with ID 'str'\n"
     "                use network scripts 'file' (default=" 
DEFAULT_NETWORK_SCRIPT ")\n"
     "                to configure it and 'dfile' (default=" 
DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
@@ -1493,6 +1493,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "                use 'vhostfd=h' to connect to an already opened vhost net 
device\n"
     "                use 'vhostfds=x:y:...:z to connect to multiple already 
opened vhost net devices\n"
     "                use 'queues=n' to specify the number of queues to be 
created for multiqueue TAP\n"
+    "                use 'backend-features=n' to specify the features that 
vhost backend supported\n"
     "-netdev bridge,id=str[,br=bridge][,helper=helper]\n"
     "                configure a host TAP network backend with ID 'str' that 
is\n"
     "                connected to a bridge (default=" DEFAULT_BRIDGE_INTERFACE 
")\n"
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]