|
|
9ae3a8 |
From 01eb364d7e367e66572363b4c974b7f3428ea4ca Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
Message-Id: <01eb364d7e367e66572363b4c974b7f3428ea4ca.1387382496.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
In-Reply-To: <c5386144fbf09f628148101bc674e2421cdd16e3.1387382496.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
References: <c5386144fbf09f628148101bc674e2421cdd16e3.1387382496.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
From: Nigel Croxon <ncroxon@redhat.com>
|
|
|
9ae3a8 |
Date: Thu, 14 Nov 2013 22:52:46 +0100
|
|
|
9ae3a8 |
Subject: [PATCH 10/46] rdma: new QEMUFileOps hooks
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Nigel Croxon <ncroxon@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1384469598-13137-11-git-send-email-ncroxon@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 55694
|
|
|
9ae3a8 |
O-Subject: [RHEL7.0 PATCH 10/42] rdma: new QEMUFileOps hooks
|
|
|
9ae3a8 |
Bugzilla: 1011720
|
|
|
9ae3a8 |
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Bugzilla: 1011720
|
|
|
9ae3a8 |
https://bugzilla.redhat.com/show_bug.cgi?id=1011720
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
>From commit ID:
|
|
|
9ae3a8 |
commit 43487c678d6e4e7182bfa70d2bc75422578782aa
|
|
|
9ae3a8 |
Author: Michael R. Hines <mrhines@us.ibm.com>
|
|
|
9ae3a8 |
Date: Tue Jun 25 21:35:35 2013 -0400
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
rdma: new QEMUFileOps hooks
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
These are the prototypes and implementation of new hooks that
|
|
|
9ae3a8 |
RDMA takes advantage of to perform dynamic page registration.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
An optional hook is also introduced for a custom function
|
|
|
9ae3a8 |
to be able to override the default save_page function.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Also included are the prototypes and accessor methods used by
|
|
|
9ae3a8 |
arch_init.c which invoke funtions inside savevm.c to call out
|
|
|
9ae3a8 |
to the hooks that may or may not have been overridden
|
|
|
9ae3a8 |
inside of QEMUFileOps.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Chegu Vinod <chegu_vinod@hp.com>
|
|
|
9ae3a8 |
Tested-by: Chegu Vinod <chegu_vinod@hp.com>
|
|
|
9ae3a8 |
Tested-by: Michael R. Hines <mrhines@us.ibm.com>
|
|
|
9ae3a8 |
Signed-off-by: Michael R. Hines <mrhines@us.ibm.com>
|
|
|
9ae3a8 |
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
include/migration/migration.h | 20 ++++++++++++++
|
|
|
9ae3a8 |
include/migration/qemu-file.h | 29 ++++++++++++++++++++
|
|
|
9ae3a8 |
savevm.c | 59 +++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
3 files changed, 108 insertions(+), 0 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Michal Novotny <minovotn@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
include/migration/migration.h | 20 +++++++++++++++
|
|
|
9ae3a8 |
include/migration/qemu-file.h | 29 +++++++++++++++++++++
|
|
|
9ae3a8 |
savevm.c | 59 +++++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
3 files changed, 108 insertions(+)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/include/migration/migration.h b/include/migration/migration.h
|
|
|
9ae3a8 |
index 201be18..6455e36 100644
|
|
|
9ae3a8 |
--- a/include/migration/migration.h
|
|
|
9ae3a8 |
+++ b/include/migration/migration.h
|
|
|
9ae3a8 |
@@ -21,6 +21,7 @@
|
|
|
9ae3a8 |
#include "qapi/error.h"
|
|
|
9ae3a8 |
#include "migration/vmstate.h"
|
|
|
9ae3a8 |
#include "qapi-types.h"
|
|
|
9ae3a8 |
+#include "exec/cpu-common.h"
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
struct MigrationParams {
|
|
|
9ae3a8 |
bool blk;
|
|
|
9ae3a8 |
@@ -134,4 +135,23 @@ int migrate_use_xbzrle(void);
|
|
|
9ae3a8 |
int64_t migrate_xbzrle_cache_size(void);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
int64_t xbzrle_cache_resize(int64_t new_size);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
|
|
|
9ae3a8 |
+void ram_control_after_iterate(QEMUFile *f, uint64_t flags);
|
|
|
9ae3a8 |
+void ram_control_load_hook(QEMUFile *f, uint64_t flags);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+/* Whenever this is found in the data stream, the flags
|
|
|
9ae3a8 |
+ * will be passed to ram_control_load_hook in the incoming-migration
|
|
|
9ae3a8 |
+ * side. This lets before_ram_iterate/after_ram_iterate add
|
|
|
9ae3a8 |
+ * transport-specific sections to the RAM migration data.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+#define RAM_SAVE_FLAG_HOOK 0x80
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+#define RAM_SAVE_CONTROL_NOT_SUPP -1000
|
|
|
9ae3a8 |
+#define RAM_SAVE_CONTROL_DELAYED -2000
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
|
|
|
9ae3a8 |
+ ram_addr_t offset, size_t size,
|
|
|
9ae3a8 |
+ int *bytes_sent);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
|
|
|
9ae3a8 |
index 37d1604..0f757fb 100644
|
|
|
9ae3a8 |
--- a/include/migration/qemu-file.h
|
|
|
9ae3a8 |
+++ b/include/migration/qemu-file.h
|
|
|
9ae3a8 |
@@ -23,6 +23,7 @@
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
#ifndef QEMU_FILE_H
|
|
|
9ae3a8 |
#define QEMU_FILE_H 1
|
|
|
9ae3a8 |
+#include "exec/cpu-common.h"
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* This function writes a chunk of data to a file at the given position.
|
|
|
9ae3a8 |
* The pos argument can be ignored if the file is only being used for
|
|
|
9ae3a8 |
@@ -57,12 +58,40 @@ typedef int (QEMUFileGetFD)(void *opaque);
|
|
|
9ae3a8 |
typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
|
|
|
9ae3a8 |
int iovcnt, int64_t pos);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+/*
|
|
|
9ae3a8 |
+ * This function provides hooks around different
|
|
|
9ae3a8 |
+ * stages of RAM migration.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+/*
|
|
|
9ae3a8 |
+ * Constants used by ram_control_* hooks
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+#define RAM_CONTROL_SETUP 0
|
|
|
9ae3a8 |
+#define RAM_CONTROL_ROUND 1
|
|
|
9ae3a8 |
+#define RAM_CONTROL_HOOK 2
|
|
|
9ae3a8 |
+#define RAM_CONTROL_FINISH 3
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+/*
|
|
|
9ae3a8 |
+ * This function allows override of where the RAM page
|
|
|
9ae3a8 |
+ * is saved (such as RDMA, for example.)
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
|
|
|
9ae3a8 |
+ ram_addr_t block_offset,
|
|
|
9ae3a8 |
+ ram_addr_t offset,
|
|
|
9ae3a8 |
+ size_t size,
|
|
|
9ae3a8 |
+ int *bytes_sent);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
typedef struct QEMUFileOps {
|
|
|
9ae3a8 |
QEMUFilePutBufferFunc *put_buffer;
|
|
|
9ae3a8 |
QEMUFileGetBufferFunc *get_buffer;
|
|
|
9ae3a8 |
QEMUFileCloseFunc *close;
|
|
|
9ae3a8 |
QEMUFileGetFD *get_fd;
|
|
|
9ae3a8 |
QEMUFileWritevBufferFunc *writev_buffer;
|
|
|
9ae3a8 |
+ QEMURamHookFunc *before_ram_iterate;
|
|
|
9ae3a8 |
+ QEMURamHookFunc *after_ram_iterate;
|
|
|
9ae3a8 |
+ QEMURamHookFunc *hook_ram_load;
|
|
|
9ae3a8 |
+ QEMURamSaveFunc *save_page;
|
|
|
9ae3a8 |
} QEMUFileOps;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
|
|
|
9ae3a8 |
diff --git a/savevm.c b/savevm.c
|
|
|
9ae3a8 |
index 26d5607..e0491e7 100644
|
|
|
9ae3a8 |
--- a/savevm.c
|
|
|
9ae3a8 |
+++ b/savevm.c
|
|
|
9ae3a8 |
@@ -616,6 +616,65 @@ void qemu_fflush(QEMUFile *f)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ int ret = 0;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (f->ops->before_ram_iterate) {
|
|
|
9ae3a8 |
+ ret = f->ops->before_ram_iterate(f, f->opaque, flags);
|
|
|
9ae3a8 |
+ if (ret < 0) {
|
|
|
9ae3a8 |
+ qemu_file_set_error(f, ret);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ int ret = 0;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (f->ops->after_ram_iterate) {
|
|
|
9ae3a8 |
+ ret = f->ops->after_ram_iterate(f, f->opaque, flags);
|
|
|
9ae3a8 |
+ if (ret < 0) {
|
|
|
9ae3a8 |
+ qemu_file_set_error(f, ret);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+void ram_control_load_hook(QEMUFile *f, uint64_t flags)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ int ret = 0;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (f->ops->hook_ram_load) {
|
|
|
9ae3a8 |
+ ret = f->ops->hook_ram_load(f, f->opaque, flags);
|
|
|
9ae3a8 |
+ if (ret < 0) {
|
|
|
9ae3a8 |
+ qemu_file_set_error(f, ret);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ } else {
|
|
|
9ae3a8 |
+ qemu_file_set_error(f, ret);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
|
|
|
9ae3a8 |
+ ram_addr_t offset, size_t size, int *bytes_sent)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ if (f->ops->save_page) {
|
|
|
9ae3a8 |
+ int ret = f->ops->save_page(f, f->opaque, block_offset,
|
|
|
9ae3a8 |
+ offset, size, bytes_sent);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (ret != RAM_SAVE_CONTROL_DELAYED) {
|
|
|
9ae3a8 |
+ if (*bytes_sent > 0) {
|
|
|
9ae3a8 |
+ qemu_update_position(f, *bytes_sent);
|
|
|
9ae3a8 |
+ } else if (ret < 0) {
|
|
|
9ae3a8 |
+ qemu_file_set_error(f, ret);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ return ret;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ return RAM_SAVE_CONTROL_NOT_SUPP;
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
static void qemu_fill_buffer(QEMUFile *f)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
int len;
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.11.7
|
|
|
9ae3a8 |
|