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