* [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support
@ 2015-09-24 16:22 marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 01/21] vhost-user: unit test for new messages marcandre.lureau
` (22 more replies)
0 siblings, 23 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Hi,
The following series implement shareable log for vhost-user to support
memory tracking during live migration. On qemu-side, the solution is
fairly straightfoward since vhost already supports the dirty log, only
vhost-user couldn't access the log memory until then.
The series includes "protocol feature negotiation" series proposed
earlier by Michael S. Tsirkinm and "vhost user: Add live migration"
series from Thibaut Collet .
v4->v5:
- rebase on top of last Michael S. Tsirkin PULL request
- block live migration if !PROTOCOL_F_LOG_SHMFD
- wait for a reply after SET_LOG_BASE
- split vhost_set_log_base from the rest of vhost_call refactoring
- use a seperate global vhost_log_shm
v3->v4:
- add the proto negotiation & the migration series
- replace the varargs vhost_call() approach for callbacks
- only share-allocate when the backend needs it
v2->v3:
- changed some patch summary
- added migration tests
- added a patch to replace error message with a trace
The development branch I used is:
https://github.com/elmarco/qemu branch "vhost-user"
Marc-André Lureau (18):
configure: probe for memfd
util: add linux-only memfd fallback
util: add memfd helpers
vhost: alloc shareable log
vhost: document log resizing
vhost: add vhost_set_log_base op
vhost-user: send log shm fd along with log_base
vhost-user: add a migration blocker
vhost: use a function for each call
vhost: only use shared log if in use by backend
vhost-user: document migration log
net: add trace_vhost_user_event
vhost-user-test: move wait_for_fds() out
vhost-user-test: remove useless static check
vhost-user-test: wrap server in TestServer struct
vhost-user-test: learn to tweak various qemu arguments
vhost-user-test: add live-migration test
vhost-user-test: check ownership during migration
Michael S. Tsirkin (1):
vhost-user: unit test for new messages
Thibaut Collet (2):
vhost user: add support of live migration
vhost user: add rarp sending after live migration for legacy guest
configure | 19 ++
docs/specs/vhost-user.txt | 63 ++++-
hw/net/vhost_net.c | 35 ++-
hw/scsi/vhost-scsi.c | 7 +-
hw/virtio/vhost-backend.c | 121 +++++++-
hw/virtio/vhost-user.c | 571 ++++++++++++++++++++++++--------------
hw/virtio/vhost.c | 101 ++++---
include/hw/virtio/vhost-backend.h | 77 ++++-
include/hw/virtio/vhost.h | 15 +-
include/net/vhost_net.h | 1 +
include/qemu/memfd.h | 24 ++
net/vhost-user.c | 34 ++-
tests/vhost-user-test.c | 390 ++++++++++++++++++++++----
trace-events | 3 +
util/Makefile.objs | 2 +-
util/memfd.c | 126 +++++++++
16 files changed, 1260 insertions(+), 329 deletions(-)
create mode 100644 include/qemu/memfd.h
create mode 100644 util/memfd.c
--
2.4.3
^ permalink raw reply [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 01/21] vhost-user: unit test for new messages
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 02/21] configure: probe for memfd marcandre.lureau
` (21 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel; +Cc: thibaut.collet, jasowang, mst, haifeng.lin, pbonzini
From: "Michael S. Tsirkin" <mst@redhat.com>
Data is empty for now, but do make sure master
sets the new feature bit flag.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
tests/vhost-user-test.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index e301db7..77b7b68 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -53,6 +53,8 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
+#define VHOST_USER_F_PROTOCOL_FEATURES 30
+
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
VHOST_USER_GET_FEATURES = 1,
@@ -69,6 +71,8 @@ typedef enum VhostUserRequest {
VHOST_USER_SET_VRING_KICK = 12,
VHOST_USER_SET_VRING_CALL = 13,
VHOST_USER_SET_VRING_ERR = 14,
+ VHOST_USER_GET_PROTOCOL_FEATURES = 15,
+ VHOST_USER_SET_PROTOCOL_FEATURES = 16,
VHOST_USER_MAX
} VhostUserRequest;
@@ -293,11 +297,26 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
/* send back features to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
msg.size = sizeof(m.u64);
+ msg.u64 = 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
+ p = (uint8_t *) &msg;
+ qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
+ break;
+
+ case VHOST_USER_SET_FEATURES:
+ g_assert_cmpint(msg.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES),
+ !=, 0ULL);
+ break;
+
+ case VHOST_USER_GET_PROTOCOL_FEATURES:
+ /* send back features to qemu */
+ msg.flags |= VHOST_USER_REPLY_MASK;
+ msg.size = sizeof(m.u64);
msg.u64 = 0;
p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break;
+
case VHOST_USER_GET_VRING_BASE:
/* send back vring base to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 02/21] configure: probe for memfd
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 01/21] vhost-user: unit test for new messages marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 03/21] util: add linux-only memfd fallback marcandre.lureau
` (20 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Check if memfd_create() is part of system libc.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
configure | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/configure b/configure
index 52f5b79..a7cdfa4 100755
--- a/configure
+++ b/configure
@@ -3455,6 +3455,22 @@ if compile_prog "" "" ; then
eventfd=yes
fi
+# check if memfd is supported
+memfd=no
+cat > $TMPC << EOF
+#include <sys/memfd.h>
+
+int main(void)
+{
+ return memfd_create("foo", MFD_ALLOW_SEALING);
+}
+EOF
+if compile_prog "" "" ; then
+ memfd=yes
+fi
+
+
+
# check for fallocate
fallocate=no
cat > $TMPC << EOF
@@ -4840,6 +4856,9 @@ fi
if test "$eventfd" = "yes" ; then
echo "CONFIG_EVENTFD=y" >> $config_host_mak
fi
+if test "$memfd" = "yes" ; then
+ echo "CONFIG_MEMFD=y" >> $config_host_mak
+fi
if test "$fallocate" = "yes" ; then
echo "CONFIG_FALLOCATE=y" >> $config_host_mak
fi
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 03/21] util: add linux-only memfd fallback
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 01/21] vhost-user: unit test for new messages marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 02/21] configure: probe for memfd marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 04/21] util: add memfd helpers marcandre.lureau
` (19 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Implement memfd_create() fallback if not available in system libc.
memfd_create() is still not included in glibc today, atlhough it's been
available since Linux 3.17 in Oct 2014.
memfd has numerous advantages over traditional shm/mmap for ipc memory
sharing with fd handler, which we are going to make use of for
vhost-user logging memory in following patches.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qemu/memfd.h | 20 +++++++++++++++++++
util/Makefile.objs | 2 +-
util/memfd.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 77 insertions(+), 1 deletion(-)
create mode 100644 include/qemu/memfd.h
create mode 100644 util/memfd.c
diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h
new file mode 100644
index 0000000..8b1fe6a
--- /dev/null
+++ b/include/qemu/memfd.h
@@ -0,0 +1,20 @@
+#ifndef QEMU_MEMFD_H
+#define QEMU_MEMFD_H
+
+#include "config-host.h"
+
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
+
+#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
+#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
+#define F_SEAL_GROW 0x0004 /* prevent file from growing */
+#define F_SEAL_WRITE 0x0008 /* prevent writes */
+#endif
+
+#endif /* QEMU_MEMFD_H */
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 114d657..84c5485 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -1,6 +1,6 @@
util-obj-y = osdep.o cutils.o unicode.o qemu-timer-common.o
util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win32.o
-util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o
+util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o memfd.o
util-obj-y += envlist.o path.o module.o
util-obj-$(call lnot,$(CONFIG_INT128)) += host-utils.o
util-obj-y += bitmap.o bitops.o hbitmap.o
diff --git a/util/memfd.c b/util/memfd.c
new file mode 100644
index 0000000..a98d57e
--- /dev/null
+++ b/util/memfd.c
@@ -0,0 +1,56 @@
+/*
+ * memfd.c
+ *
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ * QEMU library functions on POSIX which are shared between QEMU and
+ * the QEMU tools.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "config-host.h"
+
+#include "qemu/memfd.h"
+
+#ifdef CONFIG_MEMFD
+#include <sys/memfd.h>
+#elif defined CONFIG_LINUX
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <asm/unistd.h>
+
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+static inline int memfd_create(const char *name, unsigned int flags)
+{
+ return syscall(__NR_memfd_create, name, flags);
+}
+#else /* !LINUX */
+static inline int memfd_create(const char *name, unsigned int flags)
+{
+ return -1;
+}
+#endif
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 04/21] util: add memfd helpers
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (2 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 03/21] util: add linux-only memfd fallback marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 05/21] vhost: alloc shareable log marcandre.lureau
` (18 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Add qemu_memfd_alloc/free() helpers.
The function helps to allocate and seal a memfd, and implements an
open/unlink/mmap fallback for system that do not support memfd.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qemu/memfd.h | 4 +++
util/memfd.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h
index 8b1fe6a..950fb88 100644
--- a/include/qemu/memfd.h
+++ b/include/qemu/memfd.h
@@ -17,4 +17,8 @@
#define F_SEAL_WRITE 0x0008 /* prevent writes */
#endif
+void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
+ int *fd);
+void qemu_memfd_free(void *ptr, size_t size, int fd);
+
#endif /* QEMU_MEMFD_H */
diff --git a/util/memfd.c b/util/memfd.c
index a98d57e..8b2b785 100644
--- a/util/memfd.c
+++ b/util/memfd.c
@@ -27,6 +27,14 @@
#include "config-host.h"
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
#include "qemu/memfd.h"
#ifdef CONFIG_MEMFD
@@ -44,13 +52,75 @@
#define MFD_ALLOW_SEALING 0x0002U
#endif
-static inline int memfd_create(const char *name, unsigned int flags)
+static int memfd_create(const char *name, unsigned int flags)
{
return syscall(__NR_memfd_create, name, flags);
}
#else /* !LINUX */
-static inline int memfd_create(const char *name, unsigned int flags)
+static int memfd_create(const char *name, unsigned int flags)
{
return -1;
}
#endif
+
+void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
+ int *fd)
+{
+ void *ptr;
+ int mfd;
+
+ mfd = memfd_create(name, MFD_ALLOW_SEALING|MFD_CLOEXEC);
+ if (mfd != -1) {
+ if (ftruncate(mfd, size) == -1) {
+ perror("ftruncate");
+ close(mfd);
+ return NULL;
+ }
+
+ if (fcntl(mfd, F_ADD_SEALS, seals) == -1) {
+ perror("fcntl");
+ close(mfd);
+ return NULL;
+ }
+ } else {
+ const char *tmpdir = getenv("TMPDIR");
+ gchar *fname;
+
+ tmpdir = tmpdir ? tmpdir : "/tmp";
+
+ fname = g_strdup_printf("%s/memfd-XXXXXX", tmpdir);
+ mfd = mkstemp(fname);
+ unlink(fname);
+ g_free(fname);
+
+ if (mfd == -1) {
+ perror("mkstemp");
+ return NULL;
+ }
+
+ if (ftruncate(mfd, size) == -1) {
+ perror("ftruncate");
+ close(mfd);
+ return NULL;
+ }
+ }
+
+ ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, mfd, 0);
+ if (ptr == MAP_FAILED) {
+ perror("mmap");
+ close(mfd);
+ return NULL;
+ }
+
+ *fd = mfd;
+ return ptr;
+}
+
+void qemu_memfd_free(void *ptr, size_t size, int fd)
+{
+ if (ptr) {
+ munmap(ptr, size);
+ }
+
+ close(fd);
+}
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 05/21] vhost: alloc shareable log
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (3 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 04/21] util: add memfd helpers marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 06/21] vhost: document log resizing marcandre.lureau
` (17 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
If the backend is of type VHOST_BACKEND_TYPE_USER, allocate
shareable memory. Next patch will only allocate when the backend
has the required feature.
vhost_log_get() now uses 2 globals "vhost_log" and "vhost_log_shm", that
way there is a common non-shareable log and a common shareable one.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/virtio/vhost.c | 49 ++++++++++++++++++++++++++++++++++++++---------
include/hw/virtio/vhost.h | 3 ++-
2 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index c0ed5b2..bf88618 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -18,6 +18,7 @@
#include "qemu/atomic.h"
#include "qemu/range.h"
#include "qemu/error-report.h"
+#include "qemu/memfd.h"
#include <linux/vhost.h>
#include "exec/address-spaces.h"
#include "hw/virtio/virtio-bus.h"
@@ -25,6 +26,7 @@
#include "migration/migration.h"
static struct vhost_log *vhost_log;
+static struct vhost_log *vhost_log_shm;
static void vhost_dev_sync_region(struct vhost_dev *dev,
MemoryRegionSection *section,
@@ -286,25 +288,45 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
}
return log_size;
}
-static struct vhost_log *vhost_log_alloc(uint64_t size)
+
+static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
{
- struct vhost_log *log = g_malloc0(sizeof *log + size * sizeof(*(log->log)));
+ struct vhost_log *log;
+ uint64_t logsize = size * sizeof(*(log->log));
+ int fd = -1;
+
+ log = g_new0(struct vhost_log, 1);
+ if (share) {
+ log->log = qemu_memfd_alloc("vhost-log", logsize,
+ F_SEAL_GROW|F_SEAL_SHRINK|F_SEAL_SEAL, &fd);
+ memset(log->log, 0, logsize);
+ } else {
+ log->log = g_malloc0(logsize);
+ }
log->size = size;
log->refcnt = 1;
+ log->fd = fd;
return log;
}
-static struct vhost_log *vhost_log_get(uint64_t size)
+static struct vhost_log *vhost_log_get(uint64_t size, bool share)
{
- if (!vhost_log || vhost_log->size != size) {
- vhost_log = vhost_log_alloc(size);
+ struct vhost_log *log = share ? vhost_log_shm : vhost_log;
+
+ if (!log || log->size != size) {
+ log = vhost_log_alloc(size, share);
+ if (share) {
+ vhost_log_shm = log;
+ } else {
+ vhost_log = log;
+ }
} else {
- ++vhost_log->refcnt;
+ ++log->refcnt;
}
- return vhost_log;
+ return log;
}
static void vhost_log_put(struct vhost_dev *dev, bool sync)
@@ -321,16 +343,24 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
if (dev->log_size && sync) {
vhost_log_sync_range(dev, 0, dev->log_size * VHOST_LOG_CHUNK - 1);
}
+
if (vhost_log == log) {
+ g_free(log->log);
vhost_log = NULL;
+ } else if (vhost_log_shm == log) {
+ qemu_memfd_free(log->log, log->size * sizeof(*(log->log)),
+ log->fd);
+ vhost_log_shm = NULL;
}
+
g_free(log);
}
}
static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
{
- struct vhost_log *log = vhost_log_get(size);
+ bool share = dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
+ struct vhost_log *log = vhost_log_get(size, share);
uint64_t log_base = (uintptr_t)log->log;
int r;
@@ -1134,9 +1164,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
if (hdev->log_enabled) {
uint64_t log_base;
+ bool share = hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
hdev->log_size = vhost_get_log_size(hdev);
- hdev->log = vhost_log_get(hdev->log_size);
+ hdev->log = vhost_log_get(hdev->log_size, share);
log_base = (uintptr_t)hdev->log->log;
r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_LOG_BASE,
hdev->log_size ? &log_base : NULL);
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index c3758f3..7e7dc45 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -31,7 +31,8 @@ typedef unsigned long vhost_log_chunk_t;
struct vhost_log {
unsigned long long size;
int refcnt;
- vhost_log_chunk_t log[0];
+ int fd;
+ vhost_log_chunk_t *log;
};
struct vhost_memory;
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 06/21] vhost: document log resizing
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (4 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 05/21] vhost: alloc shareable log marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 07/21] vhost: add vhost_set_log_base op marcandre.lureau
` (16 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/virtio/vhost.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index bf88618..7bc3862 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -364,6 +364,8 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
uint64_t log_base = (uintptr_t)log->log;
int r;
+ /* inform backend of log switching, this must be done before
+ releasing the current log, to ensure no logging is lost */
r = dev->vhost_ops->vhost_call(dev, VHOST_SET_LOG_BASE, &log_base);
assert(r >= 0);
vhost_log_put(dev, true);
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 07/21] vhost: add vhost_set_log_base op
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (5 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 06/21] vhost: document log resizing marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 08/21] vhost-user: send log shm fd along with log_base marcandre.lureau
` (15 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Split VHOST_SET_LOG_BASE call in a seperate function callback, so that
type safety works and more arguments can be added in the next patches.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/virtio/vhost-backend.c | 8 ++++++++
hw/virtio/vhost-user.c | 17 ++++++++++++++++-
hw/virtio/vhost.c | 6 +++---
include/hw/virtio/vhost-backend.h | 5 +++++
4 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 72d1392..88d33fd 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -11,6 +11,7 @@
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-backend.h"
#include "qemu/error-report.h"
+#include "linux/vhost.h"
#include <sys/ioctl.h>
@@ -49,12 +50,19 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
return idx - dev->vq_index;
}
+static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
+{
+ return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
+}
+
static const VhostOps kernel_ops = {
.backend_type = VHOST_BACKEND_TYPE_KERNEL,
.vhost_call = vhost_kernel_call,
.vhost_backend_init = vhost_kernel_init,
.vhost_backend_cleanup = vhost_kernel_cleanup,
.vhost_backend_get_vq_index = vhost_kernel_get_vq_index,
+
+ .vhost_set_log_base = vhost_set_log_base,
};
int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index b11c0d2..fd4fcbf 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -242,7 +242,6 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
break;
case VHOST_USER_SET_FEATURES:
- case VHOST_USER_SET_LOG_BASE:
case VHOST_USER_SET_PROTOCOL_FEATURES:
msg.u64 = *((__u64 *) arg);
msg.size = sizeof(m.u64);
@@ -367,6 +366,20 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
return 0;
}
+static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_LOG_BASE,
+ .flags = VHOST_USER_VERSION,
+ .u64 = base,
+ .size = sizeof(m.u64),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
static int vhost_user_init(struct vhost_dev *dev, void *opaque)
{
unsigned long long features;
@@ -447,4 +460,6 @@ const VhostOps user_ops = {
.vhost_backend_cleanup = vhost_user_cleanup,
.vhost_backend_get_vq_index = vhost_user_get_vq_index,
.vhost_backend_set_vring_enable = vhost_user_set_vring_enable,
+
+ .vhost_set_log_base = vhost_set_log_base,
};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 7bc3862..7f01cd6 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -366,7 +366,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
/* inform backend of log switching, this must be done before
releasing the current log, to ensure no logging is lost */
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_LOG_BASE, &log_base);
+ r = dev->vhost_ops->vhost_set_log_base(dev, log_base);
assert(r >= 0);
vhost_log_put(dev, true);
dev->log = log;
@@ -1171,8 +1171,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
hdev->log_size = vhost_get_log_size(hdev);
hdev->log = vhost_log_get(hdev->log_size, share);
log_base = (uintptr_t)hdev->log->log;
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_LOG_BASE,
- hdev->log_size ? &log_base : NULL);
+ r = hdev->vhost_ops->vhost_set_log_base(hdev,
+ hdev->log_size ? log_base : 0);
if (r < 0) {
r = -errno;
goto fail_log;
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 3a0f6e2..c6b688a 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -27,13 +27,18 @@ typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
typedef int (*vhost_backend_get_vq_index)(struct vhost_dev *dev, int idx);
typedef int (*vhost_backend_set_vring_enable)(struct vhost_dev *dev, int enable);
+typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base);
+
typedef struct VhostOps {
VhostBackendType backend_type;
vhost_call vhost_call;
+
vhost_backend_init vhost_backend_init;
vhost_backend_cleanup vhost_backend_cleanup;
vhost_backend_get_vq_index vhost_backend_get_vq_index;
vhost_backend_set_vring_enable vhost_backend_set_vring_enable;
+
+ vhost_set_log_base_op vhost_set_log_base;
} VhostOps;
extern const VhostOps user_ops;
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 08/21] vhost-user: send log shm fd along with log_base
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (6 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 07/21] vhost: add vhost_set_log_base op marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 09/21] vhost-user: add a migration blocker marcandre.lureau
` (14 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Send the shm for the dirty pages logging if the backend supports
VHOST_USER_PROTOCOL_F_LOG_SHMFD. Wait for a reply to make sure
the old log is no longer used.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/virtio/vhost-backend.c | 3 ++-
hw/virtio/vhost-user.c | 32 ++++++++++++++++++++++++++++----
hw/virtio/vhost.c | 5 +++--
include/hw/virtio/vhost-backend.h | 4 +++-
4 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 88d33fd..87ab028 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -50,7 +50,8 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
return idx - dev->vq_index;
}
-static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
+static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log)
{
return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
}
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index fd4fcbf..6420efd 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -25,9 +25,10 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
-#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x1ULL
-#define VHOST_USER_PROTOCOL_F_MQ 0
+#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
+#define VHOST_USER_PROTOCOL_F_MQ 0
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
@@ -366,8 +367,13 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
return 0;
}
-static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
+static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log)
{
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ size_t fd_num = 0;
+ bool shmfd = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD);
VhostUserMsg msg = {
.request = VHOST_USER_SET_LOG_BASE,
.flags = VHOST_USER_VERSION,
@@ -375,7 +381,25 @@ static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base)
.size = sizeof(m.u64),
};
- vhost_user_write(dev, &msg, NULL, 0);
+ if (shmfd && log->fd != -1) {
+ fds[fd_num++] = log->fd;
+ }
+
+ vhost_user_write(dev, &msg, fds, fd_num);
+
+ if (shmfd) {
+ msg.size = 0;
+ if (vhost_user_read(dev, &msg) < 0) {
+ return 0;
+ }
+
+ if (msg.request != VHOST_USER_SET_LOG_BASE) {
+ error_report("Received unexpected msg type. "
+ "Expected %d received %d",
+ VHOST_USER_SET_LOG_BASE, msg.request);
+ return -1;
+ }
+ }
return 0;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 7f01cd6..9b73f83 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -366,7 +366,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
/* inform backend of log switching, this must be done before
releasing the current log, to ensure no logging is lost */
- r = dev->vhost_ops->vhost_set_log_base(dev, log_base);
+ r = dev->vhost_ops->vhost_set_log_base(dev, log_base, log);
assert(r >= 0);
vhost_log_put(dev, true);
dev->log = log;
@@ -1172,7 +1172,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
hdev->log = vhost_log_get(hdev->log_size, share);
log_base = (uintptr_t)hdev->log->log;
r = hdev->vhost_ops->vhost_set_log_base(hdev,
- hdev->log_size ? log_base : 0);
+ hdev->log_size ? log_base : 0,
+ hdev->log);
if (r < 0) {
r = -errno;
goto fail_log;
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index c6b688a..485279b 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -19,6 +19,7 @@ typedef enum VhostBackendType {
} VhostBackendType;
struct vhost_dev;
+struct vhost_log;
typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request,
void *arg);
@@ -27,7 +28,8 @@ typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
typedef int (*vhost_backend_get_vq_index)(struct vhost_dev *dev, int idx);
typedef int (*vhost_backend_set_vring_enable)(struct vhost_dev *dev, int enable);
-typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base);
+typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log);
typedef struct VhostOps {
VhostBackendType backend_type;
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 09/21] vhost-user: add a migration blocker
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (7 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 08/21] vhost-user: send log shm fd along with log_base marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 10/21] vhost: use a function for each call marcandre.lureau
` (13 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
If VHOST_USER_PROTOCOL_F_LOG_SHMFD is not announced, block vhost-user
migration.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/virtio/vhost-user.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 6420efd..ff87e87 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -15,6 +15,7 @@
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "exec/ram_addr.h"
+#include "migration/migration.h"
#include <fcntl.h>
#include <unistd.h>
@@ -442,6 +443,14 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
}
}
+ if (!virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD)) {
+ migrate_add_blocker(dev->migration_blocker);
+ error_setg(&dev->migration_blocker,
+ "Migration disabled: vhost-user backend lacks "
+ "VHOST_USER_PROTOCOL_F_LOG_SHMFD feature.");
+ }
+
return 0;
}
@@ -466,6 +475,10 @@ static int vhost_user_cleanup(struct vhost_dev *dev)
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
dev->opaque = 0;
+ if (dev->migration_blocker) {
+ migrate_del_blocker(dev->migration_blocker);
+ error_free(dev->migration_blocker);
+ }
return 0;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 10/21] vhost: use a function for each call
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (8 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 09/21] vhost-user: add a migration blocker marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend marcandre.lureau
` (12 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace the generic vhost_call() by specific functions for each
function call to help with type safety and changing arguments.
While doing this, I found that "unsigned long long" and "uint64_t" were
used interchangeably and causing compilation warnings, using uint64_t
instead, as the vhost & protocol specifies.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/net/vhost_net.c | 16 +-
hw/scsi/vhost-scsi.c | 7 +-
hw/virtio/vhost-backend.c | 124 ++++++++-
hw/virtio/vhost-user.c | 518 ++++++++++++++++++++++----------------
hw/virtio/vhost.c | 36 +--
include/hw/virtio/vhost-backend.h | 63 ++++-
include/hw/virtio/vhost.h | 12 +-
7 files changed, 501 insertions(+), 275 deletions(-)
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 2bce891..1ab4133 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -252,8 +252,7 @@ static int vhost_net_start_one(struct vhost_net *net,
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);
+ r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
if (r < 0) {
r = -errno;
goto fail;
@@ -266,8 +265,7 @@ fail:
if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
while (file.index-- > 0) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND,
- &file);
+ int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
assert(r >= 0);
}
}
@@ -289,15 +287,13 @@ static void vhost_net_stop_one(struct vhost_net *net,
if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND,
- &file);
+ int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
assert(r >= 0);
}
} else if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_DEVICE,
- NULL);
+ int r = vhost_ops->vhost_reset_device(&net->dev);
assert(r >= 0);
}
}
@@ -428,8 +424,8 @@ int vhost_set_vring_enable(NetClientState *nc, int enable)
VHostNetState *net = get_vhost_net(nc);
const VhostOps *vhost_ops = net->dev.vhost_ops;
- if (vhost_ops->vhost_backend_set_vring_enable) {
- return vhost_ops->vhost_backend_set_vring_enable(&net->dev, enable);
+ if (vhost_ops->vhost_set_vring_enable) {
+ return vhost_ops->vhost_set_vring_enable(&net->dev, enable);
}
return 0;
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index bac9ddb..a0034ab 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -45,7 +45,7 @@ static int vhost_scsi_set_endpoint(VHostSCSI *s)
memset(&backend, 0, sizeof(backend));
pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
- ret = vhost_ops->vhost_call(&s->dev, VHOST_SCSI_SET_ENDPOINT, &backend);
+ ret = vhost_ops->vhost_scsi_set_endpoint(&s->dev, &backend);
if (ret < 0) {
return -errno;
}
@@ -60,7 +60,7 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s)
memset(&backend, 0, sizeof(backend));
pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
- vhost_ops->vhost_call(&s->dev, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
+ vhost_ops->vhost_scsi_clear_endpoint(&s->dev, &backend);
}
static int vhost_scsi_start(VHostSCSI *s)
@@ -76,8 +76,7 @@ static int vhost_scsi_start(VHostSCSI *s)
return -ENOSYS;
}
- ret = vhost_ops->vhost_call(&s->dev,
- VHOST_SCSI_GET_ABI_VERSION, &abi_version);
+ ret = vhost_ops->vhost_scsi_get_abi_version(&s->dev, &abi_version);
if (ret < 0) {
return -errno;
}
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 87ab028..3820af4 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -43,27 +43,135 @@ static int vhost_kernel_cleanup(struct vhost_dev *dev)
return close(fd);
}
-static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
+static int vhost_kernel_net_set_backend(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
{
- assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
+ return vhost_kernel_call(dev, VHOST_NET_SET_BACKEND, file);
+}
- return idx - dev->vq_index;
+static int vhost_kernel_scsi_set_endpoint(struct vhost_dev *dev,
+ struct vhost_scsi_target *target)
+{
+ return vhost_kernel_call(dev, VHOST_SCSI_SET_ENDPOINT, target);
+}
+
+static int vhost_kernel_scsi_clear_endpoint(struct vhost_dev *dev,
+ struct vhost_scsi_target *target)
+{
+ return vhost_kernel_call(dev, VHOST_SCSI_CLEAR_ENDPOINT, target);
+}
+
+static int vhost_kernel_scsi_get_abi_version(struct vhost_dev *dev, int *version)
+{
+ return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version);
}
-static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base,
- struct vhost_log *log)
+static int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log)
{
return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
}
+static int vhost_kernel_set_mem_table(struct vhost_dev *dev,
+ struct vhost_memory *mem)
+{
+ return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem);
+}
+
+static int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr);
+}
+
+static int vhost_kernel_set_vring_endian(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring);
+}
+
+static int vhost_kernel_set_vring_num(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring);
+}
+
+static int vhost_kernel_set_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring);
+}
+
+static int vhost_kernel_get_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring);
+}
+
+static int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file);
+}
+
+static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
+}
+
+static int vhost_kernel_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features);
+}
+
+static int vhost_kernel_get_features(struct vhost_dev *dev,
+ uint64_t *features)
+{
+ return vhost_kernel_call(dev, VHOST_GET_FEATURES, features);
+}
+
+static int vhost_kernel_set_owner(struct vhost_dev *dev)
+{
+ return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
+}
+
+static int vhost_kernel_reset_device(struct vhost_dev *dev)
+{
+ return vhost_kernel_call(dev, VHOST_RESET_DEVICE, NULL);
+}
+
+static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
+{
+ assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
+
+ return idx - dev->vq_index;
+}
+
static const VhostOps kernel_ops = {
.backend_type = VHOST_BACKEND_TYPE_KERNEL,
- .vhost_call = vhost_kernel_call,
.vhost_backend_init = vhost_kernel_init,
.vhost_backend_cleanup = vhost_kernel_cleanup,
- .vhost_backend_get_vq_index = vhost_kernel_get_vq_index,
- .vhost_set_log_base = vhost_set_log_base,
+ .vhost_net_set_backend = vhost_kernel_net_set_backend,
+ .vhost_scsi_set_endpoint = vhost_kernel_scsi_set_endpoint,
+ .vhost_scsi_clear_endpoint = vhost_kernel_scsi_clear_endpoint,
+ .vhost_scsi_get_abi_version = vhost_kernel_scsi_get_abi_version,
+ .vhost_set_log_base = vhost_kernel_set_log_base,
+ .vhost_set_mem_table = vhost_kernel_set_mem_table,
+ .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
+ .vhost_set_vring_endian = vhost_kernel_set_vring_endian,
+ .vhost_set_vring_num = vhost_kernel_set_vring_num,
+ .vhost_set_vring_base = vhost_kernel_set_vring_base,
+ .vhost_get_vring_base = vhost_kernel_get_vring_base,
+ .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
+ .vhost_set_vring_call = vhost_kernel_set_vring_call,
+ .vhost_set_features = vhost_kernel_set_features,
+ .vhost_get_features = vhost_kernel_get_features,
+ .vhost_set_owner = vhost_kernel_set_owner,
+ .vhost_reset_device = vhost_kernel_reset_device,
+ .vhost_get_vq_index = vhost_kernel_get_vq_index,
};
int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ff87e87..41e0364 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -99,37 +99,6 @@ static bool ioeventfd_enabled(void)
return kvm_enabled() && kvm_eventfds_enabled();
}
-static unsigned long int ioctl_to_vhost_user_request[VHOST_USER_MAX] = {
- -1, /* VHOST_USER_NONE */
- VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */
- VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */
- VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */
- VHOST_RESET_DEVICE, /* VHOST_USER_RESET_DEVICE */
- VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */
- VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */
- VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */
- VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */
- VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */
- VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */
- VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */
- VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */
- VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */
- VHOST_SET_VRING_ERR /* VHOST_USER_SET_VRING_ERR */
-};
-
-static VhostUserRequest vhost_user_request_translate(unsigned long int request)
-{
- VhostUserRequest idx;
-
- for (idx = 0; idx < VHOST_USER_MAX; idx++) {
- if (ioctl_to_vhost_user_request[idx] == request) {
- break;
- }
- }
-
- return (idx == VHOST_USER_MAX) ? VHOST_USER_NONE : idx;
-}
-
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{
CharDriverState *chr = dev->opaque;
@@ -176,12 +145,35 @@ fail:
return -1;
}
+static bool vhost_user_one_time_request(VhostUserRequest request)
+{
+ switch (request) {
+ case VHOST_USER_SET_OWNER:
+ case VHOST_USER_RESET_DEVICE:
+ case VHOST_USER_SET_MEM_TABLE:
+ case VHOST_USER_GET_QUEUE_NUM:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* most non-init callers ignore the error */
static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
int *fds, int fd_num)
{
CharDriverState *chr = dev->opaque;
int size = VHOST_USER_HDR_SIZE + msg->size;
+ /*
+ * For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
+ * we just need send it once in the first time. For later such
+ * request, we just ignore it.
+ */
+ if (vhost_user_one_time_request(msg->request) && dev->vq_index != 0) {
+ return 0;
+ }
+
if (fd_num) {
qemu_chr_fe_set_msgfds(chr, fds, fd_num);
}
@@ -190,231 +182,317 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
0 : -1;
}
-static bool vhost_user_one_time_request(VhostUserRequest request)
+static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log)
{
- switch (request) {
- case VHOST_USER_SET_OWNER:
- case VHOST_USER_RESET_DEVICE:
- case VHOST_USER_SET_MEM_TABLE:
- case VHOST_USER_GET_QUEUE_NUM:
- return true;
- default:
- return false;
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ size_t fd_num = 0;
+ bool shmfd = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD);
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_LOG_BASE,
+ .flags = VHOST_USER_VERSION,
+ .u64 = base,
+ .size = sizeof(m.u64),
+ };
+
+ if (shmfd && log->fd != -1) {
+ fds[fd_num++] = log->fd;
}
+
+ vhost_user_write(dev, &msg, fds, fd_num);
+
+ if (shmfd) {
+ msg.size = 0;
+ if (vhost_user_read(dev, &msg) < 0) {
+ return 0;
+ }
+
+ if (msg.request != VHOST_USER_SET_LOG_BASE) {
+ error_report("Received unexpected msg type. "
+ "Expected %d received %d",
+ VHOST_USER_SET_LOG_BASE, msg.request);
+ return -1;
+ }
+ }
+
+ return 0;
}
-static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
- void *arg)
+static int vhost_user_set_mem_table(struct vhost_dev *dev,
+ struct vhost_memory *mem)
{
- VhostUserMsg msg;
- VhostUserRequest msg_request;
- struct vhost_vring_file *file = 0;
- int need_reply = 0;
int fds[VHOST_MEMORY_MAX_NREGIONS];
int i, fd;
size_t fd_num = 0;
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_MEM_TABLE,
+ .flags = VHOST_USER_VERSION,
+ };
- assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-
- /* only translate vhost ioctl requests */
- if (request > VHOST_USER_MAX) {
- msg_request = vhost_user_request_translate(request);
- } else {
- msg_request = request;
+ for (i = 0; i < dev->mem->nregions; ++i) {
+ struct vhost_memory_region *reg = dev->mem->regions + i;
+ ram_addr_t ram_addr;
+
+ assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
+ qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
+ &ram_addr);
+ fd = qemu_get_ram_fd(ram_addr);
+ if (fd > 0) {
+ msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
+ msg.memory.regions[fd_num].memory_size = reg->memory_size;
+ msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
+ msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
+ (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
+ assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
+ fds[fd_num++] = fd;
+ }
}
- /*
- * For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
- * we just need send it once in the first time. For later such
- * request, we just ignore it.
- */
- if (vhost_user_one_time_request(msg_request) && dev->vq_index != 0) {
- return 0;
+ msg.memory.nregions = fd_num;
+
+ if (!fd_num) {
+ error_report("Failed initializing vhost-user memory map, "
+ "consider using -object memory-backend-file share=on");
+ return -1;
}
- msg.request = msg_request;
- msg.flags = VHOST_USER_VERSION;
- msg.size = 0;
+ msg.size = sizeof(m.memory.nregions);
+ msg.size += sizeof(m.memory.padding);
+ msg.size += fd_num * sizeof(VhostUserMemoryRegion);
- switch (msg_request) {
- case VHOST_USER_GET_FEATURES:
- case VHOST_USER_GET_PROTOCOL_FEATURES:
- case VHOST_USER_GET_QUEUE_NUM:
- need_reply = 1;
- break;
+ vhost_user_write(dev, &msg, fds, fd_num);
- case VHOST_USER_SET_FEATURES:
- case VHOST_USER_SET_PROTOCOL_FEATURES:
- msg.u64 = *((__u64 *) arg);
- msg.size = sizeof(m.u64);
- break;
+ return 0;
+}
- case VHOST_USER_SET_OWNER:
- case VHOST_USER_RESET_DEVICE:
- break;
+static int vhost_user_set_vring_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_VRING_ADDR,
+ .flags = VHOST_USER_VERSION,
+ .addr = *addr,
+ .size = sizeof(*addr),
+ };
- case VHOST_USER_SET_MEM_TABLE:
- for (i = 0; i < dev->mem->nregions; ++i) {
- struct vhost_memory_region *reg = dev->mem->regions + i;
- ram_addr_t ram_addr;
-
- assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
- qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr, &ram_addr);
- fd = qemu_get_ram_fd(ram_addr);
- if (fd > 0) {
- msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
- msg.memory.regions[fd_num].memory_size = reg->memory_size;
- msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
- msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
- (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
- assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
- fds[fd_num++] = fd;
- }
- }
+ vhost_user_write(dev, &msg, NULL, 0);
- msg.memory.nregions = fd_num;
+ return 0;
+}
- if (!fd_num) {
- error_report("Failed initializing vhost-user memory map, "
- "consider using -object memory-backend-file share=on");
- return -1;
- }
+static int vhost_user_set_vring_endian(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ error_report("vhost-user trying to send unhandled ioctl");
+ return -1;
+}
- msg.size = sizeof(m.memory.nregions);
- msg.size += sizeof(m.memory.padding);
- msg.size += fd_num * sizeof(VhostUserMemoryRegion);
-
- break;
-
- case VHOST_USER_SET_LOG_FD:
- fds[fd_num++] = *((int *) arg);
- break;
-
- case VHOST_USER_SET_VRING_NUM:
- case VHOST_USER_SET_VRING_BASE:
- case VHOST_USER_SET_VRING_ENABLE:
- memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
- msg.size = sizeof(m.state);
- break;
-
- case VHOST_USER_GET_VRING_BASE:
- memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
- msg.size = sizeof(m.state);
- need_reply = 1;
- break;
-
- case VHOST_USER_SET_VRING_ADDR:
- memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr));
- msg.size = sizeof(m.addr);
- break;
-
- case VHOST_USER_SET_VRING_KICK:
- case VHOST_USER_SET_VRING_CALL:
- case VHOST_USER_SET_VRING_ERR:
- file = arg;
- msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
- msg.size = sizeof(m.u64);
- if (ioeventfd_enabled() && file->fd > 0) {
- fds[fd_num++] = file->fd;
- } else {
- msg.u64 |= VHOST_USER_VRING_NOFD_MASK;
- }
- break;
- default:
- error_report("vhost-user trying to send unhandled ioctl");
+static int vhost_set_vring(struct vhost_dev *dev,
+ unsigned long int request,
+ struct vhost_vring_state *ring)
+{
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ .state = *ring,
+ .size = sizeof(*ring),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
+static int vhost_user_set_vring_num(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_set_vring(dev, VHOST_SET_VRING_NUM, ring);
+}
+
+static int vhost_user_set_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_set_vring(dev, VHOST_SET_VRING_BASE, ring);
+}
+
+static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
+{
+ struct vhost_vring_state state = {
+ .index = dev->vq_index,
+ .num = enable,
+ };
+
+ if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ))) {
return -1;
- break;
}
- if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
+ return vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state);
+}
+
+
+static int vhost_user_get_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_GET_VRING_BASE,
+ .flags = VHOST_USER_VERSION,
+ .state = *ring,
+ .size = sizeof(*ring),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ if (vhost_user_read(dev, &msg) < 0) {
return 0;
}
- if (need_reply) {
- if (vhost_user_read(dev, &msg) < 0) {
- return 0;
- }
-
- if (msg_request != msg.request) {
- error_report("Received unexpected msg type."
- " Expected %d received %d", msg_request, msg.request);
- return -1;
- }
+ if (msg.request != VHOST_USER_GET_VRING_BASE) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ VHOST_USER_GET_VRING_BASE, msg.request);
+ return -1;
+ }
- switch (msg_request) {
- case VHOST_USER_GET_FEATURES:
- case VHOST_USER_GET_PROTOCOL_FEATURES:
- case VHOST_USER_GET_QUEUE_NUM:
- if (msg.size != sizeof(m.u64)) {
- error_report("Received bad msg size.");
- return -1;
- }
- *((__u64 *) arg) = msg.u64;
- break;
- case VHOST_USER_GET_VRING_BASE:
- if (msg.size != sizeof(m.state)) {
- error_report("Received bad msg size.");
- return -1;
- }
- memcpy(arg, &msg.state, sizeof(struct vhost_vring_state));
- break;
- default:
- error_report("Received unexpected msg type.");
- return -1;
- break;
- }
+ if (msg.size != sizeof(m.state)) {
+ error_report("Received bad msg size.");
+ return -1;
}
+ *ring = msg.state;
+
return 0;
}
-static int vhost_set_log_base(struct vhost_dev *dev, uint64_t base,
- struct vhost_log *log)
+static int vhost_set_vring_file(struct vhost_dev *dev,
+ VhostUserRequest request,
+ struct vhost_vring_file *file)
{
int fds[VHOST_MEMORY_MAX_NREGIONS];
size_t fd_num = 0;
- bool shmfd = virtio_has_feature(dev->protocol_features,
- VHOST_USER_PROTOCOL_F_LOG_SHMFD);
VhostUserMsg msg = {
- .request = VHOST_USER_SET_LOG_BASE,
+ .request = request,
.flags = VHOST_USER_VERSION,
- .u64 = base,
+ .u64 = file->index & VHOST_USER_VRING_IDX_MASK,
.size = sizeof(m.u64),
};
- if (shmfd && log->fd != -1) {
- fds[fd_num++] = log->fd;
+ if (ioeventfd_enabled() && file->fd > 0) {
+ fds[fd_num++] = file->fd;
+ } else {
+ msg.u64 |= VHOST_USER_VRING_NOFD_MASK;
}
vhost_user_write(dev, &msg, fds, fd_num);
- if (shmfd) {
- msg.size = 0;
- if (vhost_user_read(dev, &msg) < 0) {
- return 0;
- }
+ return 0;
+}
- if (msg.request != VHOST_USER_SET_LOG_BASE) {
- error_report("Received unexpected msg type. "
- "Expected %d received %d",
- VHOST_USER_SET_LOG_BASE, msg.request);
- return -1;
- }
+static int vhost_user_set_vring_kick(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
+}
+
+static int vhost_user_set_vring_call(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
+}
+
+static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
+{
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ .u64 = u64,
+ .size = sizeof(m.u64),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
+static int vhost_user_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features);
+}
+
+static int vhost_user_set_protocol_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features);
+}
+
+static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
+{
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ if (vhost_user_read(dev, &msg) < 0) {
+ return 0;
+ }
+
+ if (msg.request != request) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ request, msg.request);
+ return -1;
+ }
+
+ if (msg.size != sizeof(m.u64)) {
+ error_report("Received bad msg size.");
+ return -1;
}
+ *u64 = msg.u64;
+
+ return 0;
+}
+
+static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
+{
+ return vhost_user_get_u64(dev, VHOST_USER_GET_FEATURES, features);
+}
+
+static int vhost_user_set_owner(struct vhost_dev *dev)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_OWNER,
+ .flags = VHOST_USER_VERSION,
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
+static int vhost_user_reset_device(struct vhost_dev *dev)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_RESET_DEVICE,
+ .flags = VHOST_USER_VERSION,
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
return 0;
}
static int vhost_user_init(struct vhost_dev *dev, void *opaque)
{
- unsigned long long features;
+ uint64_t features;
int err;
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
dev->opaque = opaque;
- err = vhost_user_call(dev, VHOST_USER_GET_FEATURES, &features);
+ err = vhost_user_get_features(dev, &features);
if (err < 0) {
return err;
}
@@ -422,21 +500,22 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
if (virtio_has_feature(features, VHOST_USER_F_PROTOCOL_FEATURES)) {
dev->backend_features |= 1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
- err = vhost_user_call(dev, VHOST_USER_GET_PROTOCOL_FEATURES, &features);
+ err = vhost_user_get_u64(dev, VHOST_USER_GET_PROTOCOL_FEATURES,
+ &features);
if (err < 0) {
return err;
}
dev->protocol_features = features & VHOST_USER_PROTOCOL_FEATURE_MASK;
- err = vhost_user_call(dev, VHOST_USER_SET_PROTOCOL_FEATURES,
- &dev->protocol_features);
+ err = vhost_user_set_protocol_features(dev, dev->protocol_features);
if (err < 0) {
return err;
}
/* query the max queues we support if backend supports Multiple Queue */
if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)) {
- err = vhost_user_call(dev, VHOST_USER_GET_QUEUE_NUM, &dev->max_queues);
+ err = vhost_user_get_u64(dev, VHOST_USER_GET_QUEUE_NUM,
+ &dev->max_queues);
if (err < 0) {
return err;
}
@@ -454,22 +533,6 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
return 0;
}
-static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
-{
- struct vhost_vring_state state = {
- .index = dev->vq_index,
- .num = enable,
- };
-
- assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-
- if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ))) {
- return -1;
- }
-
- return vhost_user_call(dev, VHOST_USER_SET_VRING_ENABLE, &state);
-}
-
static int vhost_user_cleanup(struct vhost_dev *dev)
{
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
@@ -492,11 +555,22 @@ static int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
- .vhost_call = vhost_user_call,
.vhost_backend_init = vhost_user_init,
.vhost_backend_cleanup = vhost_user_cleanup,
- .vhost_backend_get_vq_index = vhost_user_get_vq_index,
- .vhost_backend_set_vring_enable = vhost_user_set_vring_enable,
- .vhost_set_log_base = vhost_set_log_base,
+ .vhost_set_log_base = vhost_user_set_log_base,
+ .vhost_set_mem_table = vhost_user_set_mem_table,
+ .vhost_set_vring_addr = vhost_user_set_vring_addr,
+ .vhost_set_vring_endian = vhost_user_set_vring_endian,
+ .vhost_set_vring_num = vhost_user_set_vring_num,
+ .vhost_set_vring_base = vhost_user_set_vring_base,
+ .vhost_get_vring_base = vhost_user_get_vring_base,
+ .vhost_set_vring_kick = vhost_user_set_vring_kick,
+ .vhost_set_vring_call = vhost_user_set_vring_call,
+ .vhost_set_features = vhost_user_set_features,
+ .vhost_get_features = vhost_user_get_features,
+ .vhost_set_owner = vhost_user_set_owner,
+ .vhost_reset_device = vhost_user_reset_device,
+ .vhost_get_vq_index = vhost_user_get_vq_index,
+ .vhost_set_vring_enable = vhost_user_set_vring_enable,
};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 9b73f83..d9f2131 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -532,7 +532,7 @@ static void vhost_commit(MemoryListener *listener)
}
if (!dev->log_enabled) {
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
+ r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
assert(r >= 0);
dev->memory_changed = false;
return;
@@ -545,7 +545,7 @@ static void vhost_commit(MemoryListener *listener)
if (dev->log_size < log_size) {
vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);
}
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
+ r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
assert(r >= 0);
/* To log less, can only decrease log size after table update. */
if (dev->log_size > log_size + VHOST_LOG_BUFFER) {
@@ -613,7 +613,7 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
.log_guest_addr = vq->used_phys,
.flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
};
- int r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr);
+ int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
if (r < 0) {
return -errno;
}
@@ -627,7 +627,7 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
if (enable_log) {
features |= 0x1ULL << VHOST_F_LOG_ALL;
}
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features);
+ r = dev->vhost_ops->vhost_set_features(dev, features);
return r < 0 ? -errno : 0;
}
@@ -732,7 +732,7 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
.num = is_big_endian
};
- if (!dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ENDIAN, &s)) {
+ if (!dev->vhost_ops->vhost_set_vring_endian(dev, &s)) {
return 0;
}
@@ -751,7 +751,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
{
hwaddr s, l, a;
int r;
- int vhost_vq_index = dev->vhost_ops->vhost_backend_get_vq_index(dev, idx);
+ int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx);
struct vhost_vring_file file = {
.index = vhost_vq_index
};
@@ -762,13 +762,13 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
vq->num = state.num = virtio_queue_get_num(vdev, idx);
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_NUM, &state);
+ r = dev->vhost_ops->vhost_set_vring_num(dev, &state);
if (r) {
return -errno;
}
state.num = virtio_queue_get_last_avail_idx(vdev, idx);
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_BASE, &state);
+ r = dev->vhost_ops->vhost_set_vring_base(dev, &state);
if (r) {
return -errno;
}
@@ -820,7 +820,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
}
file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_KICK, &file);
+ r = dev->vhost_ops->vhost_set_vring_kick(dev, &file);
if (r) {
r = -errno;
goto fail_kick;
@@ -853,13 +853,13 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
struct vhost_virtqueue *vq,
unsigned idx)
{
- int vhost_vq_index = dev->vhost_ops->vhost_backend_get_vq_index(dev, idx);
+ int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx);
struct vhost_vring_state state = {
.index = vhost_vq_index,
};
int r;
- r = dev->vhost_ops->vhost_call(dev, VHOST_GET_VRING_BASE, &state);
+ r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
if (r < 0) {
fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
fflush(stderr);
@@ -906,7 +906,7 @@ static void vhost_eventfd_del(MemoryListener *listener,
static int vhost_virtqueue_init(struct vhost_dev *dev,
struct vhost_virtqueue *vq, int n)
{
- int vhost_vq_index = dev->vhost_ops->vhost_backend_get_vq_index(dev, n);
+ int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, n);
struct vhost_vring_file file = {
.index = vhost_vq_index,
};
@@ -916,7 +916,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
}
file.fd = event_notifier_get_fd(&vq->masked_notifier);
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_CALL, &file);
+ r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
if (r) {
r = -errno;
goto fail_call;
@@ -948,12 +948,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
return -errno;
}
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_OWNER, NULL);
+ r = hdev->vhost_ops->vhost_set_owner(hdev);
if (r < 0) {
goto fail;
}
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features);
+ r = hdev->vhost_ops->vhost_get_features(hdev, &features);
if (r < 0) {
goto fail;
}
@@ -1106,8 +1106,8 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq));
}
- file.index = hdev->vhost_ops->vhost_backend_get_vq_index(hdev, n);
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_VRING_CALL, &file);
+ file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
+ r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
assert(r >= 0);
}
@@ -1149,7 +1149,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
if (r < 0) {
goto fail_features;
}
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_MEM_TABLE, hdev->mem);
+ r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
if (r < 0) {
r = -errno;
goto fail_mem;
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 485279b..868a78a 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -20,27 +20,76 @@ typedef enum VhostBackendType {
struct vhost_dev;
struct vhost_log;
+struct vhost_memory;
+struct vhost_vring_file;
+struct vhost_vring_state;
+struct vhost_vring_addr;
+struct vhost_scsi_target;
-typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request,
- void *arg);
typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
-typedef int (*vhost_backend_get_vq_index)(struct vhost_dev *dev, int idx);
-typedef int (*vhost_backend_set_vring_enable)(struct vhost_dev *dev, int enable);
+typedef int (*vhost_net_set_backend_op)(struct vhost_dev *dev,
+ struct vhost_vring_file *file);
+typedef int (*vhost_scsi_set_endpoint_op)(struct vhost_dev *dev,
+ struct vhost_scsi_target *target);
+typedef int (*vhost_scsi_clear_endpoint_op)(struct vhost_dev *dev,
+ struct vhost_scsi_target *target);
+typedef int (*vhost_scsi_get_abi_version_op)(struct vhost_dev *dev,
+ int *version);
typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base,
struct vhost_log *log);
+typedef int (*vhost_set_mem_table_op)(struct vhost_dev *dev,
+ struct vhost_memory *mem);
+typedef int (*vhost_set_vring_addr_op)(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr);
+typedef int (*vhost_set_vring_endian_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_set_vring_num_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_set_vring_base_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_get_vring_base_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev,
+ struct vhost_vring_file *file);
+typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev,
+ struct vhost_vring_file *file);
+typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
+ uint64_t features);
+typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
+ uint64_t *features);
+typedef int (*vhost_set_owner_op)(struct vhost_dev *dev);
+typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
+typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
+typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
+ int enable);
typedef struct VhostOps {
VhostBackendType backend_type;
- vhost_call vhost_call;
vhost_backend_init vhost_backend_init;
vhost_backend_cleanup vhost_backend_cleanup;
- vhost_backend_get_vq_index vhost_backend_get_vq_index;
- vhost_backend_set_vring_enable vhost_backend_set_vring_enable;
+ vhost_net_set_backend_op vhost_net_set_backend;
+ vhost_scsi_set_endpoint_op vhost_scsi_set_endpoint;
+ vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint;
+ vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version;
vhost_set_log_base_op vhost_set_log_base;
+ vhost_set_mem_table_op vhost_set_mem_table;
+ vhost_set_vring_addr_op vhost_set_vring_addr;
+ vhost_set_vring_endian_op vhost_set_vring_endian;
+ vhost_set_vring_num_op vhost_set_vring_num;
+ vhost_set_vring_base_op vhost_set_vring_base;
+ vhost_get_vring_base_op vhost_get_vring_base;
+ vhost_set_vring_kick_op vhost_set_vring_kick;
+ vhost_set_vring_call_op vhost_set_vring_call;
+ vhost_set_features_op vhost_set_features;
+ vhost_get_features_op vhost_get_features;
+ vhost_set_owner_op vhost_set_owner;
+ vhost_reset_device_op vhost_reset_device;
+ vhost_get_vq_index_op vhost_get_vq_index;
+ vhost_set_vring_enable_op vhost_set_vring_enable;
} VhostOps;
extern const VhostOps user_ops;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 7e7dc45..c8c42cc 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -45,14 +45,14 @@ struct vhost_dev {
int nvqs;
/* the first virtqueue which would be used by this vhost dev */
int vq_index;
- unsigned long long features;
- unsigned long long acked_features;
- unsigned long long backend_features;
- unsigned long long protocol_features;
- unsigned long long max_queues;
+ uint64_t features;
+ uint64_t acked_features;
+ uint64_t backend_features;
+ uint64_t protocol_features;
+ uint64_t max_queues;
bool started;
bool log_enabled;
- unsigned long long log_size;
+ uint64_t log_size;
Error *migration_blocker;
bool memory_changed;
hwaddr mem_changed_start_addr;
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (9 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 10/21] vhost: use a function for each call marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-29 14:59 ` Michael S. Tsirkin
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log marcandre.lureau
` (11 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Do not allocate a shared log if the backend doesn't support it.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/virtio/vhost-user.c | 9 +++++++++
hw/virtio/vhost.c | 15 ++++++++++-----
include/hw/virtio/vhost-backend.h | 4 ++++
3 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 41e0364..455caba 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -553,6 +553,14 @@ static int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
return idx;
}
+static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
+{
+ assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+
+ return virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD);
+}
+
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
.vhost_backend_init = vhost_user_init,
@@ -573,4 +581,5 @@ const VhostOps user_ops = {
.vhost_reset_device = vhost_user_reset_device,
.vhost_get_vq_index = vhost_user_get_vq_index,
.vhost_set_vring_enable = vhost_user_set_vring_enable,
+ .vhost_requires_shm_log = vhost_user_requires_shm_log,
};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index d9f2131..ec27c7b 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -357,10 +357,15 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
}
}
-static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
+static bool vhost_dev_log_is_shared(struct vhost_dev *dev)
{
- bool share = dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
- struct vhost_log *log = vhost_log_get(size, share);
+ return dev->vhost_ops->vhost_requires_shm_log &&
+ dev->vhost_ops->vhost_requires_shm_log(dev);
+}
+
+static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
+{
+ struct vhost_log *log = vhost_log_get(size, vhost_dev_log_is_shared(dev));
uint64_t log_base = (uintptr_t)log->log;
int r;
@@ -1166,10 +1171,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
if (hdev->log_enabled) {
uint64_t log_base;
- bool share = hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
hdev->log_size = vhost_get_log_size(hdev);
- hdev->log = vhost_log_get(hdev->log_size, share);
+ hdev->log = vhost_log_get(hdev->log_size,
+ vhost_dev_log_is_shared(hdev));
log_base = (uintptr_t)hdev->log->log;
r = hdev->vhost_ops->vhost_set_log_base(hdev,
hdev->log_size ? log_base : 0,
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 868a78a..e07118c 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -11,6 +11,8 @@
#ifndef VHOST_BACKEND_H_
#define VHOST_BACKEND_H_
+#include <stdbool.h>
+
typedef enum VhostBackendType {
VHOST_BACKEND_TYPE_NONE = 0,
VHOST_BACKEND_TYPE_KERNEL = 1,
@@ -64,6 +66,7 @@ typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
int enable);
+typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
typedef struct VhostOps {
VhostBackendType backend_type;
@@ -90,6 +93,7 @@ typedef struct VhostOps {
vhost_reset_device_op vhost_reset_device;
vhost_get_vq_index_op vhost_get_vq_index;
vhost_set_vring_enable_op vhost_set_vring_enable;
+ vhost_requires_shm_log_op vhost_requires_shm_log;
} VhostOps;
extern const VhostOps user_ops;
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (10 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:38 ` Eric Blake
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 13/21] net: add trace_vhost_user_event marcandre.lureau
` (10 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
docs/specs/vhost-user.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
index 4eadad1..e0292a0 100644
--- a/docs/specs/vhost-user.txt
+++ b/docs/specs/vhost-user.txt
@@ -115,11 +115,13 @@ the ones that do:
* VHOST_GET_FEATURES
* VHOST_GET_PROTOCOL_FEATURES
* VHOST_GET_VRING_BASE
+ * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
There are several messages that the master sends with file descriptors passed
in the ancillary data:
* VHOST_SET_MEM_TABLE
+ * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
* VHOST_SET_LOG_FD
* VHOST_SET_VRING_KICK
* VHOST_SET_VRING_CALL
@@ -140,8 +142,7 @@ Multiple queue support
Multiple queue is treated as a protocol extension, hence the slave has to
implement protocol features first. The multiple queues feature is supported
-only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set:
-#define VHOST_USER_PROTOCOL_F_MQ 0
+only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set.
The max number of queues the slave supports can be queried with message
VHOST_USER_GET_PROTOCOL_FEATURES. Master should stop when the number of
@@ -152,6 +153,48 @@ queue in the sent message to identify a specified queue. One queue pair
is enabled initially. More queues are enabled dynamically, by sending
message VHOST_USER_SET_VRING_ENABLE.
+Migration
+---------
+
+During live migration, the master may need to track the modifications
+the slave makes to the memory mapped regions. The client should mark
+the dirty pages in a log. Once it complies to this logging, it may
+declare the VHOST_F_LOG_ALL vhost feature.
+
+All the modifications to memory pointed by vring "descriptor" should
+be marked. Modifications to "used" vring should be marked if
+VHOST_VRING_F_LOG is part of ring's features.
+
+Dirty pages are of size:
+#define VHOST_LOG_PAGE 0x1000
+
+The log memory fd is provided in the ancillary data of
+VHOST_USER_SET_LOG_BASE message when the slave has
+VHOST_USER_PROTOCOL_F_LOG_SHMFD protocol feature.
+
+The size of the log may be computed by using all the known guest
+addresses. The log covers from address 0 to the maximum of guest
+regions. In pseudo-code, to mark page at "addr" as dirty:
+
+page = addr / VHOST_LOG_PAGE
+log[page / 8] |= 1 << page % 8
+
+Use atomic operations, as the log may be concurrently manipulated.
+
+VHOST_USER_SET_LOG_FD is an optional message with an eventfd in
+ancillary data, it may be used to inform the master that the log has
+been modified.
+
+Once the source has finished migration, VHOST_USER_RESET_OWNER message
+will be sent by the source. No further update must be done before the
+destination takes over with new regions & rings.
+
+Protocol features
+-----------------
+
+#define VHOST_USER_PROTOCOL_F_MQ 0
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+
Message types
-------------
@@ -236,6 +279,7 @@ Message types
Id: 6
Equivalent ioctl: VHOST_SET_LOG_BASE
Master payload: u64
+ Slave payload: N/A
Sets the logging base address.
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 13/21] net: add trace_vhost_user_event
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (11 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 14/21] vhost user: add support of live migration marcandre.lureau
` (9 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace error_report() and use tracing instead. It's not an error to get
a connection or a disconnection, so silence this and trace it instead.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
net/vhost-user.c | 4 ++--
trace-events | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 8f354eb..9b38431 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -15,6 +15,7 @@
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qmp-commands.h"
+#include "trace.h"
typedef struct VhostUserState {
NetClientState nc;
@@ -148,18 +149,17 @@ static void net_vhost_user_event(void *opaque, int event)
NET_CLIENT_OPTIONS_KIND_NIC,
MAX_QUEUE_NUM);
s = DO_UPCAST(VhostUserState, nc, ncs[0]);
+ trace_vhost_user_event(s->chr->label, event);
switch (event) {
case CHR_EVENT_OPENED:
if (vhost_user_start(queues, ncs) < 0) {
exit(1);
}
qmp_set_link(name, true, &err);
- error_report("chardev \"%s\" went up", s->chr->label);
break;
case CHR_EVENT_CLOSED:
qmp_set_link(name, true, &err);
vhost_user_stop(queues, ncs);
- error_report("chardev \"%s\" went down", s->chr->label);
break;
}
diff --git a/trace-events b/trace-events
index 25c53e0..0434705 100644
--- a/trace-events
+++ b/trace-events
@@ -1694,3 +1694,6 @@ qcrypto_tls_creds_x509_load_cert_list(void *creds, const char *file) "TLS creds
# crypto/tlssession.c
qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const char *aclname, int endpoint) "TLS session new session=%p creds=%p hostname=%s aclname=%s endpoint=%d"
+
+# net/vhost-user.c
+vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 14/21] vhost user: add support of live migration
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (12 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 13/21] net: add trace_vhost_user_event marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest marcandre.lureau
` (8 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel; +Cc: thibaut.collet, jasowang, mst, haifeng.lin, pbonzini
From: Thibaut Collet <thibaut.collet@6wind.com>
Some vhost user backends are able to support live migration.
To provide this service the following features must be added:
1. Add the VIRTIO_NET_F_GUEST_ANNOUNCE capability to vhost-net when netdev
backend is vhost-user.
2. Provide a nop receive callback to vhost-user.
This callback is called by:
* qemu_announce_self after a migration to send fake RARP to avoid network
outage for peers talking to the migrated guest.
- For guest with GUEST_ANNOUNCE capabilities, guest already sends GARP
when the bit VIRTIO_NET_S_ANNOUNCE is set.
=> These packets must be discarded.
- For guest without GUEST_ANNOUNCE capabilities, migration termination
is notified when the guest sends packets.
=> These packets can be discarded.
* virtio_net_tx_bh with a dummy boot to send fake bootp/dhcp request.
BIOS guest manages virtio driver to send 4 bootp/dhcp request in case of
dummy boot.
=> These packets must be discarded.
Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
---
hw/net/vhost_net.c | 2 ++
net/vhost-user.c | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 1ab4133..840f443 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -85,6 +85,8 @@ static const int user_feature_bits[] = {
VIRTIO_NET_F_CTRL_MAC_ADDR,
VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
+ VIRTIO_NET_F_GUEST_ANNOUNCE,
+
VIRTIO_NET_F_MQ,
VHOST_INVALID_FEATURE_BIT
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 9b38431..87917a5 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -103,6 +103,15 @@ err:
return -1;
}
+static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
+ size_t size)
+{
+ /* Discard the request that is received and managed by backend
+ * by an other way.
+ */
+ return size;
+}
+
static void vhost_user_cleanup(NetClientState *nc)
{
VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
@@ -132,6 +141,7 @@ static bool vhost_user_has_ufo(NetClientState *nc)
static NetClientInfo net_vhost_user_info = {
.type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
.size = sizeof(VhostUserState),
+ .receive = vhost_user_receive,
.cleanup = vhost_user_cleanup,
.has_vnet_hdr = vhost_user_has_vnet_hdr,
.has_ufo = vhost_user_has_ufo,
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (13 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 14/21] vhost user: add support of live migration marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 17:24 ` Thibaut Collet
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 16/21] vhost-user-test: move wait_for_fds() out marcandre.lureau
` (7 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Thibaut Collet <thibaut.collet@6wind.com>
A new vhost user message is added to allow QEMU to ask to vhost user backend to
broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE
capability.
This new message is sent only if the backend supports the new
VHOST_USER_PROTOCOL_F_RARP protocol feature.
The payload of this new message is the MAC address of the guest (not known by
the backend). The MAC address is copied in the first 6 bytes of a u64 to avoid
to create a new payload message type.
This new message has no equivalent ioctl so a new callback is added in the
userOps structure to send the request.
Upon reception of this new message the vhost user backend must generate and
broadcast a fake RARP request to notify the migration is terminated.
Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
[Rebased and fixed checkpatch errors - Marc-André]
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
docs/specs/vhost-user.txt | 15 +++++++++++++++
hw/net/vhost_net.c | 17 +++++++++++++++++
hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++
include/hw/virtio/vhost-backend.h | 3 +++
include/net/vhost_net.h | 1 +
net/vhost-user.c | 24 ++++++++++++++++++++++--
6 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
index e0292a0..e0d71e2 100644
--- a/docs/specs/vhost-user.txt
+++ b/docs/specs/vhost-user.txt
@@ -194,6 +194,7 @@ Protocol features
#define VHOST_USER_PROTOCOL_F_MQ 0
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+#define VHOST_USER_PROTOCOL_F_RARP 2
Message types
-------------
@@ -381,3 +382,17 @@ Message types
Master payload: vring state description
Signal slave to enable or disable corresponding vring.
+
+ * VHOST_USER_SEND_RARP
+
+ Id: 19
+ Equivalent ioctl: N/A
+ Master payload: u64
+
+ Ask vhost user backend to broadcast a fake RARP to notify the migration
+ is terminated for guest that does not support GUEST_ANNOUNCE.
+ Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present in
+ VHOST_USER_GET_FEATURES and protocol feature bit VHOST_USER_PROTOCOL_F_RARP
+ is present in VHOST_USER_GET_PROTOCOL_FEATURES.
+ The first 6 bytes of the payload contain the mac address of the guest to
+ allow the vhost user backend to construct and broadcast the fake RARP.
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 840f443..da66b64 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
g_free(net);
}
+int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
+{
+ const VhostOps *vhost_ops = net->dev.vhost_ops;
+ int r = -1;
+
+ if (vhost_ops->vhost_migration_done) {
+ r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
+ }
+
+ return r;
+}
+
bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
{
return vhost_virtqueue_pending(&net->dev, idx);
@@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
{
}
+int vhost_net_notify_migration_done(struct vhost_net *net)
+{
+ return -1;
+}
+
VHostNetState *get_vhost_net(NetClientState *nc)
{
return 0;
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 455caba..b7f3699 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -10,6 +10,7 @@
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-backend.h"
+#include "hw/virtio/virtio-net.h"
#include "sysemu/char.h"
#include "sysemu/kvm.h"
#include "qemu/error-report.h"
@@ -30,6 +31,7 @@
#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
#define VHOST_USER_PROTOCOL_F_MQ 0
#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+#define VHOST_USER_PROTOCOL_F_RARP 2
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
@@ -51,6 +53,7 @@ typedef enum VhostUserRequest {
VHOST_USER_SET_PROTOCOL_FEATURES = 16,
VHOST_USER_GET_QUEUE_NUM = 17,
VHOST_USER_SET_VRING_ENABLE = 18,
+ VHOST_USER_SEND_RARP = 19,
VHOST_USER_MAX
} VhostUserRequest;
@@ -561,6 +564,32 @@ static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
VHOST_USER_PROTOCOL_F_LOG_SHMFD);
}
+static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
+{
+ VhostUserMsg msg = { 0 };
+ int err;
+
+ assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+
+ /* If guest supports GUEST_ANNOUNCE do nothing */
+ if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) {
+ return 0;
+ }
+
+ /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */
+ if (virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_RARP)) {
+ msg.request = VHOST_USER_SEND_RARP;
+ msg.flags = VHOST_USER_VERSION;
+ memcpy((char *)&msg.u64, mac_addr, 6);
+ msg.size = sizeof(m.u64);
+
+ err = vhost_user_write(dev, &msg, NULL, 0);
+ return err;
+ }
+ return -1;
+}
+
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
.vhost_backend_init = vhost_user_init,
@@ -582,4 +611,5 @@ const VhostOps user_ops = {
.vhost_get_vq_index = vhost_user_get_vq_index,
.vhost_set_vring_enable = vhost_user_set_vring_enable,
.vhost_requires_shm_log = vhost_user_requires_shm_log,
+ .vhost_migration_done = vhost_user_migration_done,
};
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index e07118c..5918c01 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -67,6 +67,8 @@ typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
int enable);
typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
+typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
+ char *mac_addr);
typedef struct VhostOps {
VhostBackendType backend_type;
@@ -94,6 +96,7 @@ typedef struct VhostOps {
vhost_get_vq_index_op vhost_get_vq_index;
vhost_set_vring_enable_op vhost_set_vring_enable;
vhost_requires_shm_log_op vhost_requires_shm_log;
+ vhost_migration_done_op vhost_migration_done;
} VhostOps;
extern const VhostOps user_ops;
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 0188c4d..3389b41 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -27,6 +27,7 @@ void vhost_net_ack_features(VHostNetState *net, uint64_t features);
bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
int idx, bool mask);
+int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
VHostNetState *get_vhost_net(NetClientState *nc);
int vhost_set_vring_enable(NetClientState * nc, int enable);
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 87917a5..cfe11b8 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -106,9 +106,29 @@ err:
static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
size_t size)
{
- /* Discard the request that is received and managed by backend
- * by an other way.
+ /* In case of RARP (message size is 60) notify backup to send a fake RARP.
+ This fake RARP will be sent by backend only for guest
+ without GUEST_ANNOUNCE capability.
*/
+ if (size == 60) {
+ VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
+ int r;
+ static int display_rarp_failure = 1;
+ char mac_addr[6];
+
+ /* extract guest mac address from the RARP message */
+ memcpy(mac_addr, &buf[6], 6);
+
+ r = vhost_net_notify_migration_done(s->vhost_net, mac_addr);
+
+ if ((r != 0) && (display_rarp_failure)) {
+ fprintf(stderr,
+ "Vhost user backend fails to broadcast fake RARP\n");
+ fflush(stderr);
+ display_rarp_failure = 0;
+ }
+ }
+
return size;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 16/21] vhost-user-test: move wait_for_fds() out
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (14 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 17/21] vhost-user-test: remove useless static check marcandre.lureau
` (6 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
This function is a precondition for most vhost-user tests.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/vhost-user-test.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 77b7b68..88714ff 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -205,15 +205,11 @@ static GThread *_thread_new(const gchar *name, GThreadFunc func, gpointer data)
return thread;
}
-static void read_guest_mem(void)
+static void wait_for_fds(void)
{
- uint32_t *guest_mem;
gint64 end_time;
- int i, j;
- size_t size;
g_mutex_lock(data_mutex);
-
end_time = _get_time() + 5 * G_TIME_SPAN_SECOND;
while (!fds_num) {
if (!_cond_wait_until(data_cond, data_mutex, end_time)) {
@@ -227,6 +223,17 @@ static void read_guest_mem(void)
g_assert_cmpint(fds_num, >, 0);
g_assert_cmpint(fds_num, ==, memory.nregions);
+ g_mutex_unlock(data_mutex);
+}
+
+static void read_guest_mem(void)
+{
+ uint32_t *guest_mem;
+ int i, j;
+ size_t size;
+
+ wait_for_fds();
+
/* iterate all regions */
for (i = 0; i < fds_num; i++) {
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 17/21] vhost-user-test: remove useless static check
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (15 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 16/21] vhost-user-test: move wait_for_fds() out marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 18/21] vhost-user-test: wrap server in TestServer struct marcandre.lureau
` (5 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/vhost-user-test.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 88714ff..6662ca9 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -262,7 +262,6 @@ static void read_guest_mem(void)
munmap(guest_mem, memory.regions[i].memory_size);
}
- g_assert_cmpint(1, ==, 1);
g_mutex_unlock(data_mutex);
}
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 18/21] vhost-user-test: wrap server in TestServer struct
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (16 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 17/21] vhost-user-test: remove useless static check marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 19/21] vhost-user-test: learn to tweak various qemu arguments marcandre.lureau
` (4 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
In the coming patches, a test will use several servers
simultaneously. Wrap the server in a struct, out of the global scope.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/vhost-user-test.c | 146 ++++++++++++++++++++++++++++++------------------
1 file changed, 92 insertions(+), 54 deletions(-)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 6662ca9..8daef01 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -115,10 +115,18 @@ static VhostUserMsg m __attribute__ ((unused));
#define VHOST_USER_VERSION (0x1)
/*****************************************************************************/
-int fds_num = 0, fds[VHOST_MEMORY_MAX_NREGIONS];
-static VhostUserMemory memory;
-static GMutex *data_mutex;
-static GCond *data_cond;
+typedef struct TestServer {
+ gchar *socket_path;
+ gchar *chr_name;
+ CharDriverState *chr;
+ int fds_num;
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ VhostUserMemory memory;
+ GMutex *data_mutex;
+ GCond *data_cond;
+} TestServer;
+
+static const char *hugefs;
static gint64 _get_time(void)
{
@@ -205,64 +213,63 @@ static GThread *_thread_new(const gchar *name, GThreadFunc func, gpointer data)
return thread;
}
-static void wait_for_fds(void)
+static void wait_for_fds(TestServer *s)
{
gint64 end_time;
- g_mutex_lock(data_mutex);
+ g_mutex_lock(s->data_mutex);
end_time = _get_time() + 5 * G_TIME_SPAN_SECOND;
- while (!fds_num) {
- if (!_cond_wait_until(data_cond, data_mutex, end_time)) {
+ while (!s->fds_num) {
+ if (!_cond_wait_until(s->data_cond, s->data_mutex, end_time)) {
/* timeout has passed */
- g_assert(fds_num);
+ g_assert(s->fds_num);
break;
}
}
/* check for sanity */
- g_assert_cmpint(fds_num, >, 0);
- g_assert_cmpint(fds_num, ==, memory.nregions);
+ g_assert_cmpint(s->fds_num, >, 0);
+ g_assert_cmpint(s->fds_num, ==, s->memory.nregions);
- g_mutex_unlock(data_mutex);
+ g_mutex_unlock(s->data_mutex);
}
-static void read_guest_mem(void)
+static void read_guest_mem(TestServer *s)
{
uint32_t *guest_mem;
int i, j;
size_t size;
- wait_for_fds();
+ wait_for_fds(s);
/* iterate all regions */
- for (i = 0; i < fds_num; i++) {
+ for (i = 0; i < s->fds_num; i++) {
/* We'll check only the region statring at 0x0*/
- if (memory.regions[i].guest_phys_addr != 0x0) {
+ if (s->memory.regions[i].guest_phys_addr != 0x0) {
continue;
}
- g_assert_cmpint(memory.regions[i].memory_size, >, 1024);
+ g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);
- size = memory.regions[i].memory_size + memory.regions[i].mmap_offset;
+ size = s->memory.regions[i].memory_size +
+ s->memory.regions[i].mmap_offset;
guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fds[i], 0);
+ MAP_SHARED, s->fds[i], 0);
g_assert(guest_mem != MAP_FAILED);
- guest_mem += (memory.regions[i].mmap_offset / sizeof(*guest_mem));
+ guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));
for (j = 0; j < 256; j++) {
- uint32_t a = readl(memory.regions[i].guest_phys_addr + j*4);
+ uint32_t a = readl(s->memory.regions[i].guest_phys_addr + j*4);
uint32_t b = guest_mem[j];
g_assert_cmpint(a, ==, b);
}
- munmap(guest_mem, memory.regions[i].memory_size);
+ munmap(guest_mem, s->memory.regions[i].memory_size);
}
-
- g_mutex_unlock(data_mutex);
}
static void *thread_function(void *data)
@@ -280,7 +287,8 @@ static int chr_can_read(void *opaque)
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
- CharDriverState *chr = opaque;
+ TestServer *s = opaque;
+ CharDriverState *chr = s->chr;
VhostUserMsg msg;
uint8_t *p = (uint8_t *) &msg;
int fd;
@@ -290,12 +298,12 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
return;
}
- g_mutex_lock(data_mutex);
+ g_mutex_lock(s->data_mutex);
memcpy(p, buf, VHOST_USER_HDR_SIZE);
if (msg.size) {
p += VHOST_USER_HDR_SIZE;
- qemu_chr_fe_read_all(chr, p, msg.size);
+ g_assert_cmpint(qemu_chr_fe_read_all(chr, p, msg.size), ==, msg.size);
}
switch (msg.request) {
@@ -334,11 +342,11 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
case VHOST_USER_SET_MEM_TABLE:
/* received the mem table */
- memcpy(&memory, &msg.memory, sizeof(msg.memory));
- fds_num = qemu_chr_fe_get_msgfds(chr, fds, sizeof(fds) / sizeof(int));
+ memcpy(&s->memory, &msg.memory, sizeof(msg.memory));
+ s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, G_N_ELEMENTS(s->fds));
/* signal the test that it can continue */
- g_cond_signal(data_cond);
+ g_cond_signal(s->data_cond);
break;
case VHOST_USER_SET_VRING_KICK:
@@ -355,7 +363,53 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
default:
break;
}
- g_mutex_unlock(data_mutex);
+
+ g_mutex_unlock(s->data_mutex);
+}
+
+static TestServer *test_server_new(const gchar *name)
+{
+ TestServer *server = g_new0(TestServer, 1);
+ gchar *chr_path;
+
+ server->socket_path = g_strdup_printf("/tmp/vhost-%s-%d.sock",
+ name, getpid());
+
+ chr_path = g_strdup_printf("unix:%s,server,nowait", server->socket_path);
+ server->chr_name = g_strdup_printf("chr-%s", name);
+ server->chr = qemu_chr_new(server->chr_name, chr_path, NULL);
+ g_free(chr_path);
+
+ qemu_chr_add_handlers(server->chr, chr_can_read, chr_read, NULL, server);
+
+ /* run the main loop thread so the chardev may operate */
+ server->data_mutex = _mutex_new();
+ server->data_cond = _cond_new();
+
+ return server;
+}
+
+#define GET_QEMU_CMD(s) \
+ g_strdup_printf(QEMU_CMD, (hugefs), (s)->socket_path)
+
+
+static void test_server_free(TestServer *server)
+{
+ int i;
+
+ qemu_chr_delete(server->chr);
+
+ for (i = 0; i < server->fds_num; i++) {
+ close(server->fds[i]);
+ }
+
+ unlink(server->socket_path);
+ g_free(server->socket_path);
+
+ _cond_free(server->data_cond);
+ _mutex_free(server->data_mutex);
+
+ g_free(server);
}
static const char *init_hugepagefs(void)
@@ -394,41 +448,28 @@ static const char *init_hugepagefs(void)
int main(int argc, char **argv)
{
QTestState *s = NULL;
- CharDriverState *chr = NULL;
- const char *hugefs = 0;
- char *socket_path = 0;
- char *qemu_cmd = 0;
- char *chr_path = 0;
+ TestServer *server = NULL;
+ char *qemu_cmd;
int ret;
g_test_init(&argc, &argv, NULL);
module_call_init(MODULE_INIT_QOM);
+ qemu_add_opts(&qemu_chardev_opts);
hugefs = init_hugepagefs();
if (!hugefs) {
return 0;
}
- socket_path = g_strdup_printf("/tmp/vhost-%d.sock", getpid());
-
- /* create char dev and add read handlers */
- qemu_add_opts(&qemu_chardev_opts);
- chr_path = g_strdup_printf("unix:%s,server,nowait", socket_path);
- chr = qemu_chr_new("chr0", chr_path, NULL);
- g_free(chr_path);
- qemu_chr_add_handlers(chr, chr_can_read, chr_read, NULL, chr);
-
- /* run the main loop thread so the chardev may operate */
- data_mutex = _mutex_new();
- data_cond = _cond_new();
_thread_new(NULL, thread_function, NULL);
- qemu_cmd = g_strdup_printf(QEMU_CMD, hugefs, socket_path);
+ server = test_server_new("test");
+ qemu_cmd = GET_QEMU_CMD(server);
s = qtest_start(qemu_cmd);
g_free(qemu_cmd);
- qtest_add_func("/vhost-user/read-guest-mem", read_guest_mem);
+ qtest_add_data_func("/vhost-user/read-guest-mem", server, read_guest_mem);
ret = g_test_run();
@@ -437,10 +478,7 @@ int main(int argc, char **argv)
}
/* cleanup */
- unlink(socket_path);
- g_free(socket_path);
- _cond_free(data_cond);
- _mutex_free(data_mutex);
+ test_server_free(server);
return ret;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 19/21] vhost-user-test: learn to tweak various qemu arguments
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (17 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 18/21] vhost-user-test: wrap server in TestServer struct marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 20/21] vhost-user-test: add live-migration test marcandre.lureau
` (3 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Add a new macro to make the qemu command line with other
values of memory size, and specific chardev id.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/vhost-user-test.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 8daef01..b2ac454 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -37,10 +37,10 @@
#endif
#define QEMU_CMD_ACCEL " -machine accel=tcg"
-#define QEMU_CMD_MEM " -m 512 -object memory-backend-file,id=mem,size=512M,"\
+#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM,"\
"mem-path=%s,share=on -numa node,memdev=mem"
-#define QEMU_CMD_CHR " -chardev socket,id=chr0,path=%s"
-#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=chr0,vhostforce"
+#define QEMU_CMD_CHR " -chardev socket,id=%s,path=%s"
+#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
#define QEMU_CMD_NET " -device virtio-net-pci,netdev=net0 "
#define QEMU_CMD_ROM " -option-rom ../pc-bios/pxe-virtio.rom"
@@ -389,9 +389,13 @@ static TestServer *test_server_new(const gchar *name)
return server;
}
-#define GET_QEMU_CMD(s) \
- g_strdup_printf(QEMU_CMD, (hugefs), (s)->socket_path)
+#define GET_QEMU_CMD(s) \
+ g_strdup_printf(QEMU_CMD, 512, 512, (hugefs), \
+ (s)->chr_name, (s)->socket_path, (s)->chr_name)
+#define GET_QEMU_CMDE(s, mem, extra, ...) \
+ g_strdup_printf(QEMU_CMD extra, (mem), (mem), (hugefs), \
+ (s)->chr_name, (s)->socket_path, (s)->chr_name, ##__VA_ARGS__)
static void test_server_free(TestServer *server)
{
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 20/21] vhost-user-test: add live-migration test
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (18 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 19/21] vhost-user-test: learn to tweak various qemu arguments marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 21/21] vhost-user-test: check ownership during migration marcandre.lureau
` (2 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
This test checks that the log fd is given to the migration source, and
mark dirty pages during migration.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/vhost-user-test.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 168 insertions(+), 3 deletions(-)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index b2ac454..7b5f130 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -13,6 +13,7 @@
#include "libqtest.h"
#include "qemu/option.h"
+#include "qemu/range.h"
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
@@ -54,6 +55,9 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+
+#define VHOST_LOG_PAGE 0x1000
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
@@ -124,6 +128,7 @@ typedef struct TestServer {
VhostUserMemory memory;
GMutex *data_mutex;
GCond *data_cond;
+ int log_fd;
} TestServer;
static const char *hugefs;
@@ -311,7 +316,8 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
/* send back features to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
msg.size = sizeof(m.u64);
- msg.u64 = 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
+ msg.u64 = 0x1ULL << VHOST_F_LOG_ALL |
+ 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break;
@@ -325,12 +331,11 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
/* send back features to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
msg.size = sizeof(m.u64);
- msg.u64 = 0;
+ msg.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD;
p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break;
-
case VHOST_USER_GET_VRING_BASE:
/* send back vring base to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
@@ -360,6 +365,21 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
*/
qemu_set_nonblock(fd);
break;
+
+ case VHOST_USER_SET_LOG_BASE:
+ if (s->log_fd != -1) {
+ close(s->log_fd);
+ s->log_fd = -1;
+ }
+ qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1);
+ msg.flags |= VHOST_USER_REPLY_MASK;
+ msg.size = 0;
+ p = (uint8_t *) &msg;
+ qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE);
+
+ g_cond_signal(s->data_cond);
+ break;
+
default:
break;
}
@@ -386,6 +406,8 @@ static TestServer *test_server_new(const gchar *name)
server->data_mutex = _mutex_new();
server->data_cond = _cond_new();
+ server->log_fd = -1;
+
return server;
}
@@ -407,15 +429,157 @@ static void test_server_free(TestServer *server)
close(server->fds[i]);
}
+ if (server->log_fd != -1) {
+ close(server->log_fd);
+ }
+
unlink(server->socket_path);
g_free(server->socket_path);
_cond_free(server->data_cond);
_mutex_free(server->data_mutex);
+ g_free(server->chr_name);
g_free(server);
}
+static void wait_for_log_fd(TestServer *s)
+{
+ gint64 end_time;
+
+ g_mutex_lock(s->data_mutex);
+ end_time = _get_time() + 5 * G_TIME_SPAN_SECOND;
+ while (s->log_fd == -1) {
+ if (!_cond_wait_until(s->data_cond, s->data_mutex, end_time)) {
+ /* timeout has passed */
+ g_assert(s->log_fd != -1);
+ break;
+ }
+ }
+
+ g_mutex_unlock(s->data_mutex);
+}
+
+static void write_guest_mem(TestServer *s, uint32 seed)
+{
+ uint32_t *guest_mem;
+ int i, j;
+ size_t size;
+
+ wait_for_fds(s);
+
+ /* iterate all regions */
+ for (i = 0; i < s->fds_num; i++) {
+
+ /* We'll write only the region statring at 0x0 */
+ if (s->memory.regions[i].guest_phys_addr != 0x0) {
+ continue;
+ }
+
+ g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);
+
+ size = s->memory.regions[i].memory_size +
+ s->memory.regions[i].mmap_offset;
+
+ guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, s->fds[i], 0);
+
+ g_assert(guest_mem != MAP_FAILED);
+ guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));
+
+ for (j = 0; j < 256; j++) {
+ guest_mem[j] = seed + j;
+ }
+
+ munmap(guest_mem, s->memory.regions[i].memory_size);
+ break;
+ }
+}
+
+static guint64 get_log_size(TestServer *s)
+{
+ guint64 log_size = 0;
+ int i;
+
+ for (i = 0; i < s->memory.nregions; ++i) {
+ VhostUserMemoryRegion *reg = &s->memory.regions[i];
+ guint64 last = range_get_last(reg->guest_phys_addr,
+ reg->memory_size);
+ log_size = MAX(log_size, last / (8 * VHOST_LOG_PAGE) + 1);
+ }
+
+ return log_size;
+}
+
+static void test_migrate(void)
+{
+ TestServer *s = test_server_new("src");
+ TestServer *dest = test_server_new("dest");
+ const char *uri = "tcp:127.0.0.1:1234";
+ QTestState *global = global_qtest, *from, *to;
+ gchar *cmd;
+ QDict *rsp;
+ guint8 *log;
+ guint64 size;
+
+ cmd = GET_QEMU_CMDE(s, 2, "");
+ from = qtest_start(cmd);
+ g_free(cmd);
+
+ wait_for_fds(s);
+ size = get_log_size(s);
+ g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
+
+ cmd = GET_QEMU_CMDE(dest, 2, " -incoming %s", uri);
+ to = qtest_init(cmd);
+ g_free(cmd);
+
+ /* slow down migration to have time to fiddle with log */
+ /* TODO: qtest could learn to break on some places */
+ rsp = qmp("{ 'execute': 'migrate_set_speed',"
+ "'arguments': { 'value': 10 } }");
+ g_assert(qdict_haskey(rsp, "return"));
+ QDECREF(rsp);
+
+ cmd = g_strdup_printf("{ 'execute': 'migrate',"
+ "'arguments': { 'uri': '%s' } }",
+ uri);
+ rsp = qmp(cmd);
+ g_free(cmd);
+ g_assert(qdict_haskey(rsp, "return"));
+ QDECREF(rsp);
+
+ wait_for_log_fd(s);
+
+ log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0);
+ g_assert(log != MAP_FAILED);
+
+ /* modify first page */
+ write_guest_mem(s, 0x42);
+ log[0] = 1;
+ munmap(log, size);
+
+ /* speed things up */
+ rsp = qmp("{ 'execute': 'migrate_set_speed',"
+ "'arguments': { 'value': 0 } }");
+ g_assert(qdict_haskey(rsp, "return"));
+ QDECREF(rsp);
+
+ qmp_eventwait("STOP");
+
+ global_qtest = to;
+ qmp_eventwait("RESUME");
+
+ read_guest_mem(dest);
+
+ qtest_quit(to);
+ test_server_free(dest);
+ qtest_quit(from);
+ test_server_free(s);
+
+ global_qtest = global;
+}
+
static const char *init_hugepagefs(void)
{
const char *path;
@@ -474,6 +638,7 @@ int main(int argc, char **argv)
g_free(qemu_cmd);
qtest_add_data_func("/vhost-user/read-guest-mem", server, read_guest_mem);
+ qtest_add_func("/vhost-user/migrate", test_migrate);
ret = g_test_run();
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PATCH v5 21/21] vhost-user-test: check ownership during migration
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (19 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 20/21] vhost-user-test: add live-migration test marcandre.lureau
@ 2015-09-24 16:22 ` marcandre.lureau
2015-09-27 13:19 ` [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support Michael S. Tsirkin
2015-09-29 15:07 ` Michael S. Tsirkin
22 siblings, 0 replies; 35+ messages in thread
From: marcandre.lureau @ 2015-09-24 16:22 UTC (permalink / raw)
To: qemu-devel
Cc: haifeng.lin, mst, thibaut.collet, jasowang, pbonzini,
Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Check that backend source and destination do not have simultaneous
ownership during migration.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/vhost-user-test.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 7b5f130..99a5cfe 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -380,6 +380,10 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
g_cond_signal(s->data_cond);
break;
+ case VHOST_USER_RESET_OWNER:
+ s->fds_num = 0;
+ break;
+
default:
break;
}
@@ -511,12 +515,37 @@ static guint64 get_log_size(TestServer *s)
return log_size;
}
+typedef struct TestMigrateSource {
+ GSource source;
+ TestServer *src;
+ TestServer *dest;
+} TestMigrateSource;
+
+static gboolean
+test_migrate_source_check(GSource *source)
+{
+ TestMigrateSource *t = (TestMigrateSource *)source;
+ gboolean overlap = t->src->fds_num > 0 && t->dest->fds_num > 0;
+
+ g_assert(!overlap);
+
+ return FALSE;
+}
+
+GSourceFuncs test_migrate_source_funcs = {
+ NULL,
+ test_migrate_source_check,
+ NULL,
+ NULL
+};
+
static void test_migrate(void)
{
TestServer *s = test_server_new("src");
TestServer *dest = test_server_new("dest");
const char *uri = "tcp:127.0.0.1:1234";
QTestState *global = global_qtest, *from, *to;
+ GSource *source;
gchar *cmd;
QDict *rsp;
guint8 *log;
@@ -534,6 +563,12 @@ static void test_migrate(void)
to = qtest_init(cmd);
g_free(cmd);
+ source = g_source_new(&test_migrate_source_funcs,
+ sizeof(TestMigrateSource));
+ ((TestMigrateSource *)source)->src = s;
+ ((TestMigrateSource *)source)->dest = dest;
+ g_source_attach(source, NULL);
+
/* slow down migration to have time to fiddle with log */
/* TODO: qtest could learn to break on some places */
rsp = qmp("{ 'execute': 'migrate_set_speed',"
@@ -572,6 +607,9 @@ static void test_migrate(void)
read_guest_mem(dest);
+ g_source_destroy(source);
+ g_source_unref(source);
+
qtest_quit(to);
test_server_free(dest);
qtest_quit(from);
--
2.4.3
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log marcandre.lureau
@ 2015-09-24 16:38 ` Eric Blake
2015-09-24 16:41 ` Marc-André Lureau
0 siblings, 1 reply; 35+ messages in thread
From: Eric Blake @ 2015-09-24 16:38 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel
Cc: thibaut.collet, jasowang, pbonzini, haifeng.lin, mst
[-- Attachment #1: Type: text/plain, Size: 1121 bytes --]
On 09/24/2015 10:22 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> docs/specs/vhost-user.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 46 insertions(+), 2 deletions(-)
> @@ -140,8 +142,7 @@ Multiple queue support
>
> Multiple queue is treated as a protocol extension, hence the slave has to
> implement protocol features first. The multiple queues feature is supported
> -only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set:
> -#define VHOST_USER_PROTOCOL_F_MQ 0
> +only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set.
Should this hunk be in an earlier patch,
> +
> +Protocol features
> +-----------------
> +
> +#define VHOST_USER_PROTOCOL_F_MQ 0
> +#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
along with this section (of course, with just bit 0 in that patch)?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log
2015-09-24 16:38 ` Eric Blake
@ 2015-09-24 16:41 ` Marc-André Lureau
2015-09-24 16:47 ` Eric Blake
0 siblings, 1 reply; 35+ messages in thread
From: Marc-André Lureau @ 2015-09-24 16:41 UTC (permalink / raw)
To: Eric Blake
Cc: haifeng lin, mst, thibaut collet, jasowang, qemu-devel, pbonzini,
marcandre lureau
Hi
----- Original Message -----
> On 09/24/2015 10:22 AM, marcandre.lureau@redhat.com wrote:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > docs/specs/vhost-user.txt | 48
> > +++++++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 46 insertions(+), 2 deletions(-)
>
> > @@ -140,8 +142,7 @@ Multiple queue support
> >
> > Multiple queue is treated as a protocol extension, hence the slave has to
> > implement protocol features first. The multiple queues feature is
> > supported
> > -only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set:
> > -#define VHOST_USER_PROTOCOL_F_MQ 0
> > +only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set.
>
> Should this hunk be in an earlier patch,
The series is on top of last Michael PULL request. I just moved the define
in a common section, since now they are 2 and later 3. Does that make sense?
>
> > +
> > +Protocol features
> > +-----------------
> > +
> > +#define VHOST_USER_PROTOCOL_F_MQ 0
> > +#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
>
> along with this section (of course, with just bit 0 in that patch)?
>
> --
> Eric Blake eblake redhat com +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log
2015-09-24 16:41 ` Marc-André Lureau
@ 2015-09-24 16:47 ` Eric Blake
0 siblings, 0 replies; 35+ messages in thread
From: Eric Blake @ 2015-09-24 16:47 UTC (permalink / raw)
To: Marc-André Lureau
Cc: haifeng lin, mst, thibaut collet, jasowang, qemu-devel, pbonzini,
marcandre lureau
[-- Attachment #1: Type: text/plain, Size: 710 bytes --]
On 09/24/2015 10:41 AM, Marc-André Lureau wrote:
>>> -only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set:
>>> -#define VHOST_USER_PROTOCOL_F_MQ 0
>>> +only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set.
>>
>> Should this hunk be in an earlier patch,
>
> The series is on top of last Michael PULL request. I just moved the define
> in a common section, since now they are 2 and later 3. Does that make sense?
Sure. My bad for not checking whether it was this series that introduced
bit 0 vs. it being pre-existing from an earlier series.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest marcandre.lureau
@ 2015-09-24 17:24 ` Thibaut Collet
2015-09-24 21:53 ` Marc-André Lureau
0 siblings, 1 reply; 35+ messages in thread
From: Thibaut Collet @ 2015-09-24 17:24 UTC (permalink / raw)
To: marcandre.lureau
Cc: Paolo Bonzini, Jason Wang, Michael S. Tsirkin, qemu-devel,
Linhaifeng
On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote:
> From: Thibaut Collet <thibaut.collet@6wind.com>
>
> A new vhost user message is added to allow QEMU to ask to vhost user backend to
> broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE
> capability.
>
> This new message is sent only if the backend supports the new
> VHOST_USER_PROTOCOL_F_RARP protocol feature.
> The payload of this new message is the MAC address of the guest (not known by
> the backend). The MAC address is copied in the first 6 bytes of a u64 to avoid
> to create a new payload message type.
>
> This new message has no equivalent ioctl so a new callback is added in the
> userOps structure to send the request.
>
> Upon reception of this new message the vhost user backend must generate and
> broadcast a fake RARP request to notify the migration is terminated.
>
> Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
> [Rebased and fixed checkpatch errors - Marc-André]
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> docs/specs/vhost-user.txt | 15 +++++++++++++++
> hw/net/vhost_net.c | 17 +++++++++++++++++
> hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++
> include/hw/virtio/vhost-backend.h | 3 +++
> include/net/vhost_net.h | 1 +
> net/vhost-user.c | 24 ++++++++++++++++++++++--
> 6 files changed, 88 insertions(+), 2 deletions(-)
>
> diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
> index e0292a0..e0d71e2 100644
> --- a/docs/specs/vhost-user.txt
> +++ b/docs/specs/vhost-user.txt
> @@ -194,6 +194,7 @@ Protocol features
>
> #define VHOST_USER_PROTOCOL_F_MQ 0
> #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> +#define VHOST_USER_PROTOCOL_F_RARP 2
>
> Message types
> -------------
> @@ -381,3 +382,17 @@ Message types
> Master payload: vring state description
>
> Signal slave to enable or disable corresponding vring.
> +
> + * VHOST_USER_SEND_RARP
> +
> + Id: 19
> + Equivalent ioctl: N/A
> + Master payload: u64
> +
> + Ask vhost user backend to broadcast a fake RARP to notify the migration
> + is terminated for guest that does not support GUEST_ANNOUNCE.
> + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present in
> + VHOST_USER_GET_FEATURES and protocol feature bit VHOST_USER_PROTOCOL_F_RARP
> + is present in VHOST_USER_GET_PROTOCOL_FEATURES.
> + The first 6 bytes of the payload contain the mac address of the guest to
> + allow the vhost user backend to construct and broadcast the fake RARP.
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 840f443..da66b64 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
> g_free(net);
> }
>
> +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
> +{
> + const VhostOps *vhost_ops = net->dev.vhost_ops;
> + int r = -1;
> +
> + if (vhost_ops->vhost_migration_done) {
> + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
> + }
> +
> + return r;
> +}
> +
> bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
> {
> return vhost_virtqueue_pending(&net->dev, idx);
> @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> {
> }
>
> +int vhost_net_notify_migration_done(struct vhost_net *net)
> +{
> + return -1;
> +}
> +
> VHostNetState *get_vhost_net(NetClientState *nc)
> {
> return 0;
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 455caba..b7f3699 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -10,6 +10,7 @@
>
> #include "hw/virtio/vhost.h"
> #include "hw/virtio/vhost-backend.h"
> +#include "hw/virtio/virtio-net.h"
> #include "sysemu/char.h"
> #include "sysemu/kvm.h"
> #include "qemu/error-report.h"
> @@ -30,6 +31,7 @@
> #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
> #define VHOST_USER_PROTOCOL_F_MQ 0
> #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> +#define VHOST_USER_PROTOCOL_F_RARP 2
The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL
>
> typedef enum VhostUserRequest {
> VHOST_USER_NONE = 0,
> @@ -51,6 +53,7 @@ typedef enum VhostUserRequest {
> VHOST_USER_SET_PROTOCOL_FEATURES = 16,
> VHOST_USER_GET_QUEUE_NUM = 17,
> VHOST_USER_SET_VRING_ENABLE = 18,
> + VHOST_USER_SEND_RARP = 19,
> VHOST_USER_MAX
> } VhostUserRequest;
>
> @@ -561,6 +564,32 @@ static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
> VHOST_USER_PROTOCOL_F_LOG_SHMFD);
> }
>
> +static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
> +{
> + VhostUserMsg msg = { 0 };
> + int err;
> +
> + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
> +
> + /* If guest supports GUEST_ANNOUNCE do nothing */
> + if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) {
> + return 0;
> + }
> +
> + /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */
> + if (virtio_has_feature(dev->protocol_features,
> + VHOST_USER_PROTOCOL_F_RARP)) {
> + msg.request = VHOST_USER_SEND_RARP;
> + msg.flags = VHOST_USER_VERSION;
> + memcpy((char *)&msg.u64, mac_addr, 6);
> + msg.size = sizeof(m.u64);
> +
> + err = vhost_user_write(dev, &msg, NULL, 0);
> + return err;
> + }
> + return -1;
> +}
> +
> const VhostOps user_ops = {
> .backend_type = VHOST_BACKEND_TYPE_USER,
> .vhost_backend_init = vhost_user_init,
> @@ -582,4 +611,5 @@ const VhostOps user_ops = {
> .vhost_get_vq_index = vhost_user_get_vq_index,
> .vhost_set_vring_enable = vhost_user_set_vring_enable,
> .vhost_requires_shm_log = vhost_user_requires_shm_log,
> + .vhost_migration_done = vhost_user_migration_done,
> };
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index e07118c..5918c01 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -67,6 +67,8 @@ typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
> typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
> int enable);
> typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
> +typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
> + char *mac_addr);
>
> typedef struct VhostOps {
> VhostBackendType backend_type;
> @@ -94,6 +96,7 @@ typedef struct VhostOps {
> vhost_get_vq_index_op vhost_get_vq_index;
> vhost_set_vring_enable_op vhost_set_vring_enable;
> vhost_requires_shm_log_op vhost_requires_shm_log;
> + vhost_migration_done_op vhost_migration_done;
> } VhostOps;
>
> extern const VhostOps user_ops;
> diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> index 0188c4d..3389b41 100644
> --- a/include/net/vhost_net.h
> +++ b/include/net/vhost_net.h
> @@ -27,6 +27,7 @@ void vhost_net_ack_features(VHostNetState *net, uint64_t features);
> bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
> void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> int idx, bool mask);
> +int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
> VHostNetState *get_vhost_net(NetClientState *nc);
>
> int vhost_set_vring_enable(NetClientState * nc, int enable);
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> index 87917a5..cfe11b8 100644
> --- a/net/vhost-user.c
> +++ b/net/vhost-user.c
> @@ -106,9 +106,29 @@ err:
> static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
> size_t size)
> {
> - /* Discard the request that is received and managed by backend
> - * by an other way.
> + /* In case of RARP (message size is 60) notify backup to send a fake RARP.
> + This fake RARP will be sent by backend only for guest
> + without GUEST_ANNOUNCE capability.
> */
> + if (size == 60) {
> + VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
> + int r;
> + static int display_rarp_failure = 1;
> + char mac_addr[6];
> +
> + /* extract guest mac address from the RARP message */
> + memcpy(mac_addr, &buf[6], 6);
> +
> + r = vhost_net_notify_migration_done(s->vhost_net, mac_addr);
> +
> + if ((r != 0) && (display_rarp_failure)) {
> + fprintf(stderr,
> + "Vhost user backend fails to broadcast fake RARP\n");
> + fflush(stderr);
> + display_rarp_failure = 0;
> + }
> + }
> +
> return size;
> }
>
> --
> 2.4.3
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-24 17:24 ` Thibaut Collet
@ 2015-09-24 21:53 ` Marc-André Lureau
2015-09-27 13:12 ` Michael S. Tsirkin
0 siblings, 1 reply; 35+ messages in thread
From: Marc-André Lureau @ 2015-09-24 21:53 UTC (permalink / raw)
To: Thibaut Collet
Cc: Linhaifeng, Michael S. Tsirkin, Jason Wang, qemu-devel,
Paolo Bonzini, marcandre lureau
Hi
----- Original Message -----
> On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote:
> > From: Thibaut Collet <thibaut.collet@6wind.com>
> >
> > A new vhost user message is added to allow QEMU to ask to vhost user
> > backend to
> > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE
> > capability.
> >
> > This new message is sent only if the backend supports the new
> > VHOST_USER_PROTOCOL_F_RARP protocol feature.
> > The payload of this new message is the MAC address of the guest (not known
> > by
> > the backend). The MAC address is copied in the first 6 bytes of a u64 to
> > avoid
> > to create a new payload message type.
> >
> > This new message has no equivalent ioctl so a new callback is added in the
> > userOps structure to send the request.
> >
> > Upon reception of this new message the vhost user backend must generate and
> > broadcast a fake RARP request to notify the migration is terminated.
> >
> > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
> > [Rebased and fixed checkpatch errors - Marc-André]
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > docs/specs/vhost-user.txt | 15 +++++++++++++++
> > hw/net/vhost_net.c | 17 +++++++++++++++++
> > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++
> > include/hw/virtio/vhost-backend.h | 3 +++
> > include/net/vhost_net.h | 1 +
> > net/vhost-user.c | 24 ++++++++++++++++++++++--
> > 6 files changed, 88 insertions(+), 2 deletions(-)
> >
> > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
> > index e0292a0..e0d71e2 100644
> > --- a/docs/specs/vhost-user.txt
> > +++ b/docs/specs/vhost-user.txt
> > @@ -194,6 +194,7 @@ Protocol features
> >
> > #define VHOST_USER_PROTOCOL_F_MQ 0
> > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> > +#define VHOST_USER_PROTOCOL_F_RARP 2
> >
> > Message types
> > -------------
> > @@ -381,3 +382,17 @@ Message types
> > Master payload: vring state description
> >
> > Signal slave to enable or disable corresponding vring.
> > +
> > + * VHOST_USER_SEND_RARP
> > +
> > + Id: 19
> > + Equivalent ioctl: N/A
> > + Master payload: u64
> > +
> > + Ask vhost user backend to broadcast a fake RARP to notify the
> > migration
> > + is terminated for guest that does not support GUEST_ANNOUNCE.
> > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present
> > in
> > + VHOST_USER_GET_FEATURES and protocol feature bit
> > VHOST_USER_PROTOCOL_F_RARP
> > + is present in VHOST_USER_GET_PROTOCOL_FEATURES.
> > + The first 6 bytes of the payload contain the mac address of the
> > guest to
> > + allow the vhost user backend to construct and broadcast the fake
> > RARP.
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 840f443..da66b64 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
> > g_free(net);
> > }
> >
> > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
> > +{
> > + const VhostOps *vhost_ops = net->dev.vhost_ops;
> > + int r = -1;
> > +
> > + if (vhost_ops->vhost_migration_done) {
> > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
> > + }
> > +
> > + return r;
> > +}
> > +
> > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
> > {
> > return vhost_virtqueue_pending(&net->dev, idx);
> > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net,
> > VirtIODevice *dev,
> > {
> > }
> >
> > +int vhost_net_notify_migration_done(struct vhost_net *net)
> > +{
> > + return -1;
> > +}
> > +
> > VHostNetState *get_vhost_net(NetClientState *nc)
> > {
> > return 0;
> > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> > index 455caba..b7f3699 100644
> > --- a/hw/virtio/vhost-user.c
> > +++ b/hw/virtio/vhost-user.c
> > @@ -10,6 +10,7 @@
> >
> > #include "hw/virtio/vhost.h"
> > #include "hw/virtio/vhost-backend.h"
> > +#include "hw/virtio/virtio-net.h"
> > #include "sysemu/char.h"
> > #include "sysemu/kvm.h"
> > #include "qemu/error-report.h"
> > @@ -30,6 +31,7 @@
> > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
> > #define VHOST_USER_PROTOCOL_F_MQ 0
> > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> > +#define VHOST_USER_PROTOCOL_F_RARP 2
>
> The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL
>
Good catch (too many rebases, having a test would help to prevent this kind of mistake)
thanks
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-24 21:53 ` Marc-André Lureau
@ 2015-09-27 13:12 ` Michael S. Tsirkin
2015-09-27 15:13 ` Marc-André Lureau
0 siblings, 1 reply; 35+ messages in thread
From: Michael S. Tsirkin @ 2015-09-27 13:12 UTC (permalink / raw)
To: Marc-André Lureau
Cc: Linhaifeng, Thibaut Collet, Jason Wang, qemu-devel,
marcandre lureau, Paolo Bonzini
On Thu, Sep 24, 2015 at 05:53:05PM -0400, Marc-André Lureau wrote:
> Hi
>
> ----- Original Message -----
> > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote:
> > > From: Thibaut Collet <thibaut.collet@6wind.com>
> > >
> > > A new vhost user message is added to allow QEMU to ask to vhost user
> > > backend to
> > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE
> > > capability.
> > >
> > > This new message is sent only if the backend supports the new
> > > VHOST_USER_PROTOCOL_F_RARP protocol feature.
> > > The payload of this new message is the MAC address of the guest (not known
> > > by
> > > the backend). The MAC address is copied in the first 6 bytes of a u64 to
> > > avoid
> > > to create a new payload message type.
> > >
> > > This new message has no equivalent ioctl so a new callback is added in the
> > > userOps structure to send the request.
> > >
> > > Upon reception of this new message the vhost user backend must generate and
> > > broadcast a fake RARP request to notify the migration is terminated.
> > >
> > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
> > > [Rebased and fixed checkpatch errors - Marc-André]
> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > ---
> > > docs/specs/vhost-user.txt | 15 +++++++++++++++
> > > hw/net/vhost_net.c | 17 +++++++++++++++++
> > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++
> > > include/hw/virtio/vhost-backend.h | 3 +++
> > > include/net/vhost_net.h | 1 +
> > > net/vhost-user.c | 24 ++++++++++++++++++++++--
> > > 6 files changed, 88 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
> > > index e0292a0..e0d71e2 100644
> > > --- a/docs/specs/vhost-user.txt
> > > +++ b/docs/specs/vhost-user.txt
> > > @@ -194,6 +194,7 @@ Protocol features
> > >
> > > #define VHOST_USER_PROTOCOL_F_MQ 0
> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> > > +#define VHOST_USER_PROTOCOL_F_RARP 2
> > >
> > > Message types
> > > -------------
> > > @@ -381,3 +382,17 @@ Message types
> > > Master payload: vring state description
> > >
> > > Signal slave to enable or disable corresponding vring.
> > > +
> > > + * VHOST_USER_SEND_RARP
> > > +
> > > + Id: 19
> > > + Equivalent ioctl: N/A
> > > + Master payload: u64
> > > +
> > > + Ask vhost user backend to broadcast a fake RARP to notify the
> > > migration
> > > + is terminated for guest that does not support GUEST_ANNOUNCE.
> > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present
> > > in
> > > + VHOST_USER_GET_FEATURES and protocol feature bit
> > > VHOST_USER_PROTOCOL_F_RARP
> > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES.
> > > + The first 6 bytes of the payload contain the mac address of the
> > > guest to
> > > + allow the vhost user backend to construct and broadcast the fake
> > > RARP.
> > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > > index 840f443..da66b64 100644
> > > --- a/hw/net/vhost_net.c
> > > +++ b/hw/net/vhost_net.c
> > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
> > > g_free(net);
> > > }
> > >
> > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
> > > +{
> > > + const VhostOps *vhost_ops = net->dev.vhost_ops;
> > > + int r = -1;
> > > +
> > > + if (vhost_ops->vhost_migration_done) {
> > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
> > > + }
> > > +
> > > + return r;
> > > +}
> > > +
> > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
> > > {
> > > return vhost_virtqueue_pending(&net->dev, idx);
> > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net,
> > > VirtIODevice *dev,
> > > {
> > > }
> > >
> > > +int vhost_net_notify_migration_done(struct vhost_net *net)
> > > +{
> > > + return -1;
> > > +}
> > > +
> > > VHostNetState *get_vhost_net(NetClientState *nc)
> > > {
> > > return 0;
> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> > > index 455caba..b7f3699 100644
> > > --- a/hw/virtio/vhost-user.c
> > > +++ b/hw/virtio/vhost-user.c
> > > @@ -10,6 +10,7 @@
> > >
> > > #include "hw/virtio/vhost.h"
> > > #include "hw/virtio/vhost-backend.h"
> > > +#include "hw/virtio/virtio-net.h"
> > > #include "sysemu/char.h"
> > > #include "sysemu/kvm.h"
> > > #include "qemu/error-report.h"
> > > @@ -30,6 +31,7 @@
> > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
> > > #define VHOST_USER_PROTOCOL_F_MQ 0
> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> > > +#define VHOST_USER_PROTOCOL_F_RARP 2
> >
> > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL
> >
Better, change VHOST_USER_PROTOCOL_FEATURE_MASK to be
calculated based on other macros.
>
> Good catch (too many rebases, having a test would help to prevent this kind of mistake)
>
> thanks
So there will be v6 with a fix?
--
MST
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (20 preceding siblings ...)
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 21/21] vhost-user-test: check ownership during migration marcandre.lureau
@ 2015-09-27 13:19 ` Michael S. Tsirkin
2015-09-29 15:07 ` Michael S. Tsirkin
22 siblings, 0 replies; 35+ messages in thread
From: Michael S. Tsirkin @ 2015-09-27 13:19 UTC (permalink / raw)
To: marcandre.lureau
Cc: haifeng.lin, thibaut.collet, jasowang, qemu-devel, pbonzini
On Thu, Sep 24, 2015 at 06:22:00PM +0200, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Hi,
>
> The following series implement shareable log for vhost-user to support
> memory tracking during live migration. On qemu-side, the solution is
> fairly straightfoward since vhost already supports the dirty log, only
> vhost-user couldn't access the log memory until then.
>
> The series includes "protocol feature negotiation" series proposed
> earlier by Michael S. Tsirkinm and "vhost user: Add live migration"
> series from Thibaut Collet .
I applied patches 1-14 in my tree for now.
This way you don't need to repost them.
If you do change some of these you can post a fixup patch
(with subject fixup! <original subject>)
or tell me to drop some of the old patches.
> v4->v5:
> - rebase on top of last Michael S. Tsirkin PULL request
> - block live migration if !PROTOCOL_F_LOG_SHMFD
> - wait for a reply after SET_LOG_BASE
> - split vhost_set_log_base from the rest of vhost_call refactoring
> - use a seperate global vhost_log_shm
>
> v3->v4:
> - add the proto negotiation & the migration series
> - replace the varargs vhost_call() approach for callbacks
> - only share-allocate when the backend needs it
>
> v2->v3:
> - changed some patch summary
> - added migration tests
> - added a patch to replace error message with a trace
>
> The development branch I used is:
> https://github.com/elmarco/qemu branch "vhost-user"
>
> Marc-André Lureau (18):
> configure: probe for memfd
> util: add linux-only memfd fallback
> util: add memfd helpers
> vhost: alloc shareable log
> vhost: document log resizing
> vhost: add vhost_set_log_base op
> vhost-user: send log shm fd along with log_base
> vhost-user: add a migration blocker
> vhost: use a function for each call
> vhost: only use shared log if in use by backend
> vhost-user: document migration log
> net: add trace_vhost_user_event
> vhost-user-test: move wait_for_fds() out
> vhost-user-test: remove useless static check
> vhost-user-test: wrap server in TestServer struct
> vhost-user-test: learn to tweak various qemu arguments
> vhost-user-test: add live-migration test
> vhost-user-test: check ownership during migration
>
> Michael S. Tsirkin (1):
> vhost-user: unit test for new messages
>
> Thibaut Collet (2):
> vhost user: add support of live migration
> vhost user: add rarp sending after live migration for legacy guest
>
> configure | 19 ++
> docs/specs/vhost-user.txt | 63 ++++-
> hw/net/vhost_net.c | 35 ++-
> hw/scsi/vhost-scsi.c | 7 +-
> hw/virtio/vhost-backend.c | 121 +++++++-
> hw/virtio/vhost-user.c | 571 ++++++++++++++++++++++++--------------
> hw/virtio/vhost.c | 101 ++++---
> include/hw/virtio/vhost-backend.h | 77 ++++-
> include/hw/virtio/vhost.h | 15 +-
> include/net/vhost_net.h | 1 +
> include/qemu/memfd.h | 24 ++
> net/vhost-user.c | 34 ++-
> tests/vhost-user-test.c | 390 ++++++++++++++++++++++----
> trace-events | 3 +
> util/Makefile.objs | 2 +-
> util/memfd.c | 126 +++++++++
> 16 files changed, 1260 insertions(+), 329 deletions(-)
> create mode 100644 include/qemu/memfd.h
> create mode 100644 util/memfd.c
>
> --
> 2.4.3
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-27 13:12 ` Michael S. Tsirkin
@ 2015-09-27 15:13 ` Marc-André Lureau
2015-09-27 15:49 ` Thibaut Collet
0 siblings, 1 reply; 35+ messages in thread
From: Marc-André Lureau @ 2015-09-27 15:13 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Thibaut Collet, Jason Wang, Paolo Bonzini, Linhaifeng, qemu-devel
Hi
On Sun, Sep 27, 2015 at 3:12 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Thu, Sep 24, 2015 at 05:53:05PM -0400, Marc-André Lureau wrote:
>> Hi
>>
>> ----- Original Message -----
>> > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote:
>> > > From: Thibaut Collet <thibaut.collet@6wind.com>
>> > >
>> > > A new vhost user message is added to allow QEMU to ask to vhost user
>> > > backend to
>> > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE
>> > > capability.
>> > >
>> > > This new message is sent only if the backend supports the new
>> > > VHOST_USER_PROTOCOL_F_RARP protocol feature.
>> > > The payload of this new message is the MAC address of the guest (not known
>> > > by
>> > > the backend). The MAC address is copied in the first 6 bytes of a u64 to
>> > > avoid
>> > > to create a new payload message type.
>> > >
>> > > This new message has no equivalent ioctl so a new callback is added in the
>> > > userOps structure to send the request.
>> > >
>> > > Upon reception of this new message the vhost user backend must generate and
>> > > broadcast a fake RARP request to notify the migration is terminated.
>> > >
>> > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
>> > > [Rebased and fixed checkpatch errors - Marc-André]
>> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> > > ---
>> > > docs/specs/vhost-user.txt | 15 +++++++++++++++
>> > > hw/net/vhost_net.c | 17 +++++++++++++++++
>> > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++
>> > > include/hw/virtio/vhost-backend.h | 3 +++
>> > > include/net/vhost_net.h | 1 +
>> > > net/vhost-user.c | 24 ++++++++++++++++++++++--
>> > > 6 files changed, 88 insertions(+), 2 deletions(-)
>> > >
>> > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
>> > > index e0292a0..e0d71e2 100644
>> > > --- a/docs/specs/vhost-user.txt
>> > > +++ b/docs/specs/vhost-user.txt
>> > > @@ -194,6 +194,7 @@ Protocol features
>> > >
>> > > #define VHOST_USER_PROTOCOL_F_MQ 0
>> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
>> > > +#define VHOST_USER_PROTOCOL_F_RARP 2
>> > >
>> > > Message types
>> > > -------------
>> > > @@ -381,3 +382,17 @@ Message types
>> > > Master payload: vring state description
>> > >
>> > > Signal slave to enable or disable corresponding vring.
>> > > +
>> > > + * VHOST_USER_SEND_RARP
>> > > +
>> > > + Id: 19
>> > > + Equivalent ioctl: N/A
>> > > + Master payload: u64
>> > > +
>> > > + Ask vhost user backend to broadcast a fake RARP to notify the
>> > > migration
>> > > + is terminated for guest that does not support GUEST_ANNOUNCE.
>> > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present
>> > > in
>> > > + VHOST_USER_GET_FEATURES and protocol feature bit
>> > > VHOST_USER_PROTOCOL_F_RARP
>> > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES.
>> > > + The first 6 bytes of the payload contain the mac address of the
>> > > guest to
>> > > + allow the vhost user backend to construct and broadcast the fake
>> > > RARP.
>> > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
>> > > index 840f443..da66b64 100644
>> > > --- a/hw/net/vhost_net.c
>> > > +++ b/hw/net/vhost_net.c
>> > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
>> > > g_free(net);
>> > > }
>> > >
>> > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
>> > > +{
>> > > + const VhostOps *vhost_ops = net->dev.vhost_ops;
>> > > + int r = -1;
>> > > +
>> > > + if (vhost_ops->vhost_migration_done) {
>> > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
>> > > + }
>> > > +
>> > > + return r;
>> > > +}
>> > > +
>> > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
>> > > {
>> > > return vhost_virtqueue_pending(&net->dev, idx);
>> > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net,
>> > > VirtIODevice *dev,
>> > > {
>> > > }
>> > >
>> > > +int vhost_net_notify_migration_done(struct vhost_net *net)
>> > > +{
>> > > + return -1;
>> > > +}
>> > > +
>> > > VHostNetState *get_vhost_net(NetClientState *nc)
>> > > {
>> > > return 0;
>> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
>> > > index 455caba..b7f3699 100644
>> > > --- a/hw/virtio/vhost-user.c
>> > > +++ b/hw/virtio/vhost-user.c
>> > > @@ -10,6 +10,7 @@
>> > >
>> > > #include "hw/virtio/vhost.h"
>> > > #include "hw/virtio/vhost-backend.h"
>> > > +#include "hw/virtio/virtio-net.h"
>> > > #include "sysemu/char.h"
>> > > #include "sysemu/kvm.h"
>> > > #include "qemu/error-report.h"
>> > > @@ -30,6 +31,7 @@
>> > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
>> > > #define VHOST_USER_PROTOCOL_F_MQ 0
>> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
>> > > +#define VHOST_USER_PROTOCOL_F_RARP 2
>> >
>> > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL
>> >
> Better, change VHOST_USER_PROTOCOL_FEATURE_MASK to be
> calculated based on other macros.
yeah, I actually thought about something like this a few days ago:
https://github.com/elmarco/qemu/commit/b4e4ec2e4c78f6b12e34822d8a3f3a101d065d80
Is that what you have in mind or rather make a bit mask of all the
features? Maybe the bitmask of all the features is simpler.
>
>>
>> Good catch (too many rebases, having a test would help to prevent this kind of mistake)
>>
>> thanks
>
> So there will be v6 with a fix?
If there is no further changes in the series, I guess you could fix it
when cherry-picking. But if I have to send a v6, I'll include the fix.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-27 15:13 ` Marc-André Lureau
@ 2015-09-27 15:49 ` Thibaut Collet
2015-09-27 18:04 ` Marc-André Lureau
0 siblings, 1 reply; 35+ messages in thread
From: Thibaut Collet @ 2015-09-27 15:49 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Paolo Bonzini, Jason Wang, Linhaifeng,
Michael S. Tsirkin
On Sun, Sep 27, 2015 at 5:13 PM, Marc-André Lureau
<marcandre.lureau@gmail.com> wrote:
> Hi
>
> On Sun, Sep 27, 2015 at 3:12 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> On Thu, Sep 24, 2015 at 05:53:05PM -0400, Marc-André Lureau wrote:
>>> Hi
>>>
>>> ----- Original Message -----
>>> > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote:
>>> > > From: Thibaut Collet <thibaut.collet@6wind.com>
>>> > >
>>> > > A new vhost user message is added to allow QEMU to ask to vhost user
>>> > > backend to
>>> > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE
>>> > > capability.
>>> > >
>>> > > This new message is sent only if the backend supports the new
>>> > > VHOST_USER_PROTOCOL_F_RARP protocol feature.
>>> > > The payload of this new message is the MAC address of the guest (not known
>>> > > by
>>> > > the backend). The MAC address is copied in the first 6 bytes of a u64 to
>>> > > avoid
>>> > > to create a new payload message type.
>>> > >
>>> > > This new message has no equivalent ioctl so a new callback is added in the
>>> > > userOps structure to send the request.
>>> > >
>>> > > Upon reception of this new message the vhost user backend must generate and
>>> > > broadcast a fake RARP request to notify the migration is terminated.
>>> > >
>>> > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
>>> > > [Rebased and fixed checkpatch errors - Marc-André]
>>> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> > > ---
>>> > > docs/specs/vhost-user.txt | 15 +++++++++++++++
>>> > > hw/net/vhost_net.c | 17 +++++++++++++++++
>>> > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++
>>> > > include/hw/virtio/vhost-backend.h | 3 +++
>>> > > include/net/vhost_net.h | 1 +
>>> > > net/vhost-user.c | 24 ++++++++++++++++++++++--
>>> > > 6 files changed, 88 insertions(+), 2 deletions(-)
>>> > >
>>> > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
>>> > > index e0292a0..e0d71e2 100644
>>> > > --- a/docs/specs/vhost-user.txt
>>> > > +++ b/docs/specs/vhost-user.txt
>>> > > @@ -194,6 +194,7 @@ Protocol features
>>> > >
>>> > > #define VHOST_USER_PROTOCOL_F_MQ 0
>>> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
>>> > > +#define VHOST_USER_PROTOCOL_F_RARP 2
>>> > >
>>> > > Message types
>>> > > -------------
>>> > > @@ -381,3 +382,17 @@ Message types
>>> > > Master payload: vring state description
>>> > >
>>> > > Signal slave to enable or disable corresponding vring.
>>> > > +
>>> > > + * VHOST_USER_SEND_RARP
>>> > > +
>>> > > + Id: 19
>>> > > + Equivalent ioctl: N/A
>>> > > + Master payload: u64
>>> > > +
>>> > > + Ask vhost user backend to broadcast a fake RARP to notify the
>>> > > migration
>>> > > + is terminated for guest that does not support GUEST_ANNOUNCE.
>>> > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present
>>> > > in
>>> > > + VHOST_USER_GET_FEATURES and protocol feature bit
>>> > > VHOST_USER_PROTOCOL_F_RARP
>>> > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES.
>>> > > + The first 6 bytes of the payload contain the mac address of the
>>> > > guest to
>>> > > + allow the vhost user backend to construct and broadcast the fake
>>> > > RARP.
>>> > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
>>> > > index 840f443..da66b64 100644
>>> > > --- a/hw/net/vhost_net.c
>>> > > +++ b/hw/net/vhost_net.c
>>> > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
>>> > > g_free(net);
>>> > > }
>>> > >
>>> > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
>>> > > +{
>>> > > + const VhostOps *vhost_ops = net->dev.vhost_ops;
>>> > > + int r = -1;
>>> > > +
>>> > > + if (vhost_ops->vhost_migration_done) {
>>> > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
>>> > > + }
>>> > > +
>>> > > + return r;
>>> > > +}
>>> > > +
>>> > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
>>> > > {
>>> > > return vhost_virtqueue_pending(&net->dev, idx);
>>> > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net,
>>> > > VirtIODevice *dev,
>>> > > {
>>> > > }
>>> > >
>>> > > +int vhost_net_notify_migration_done(struct vhost_net *net)
>>> > > +{
>>> > > + return -1;
>>> > > +}
>>> > > +
>>> > > VHostNetState *get_vhost_net(NetClientState *nc)
>>> > > {
>>> > > return 0;
>>> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
>>> > > index 455caba..b7f3699 100644
>>> > > --- a/hw/virtio/vhost-user.c
>>> > > +++ b/hw/virtio/vhost-user.c
>>> > > @@ -10,6 +10,7 @@
>>> > >
>>> > > #include "hw/virtio/vhost.h"
>>> > > #include "hw/virtio/vhost-backend.h"
>>> > > +#include "hw/virtio/virtio-net.h"
>>> > > #include "sysemu/char.h"
>>> > > #include "sysemu/kvm.h"
>>> > > #include "qemu/error-report.h"
>>> > > @@ -30,6 +31,7 @@
>>> > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL
>>> > > #define VHOST_USER_PROTOCOL_F_MQ 0
>>> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
>>> > > +#define VHOST_USER_PROTOCOL_F_RARP 2
>>> >
>>> > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL
>>> >
>> Better, change VHOST_USER_PROTOCOL_FEATURE_MASK to be
>> calculated based on other macros.
>
> yeah, I actually thought about something like this a few days ago:
> https://github.com/elmarco/qemu/commit/b4e4ec2e4c78f6b12e34822d8a3f3a101d065d80
>
I agree an automatic computation of the FEATURE_MASK from the
different protocol feature will avoid issues wiht rebase or merge
operation.
Maybe a solution like that is clearer ?
-#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x7ULL
-#define VHOST_USER_PROTOCOL_F_MQ 0
-#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
-#define VHOST_USER_PROTOCOL_F_RARP 2
+typedef enum VhostUserProtocolFeature {
+VHOST_USER_PROTOCOL_F_MQ = 0,
+VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
+VHOST_USER_PROTOCOL_F_RARP = 2,
+VHOST_USER_PROTOCOL_F_MAX
+} VhostUserProtocolFeature ;
+#define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1)
> Is that what you have in mind or rather make a bit mask of all the
> features? Maybe the bitmask of all the features is simpler.
>
>>
>>>
>>> Good catch (too many rebases, having a test would help to prevent this kind of mistake)
>>>
>>> thanks
>>
>> So there will be v6 with a fix?
>
> If there is no further changes in the series, I guess you could fix it
> when cherry-picking. But if I have to send a v6, I'll include the fix.
>
> thanks
>
>
>
> --
> Marc-André Lureau
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest
2015-09-27 15:49 ` Thibaut Collet
@ 2015-09-27 18:04 ` Marc-André Lureau
0 siblings, 0 replies; 35+ messages in thread
From: Marc-André Lureau @ 2015-09-27 18:04 UTC (permalink / raw)
To: Thibaut Collet
Cc: qemu-devel, Paolo Bonzini, Jason Wang, Linhaifeng,
Michael S. Tsirkin
hi
On Sun, Sep 27, 2015 at 5:49 PM, Thibaut Collet
<thibaut.collet@6wind.com> wrote:
> Maybe a solution like that is clearer ?
>
> -#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x7ULL
> -#define VHOST_USER_PROTOCOL_F_MQ 0
> -#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
> -#define VHOST_USER_PROTOCOL_F_RARP 2
> +typedef enum VhostUserProtocolFeature {
> +VHOST_USER_PROTOCOL_F_MQ = 0,
> +VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
> +VHOST_USER_PROTOCOL_F_RARP = 2,
> +VHOST_USER_PROTOCOL_F_MAX
> +} VhostUserProtocolFeature ;
>
> +#define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1)
I agree with that, I don't see a good reason to keep the defines.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend marcandre.lureau
@ 2015-09-29 14:59 ` Michael S. Tsirkin
2015-09-29 15:26 ` Marc-André Lureau
0 siblings, 1 reply; 35+ messages in thread
From: Michael S. Tsirkin @ 2015-09-29 14:59 UTC (permalink / raw)
To: marcandre.lureau
Cc: haifeng.lin, thibaut.collet, jasowang, qemu-devel, pbonzini
On Thu, Sep 24, 2015 at 06:22:11PM +0200, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Do not allocate a shared log if the backend doesn't support it.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
So squash this in the previous patch introducing the shared log?
This split makes review harder, not easier.
> ---
> hw/virtio/vhost-user.c | 9 +++++++++
> hw/virtio/vhost.c | 15 ++++++++++-----
> include/hw/virtio/vhost-backend.h | 4 ++++
> 3 files changed, 23 insertions(+), 5 deletions(-)
>
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 41e0364..455caba 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -553,6 +553,14 @@ static int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
> return idx;
> }
>
> +static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
> +{
> + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
> +
> + return virtio_has_feature(dev->protocol_features,
> + VHOST_USER_PROTOCOL_F_LOG_SHMFD);
> +}
> +
> const VhostOps user_ops = {
> .backend_type = VHOST_BACKEND_TYPE_USER,
> .vhost_backend_init = vhost_user_init,
> @@ -573,4 +581,5 @@ const VhostOps user_ops = {
> .vhost_reset_device = vhost_user_reset_device,
> .vhost_get_vq_index = vhost_user_get_vq_index,
> .vhost_set_vring_enable = vhost_user_set_vring_enable,
> + .vhost_requires_shm_log = vhost_user_requires_shm_log,
> };
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index d9f2131..ec27c7b 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -357,10 +357,15 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
> }
> }
>
> -static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
> +static bool vhost_dev_log_is_shared(struct vhost_dev *dev)
> {
> - bool share = dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
> - struct vhost_log *log = vhost_log_get(size, share);
> + return dev->vhost_ops->vhost_requires_shm_log &&
> + dev->vhost_ops->vhost_requires_shm_log(dev);
> +}
> +
> +static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
> +{
> + struct vhost_log *log = vhost_log_get(size, vhost_dev_log_is_shared(dev));
> uint64_t log_base = (uintptr_t)log->log;
> int r;
>
> @@ -1166,10 +1171,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>
> if (hdev->log_enabled) {
> uint64_t log_base;
> - bool share = hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
>
> hdev->log_size = vhost_get_log_size(hdev);
> - hdev->log = vhost_log_get(hdev->log_size, share);
> + hdev->log = vhost_log_get(hdev->log_size,
> + vhost_dev_log_is_shared(hdev));
> log_base = (uintptr_t)hdev->log->log;
> r = hdev->vhost_ops->vhost_set_log_base(hdev,
> hdev->log_size ? log_base : 0,
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index 868a78a..e07118c 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -11,6 +11,8 @@
> #ifndef VHOST_BACKEND_H_
> #define VHOST_BACKEND_H_
>
> +#include <stdbool.h>
> +
> typedef enum VhostBackendType {
> VHOST_BACKEND_TYPE_NONE = 0,
> VHOST_BACKEND_TYPE_KERNEL = 1,
> @@ -64,6 +66,7 @@ typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
> typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
> typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
> int enable);
> +typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
>
> typedef struct VhostOps {
> VhostBackendType backend_type;
> @@ -90,6 +93,7 @@ typedef struct VhostOps {
> vhost_reset_device_op vhost_reset_device;
> vhost_get_vq_index_op vhost_get_vq_index;
> vhost_set_vring_enable_op vhost_set_vring_enable;
> + vhost_requires_shm_log_op vhost_requires_shm_log;
> } VhostOps;
>
> extern const VhostOps user_ops;
> --
> 2.4.3
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
` (21 preceding siblings ...)
2015-09-27 13:19 ` [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support Michael S. Tsirkin
@ 2015-09-29 15:07 ` Michael S. Tsirkin
22 siblings, 0 replies; 35+ messages in thread
From: Michael S. Tsirkin @ 2015-09-29 15:07 UTC (permalink / raw)
To: marcandre.lureau
Cc: haifeng.lin, thibaut.collet, jasowang, qemu-devel, pbonzini
On Thu, Sep 24, 2015 at 06:22:00PM +0200, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Hi,
>
> The following series implement shareable log for vhost-user to support
> memory tracking during live migration. On qemu-side, the solution is
> fairly straightfoward since vhost already supports the dirty log, only
> vhost-user couldn't access the log memory until then.
>
> The series includes "protocol feature negotiation" series proposed
> earlier by Michael S. Tsirkinm and "vhost user: Add live migration"
> series from Thibaut Collet .
So I dropped everything except the 1st patch from my tree
since there were too many failures.
> v4->v5:
> - rebase on top of last Michael S. Tsirkin PULL request
> - block live migration if !PROTOCOL_F_LOG_SHMFD
> - wait for a reply after SET_LOG_BASE
> - split vhost_set_log_base from the rest of vhost_call refactoring
> - use a seperate global vhost_log_shm
>
> v3->v4:
> - add the proto negotiation & the migration series
> - replace the varargs vhost_call() approach for callbacks
> - only share-allocate when the backend needs it
>
> v2->v3:
> - changed some patch summary
> - added migration tests
> - added a patch to replace error message with a trace
>
> The development branch I used is:
> https://github.com/elmarco/qemu branch "vhost-user"
>
> Marc-André Lureau (18):
> configure: probe for memfd
> util: add linux-only memfd fallback
> util: add memfd helpers
> vhost: alloc shareable log
> vhost: document log resizing
> vhost: add vhost_set_log_base op
> vhost-user: send log shm fd along with log_base
> vhost-user: add a migration blocker
> vhost: use a function for each call
> vhost: only use shared log if in use by backend
> vhost-user: document migration log
> net: add trace_vhost_user_event
> vhost-user-test: move wait_for_fds() out
> vhost-user-test: remove useless static check
> vhost-user-test: wrap server in TestServer struct
> vhost-user-test: learn to tweak various qemu arguments
> vhost-user-test: add live-migration test
> vhost-user-test: check ownership during migration
>
> Michael S. Tsirkin (1):
> vhost-user: unit test for new messages
>
> Thibaut Collet (2):
> vhost user: add support of live migration
> vhost user: add rarp sending after live migration for legacy guest
>
> configure | 19 ++
> docs/specs/vhost-user.txt | 63 ++++-
> hw/net/vhost_net.c | 35 ++-
> hw/scsi/vhost-scsi.c | 7 +-
> hw/virtio/vhost-backend.c | 121 +++++++-
> hw/virtio/vhost-user.c | 571 ++++++++++++++++++++++++--------------
> hw/virtio/vhost.c | 101 ++++---
> include/hw/virtio/vhost-backend.h | 77 ++++-
> include/hw/virtio/vhost.h | 15 +-
> include/net/vhost_net.h | 1 +
> include/qemu/memfd.h | 24 ++
> net/vhost-user.c | 34 ++-
> tests/vhost-user-test.c | 390 ++++++++++++++++++++++----
> trace-events | 3 +
> util/Makefile.objs | 2 +-
> util/memfd.c | 126 +++++++++
> 16 files changed, 1260 insertions(+), 329 deletions(-)
> create mode 100644 include/qemu/memfd.h
> create mode 100644 util/memfd.c
>
> --
> 2.4.3
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend
2015-09-29 14:59 ` Michael S. Tsirkin
@ 2015-09-29 15:26 ` Marc-André Lureau
0 siblings, 0 replies; 35+ messages in thread
From: Marc-André Lureau @ 2015-09-29 15:26 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: haifeng lin, thibaut collet, jasowang, qemu-devel, pbonzini,
marcandre lureau
Hi
----- Original Message -----
> On Thu, Sep 24, 2015 at 06:22:11PM +0200, marcandre.lureau@redhat.com wrote:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Do not allocate a shared log if the backend doesn't support it.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> So squash this in the previous patch introducing the shared log?
> This split makes review harder, not easier.
Ok, I'll try to reorder things
>
> > ---
> > hw/virtio/vhost-user.c | 9 +++++++++
> > hw/virtio/vhost.c | 15 ++++++++++-----
> > include/hw/virtio/vhost-backend.h | 4 ++++
> > 3 files changed, 23 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> > index 41e0364..455caba 100644
> > --- a/hw/virtio/vhost-user.c
> > +++ b/hw/virtio/vhost-user.c
> > @@ -553,6 +553,14 @@ static int vhost_user_get_vq_index(struct vhost_dev
> > *dev, int idx)
> > return idx;
> > }
> >
> > +static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
> > +{
> > + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
> > +
> > + return virtio_has_feature(dev->protocol_features,
> > + VHOST_USER_PROTOCOL_F_LOG_SHMFD);
> > +}
> > +
> > const VhostOps user_ops = {
> > .backend_type = VHOST_BACKEND_TYPE_USER,
> > .vhost_backend_init = vhost_user_init,
> > @@ -573,4 +581,5 @@ const VhostOps user_ops = {
> > .vhost_reset_device = vhost_user_reset_device,
> > .vhost_get_vq_index = vhost_user_get_vq_index,
> > .vhost_set_vring_enable = vhost_user_set_vring_enable,
> > + .vhost_requires_shm_log = vhost_user_requires_shm_log,
> > };
> > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> > index d9f2131..ec27c7b 100644
> > --- a/hw/virtio/vhost.c
> > +++ b/hw/virtio/vhost.c
> > @@ -357,10 +357,15 @@ static void vhost_log_put(struct vhost_dev *dev, bool
> > sync)
> > }
> > }
> >
> > -static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t
> > size)
> > +static bool vhost_dev_log_is_shared(struct vhost_dev *dev)
> > {
> > - bool share = dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER;
> > - struct vhost_log *log = vhost_log_get(size, share);
> > + return dev->vhost_ops->vhost_requires_shm_log &&
> > + dev->vhost_ops->vhost_requires_shm_log(dev);
> > +}
> > +
> > +static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t
> > size)
> > +{
> > + struct vhost_log *log = vhost_log_get(size,
> > vhost_dev_log_is_shared(dev));
> > uint64_t log_base = (uintptr_t)log->log;
> > int r;
> >
> > @@ -1166,10 +1171,10 @@ int vhost_dev_start(struct vhost_dev *hdev,
> > VirtIODevice *vdev)
> >
> > if (hdev->log_enabled) {
> > uint64_t log_base;
> > - bool share = hdev->vhost_ops->backend_type ==
> > VHOST_BACKEND_TYPE_USER;
> >
> > hdev->log_size = vhost_get_log_size(hdev);
> > - hdev->log = vhost_log_get(hdev->log_size, share);
> > + hdev->log = vhost_log_get(hdev->log_size,
> > + vhost_dev_log_is_shared(hdev));
> > log_base = (uintptr_t)hdev->log->log;
> > r = hdev->vhost_ops->vhost_set_log_base(hdev,
> > hdev->log_size ? log_base
> > : 0,
> > diff --git a/include/hw/virtio/vhost-backend.h
> > b/include/hw/virtio/vhost-backend.h
> > index 868a78a..e07118c 100644
> > --- a/include/hw/virtio/vhost-backend.h
> > +++ b/include/hw/virtio/vhost-backend.h
> > @@ -11,6 +11,8 @@
> > #ifndef VHOST_BACKEND_H_
> > #define VHOST_BACKEND_H_
> >
> > +#include <stdbool.h>
> > +
> > typedef enum VhostBackendType {
> > VHOST_BACKEND_TYPE_NONE = 0,
> > VHOST_BACKEND_TYPE_KERNEL = 1,
> > @@ -64,6 +66,7 @@ typedef int (*vhost_reset_device_op)(struct vhost_dev
> > *dev);
> > typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
> > typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
> > int enable);
> > +typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
> >
> > typedef struct VhostOps {
> > VhostBackendType backend_type;
> > @@ -90,6 +93,7 @@ typedef struct VhostOps {
> > vhost_reset_device_op vhost_reset_device;
> > vhost_get_vq_index_op vhost_get_vq_index;
> > vhost_set_vring_enable_op vhost_set_vring_enable;
> > + vhost_requires_shm_log_op vhost_requires_shm_log;
> > } VhostOps;
> >
> > extern const VhostOps user_ops;
> > --
> > 2.4.3
>
^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2015-09-29 15:26 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-24 16:22 [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 01/21] vhost-user: unit test for new messages marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 02/21] configure: probe for memfd marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 03/21] util: add linux-only memfd fallback marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 04/21] util: add memfd helpers marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 05/21] vhost: alloc shareable log marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 06/21] vhost: document log resizing marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 07/21] vhost: add vhost_set_log_base op marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 08/21] vhost-user: send log shm fd along with log_base marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 09/21] vhost-user: add a migration blocker marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 10/21] vhost: use a function for each call marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 11/21] vhost: only use shared log if in use by backend marcandre.lureau
2015-09-29 14:59 ` Michael S. Tsirkin
2015-09-29 15:26 ` Marc-André Lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 12/21] vhost-user: document migration log marcandre.lureau
2015-09-24 16:38 ` Eric Blake
2015-09-24 16:41 ` Marc-André Lureau
2015-09-24 16:47 ` Eric Blake
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 13/21] net: add trace_vhost_user_event marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 14/21] vhost user: add support of live migration marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 15/21] vhost user: add rarp sending after live migration for legacy guest marcandre.lureau
2015-09-24 17:24 ` Thibaut Collet
2015-09-24 21:53 ` Marc-André Lureau
2015-09-27 13:12 ` Michael S. Tsirkin
2015-09-27 15:13 ` Marc-André Lureau
2015-09-27 15:49 ` Thibaut Collet
2015-09-27 18:04 ` Marc-André Lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 16/21] vhost-user-test: move wait_for_fds() out marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 17/21] vhost-user-test: remove useless static check marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 18/21] vhost-user-test: wrap server in TestServer struct marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 19/21] vhost-user-test: learn to tweak various qemu arguments marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 20/21] vhost-user-test: add live-migration test marcandre.lureau
2015-09-24 16:22 ` [Qemu-devel] [PATCH v5 21/21] vhost-user-test: check ownership during migration marcandre.lureau
2015-09-27 13:19 ` [Qemu-devel] [PATCH v5 00/21] vhost-user: add migration support Michael S. Tsirkin
2015-09-29 15:07 ` Michael S. Tsirkin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).