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