[RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name

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

 



Allows us to compress the protocol a bit.

Signed-off-by: Alex Williamson <alex.williamson@xxxxxxxxxx>
---

 arch_init.c |   77 +++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 5780195..8ae6a10 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -87,6 +87,7 @@ const uint32_t arch_type = QEMU_ARCH;
 #define RAM_SAVE_FLAG_MEM_SIZE	0x04
 #define RAM_SAVE_FLAG_PAGE	0x08
 #define RAM_SAVE_FLAG_EOS	0x10
+#define RAM_SAVE_FLAG_CONTINUE	0x20
 
 static int is_dup_page(uint8_t *page, uint8_t ch)
 {
@@ -120,6 +121,7 @@ static int ram_save_block(QEMUFile *f)
     do {
         if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
             uint8_t *p;
+            int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
 
             cpu_physical_memory_reset_dirty(current_addr,
                                             current_addr + TARGET_PAGE_SIZE,
@@ -128,13 +130,17 @@ static int ram_save_block(QEMUFile *f)
             p = block->host + offset;
 
             if (is_dup_page(p, *p)) {
-                qemu_put_be64(f, offset | RAM_SAVE_FLAG_COMPRESS);
-                qemu_put_buffer(f, (uint8_t *)block->name, sizeof(block->name));
+                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS);
+                if (!cont)
+                    qemu_put_buffer(f, (uint8_t *)block->name,
+                                    sizeof(block->name));
                 qemu_put_byte(f, *p);
                 bytes_sent = 1;
             } else {
-                qemu_put_be64(f, offset | RAM_SAVE_FLAG_PAGE);
-                qemu_put_buffer(f, (uint8_t *)block->name, sizeof(block->name));
+                qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
+                if (!cont)
+                    qemu_put_buffer(f, (uint8_t *)block->name,
+                                    sizeof(block->name));
                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
                 bytes_sent = TARGET_PAGE_SIZE;
             }
@@ -284,6 +290,33 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
     return (stage == 2) && (expected_time <= migrate_max_downtime());
 }
 
+static inline void *host_from_stream_offset(QEMUFile *f,
+                                            ram_addr_t offset,
+                                            int flags)
+{
+    static RAMBlock *block = NULL;
+    char name[64];
+
+    if (flags & RAM_SAVE_FLAG_CONTINUE) {
+        if (!block) {
+            fprintf(stderr, "Ack, bad migration stream!\n");
+            return NULL;
+        }
+
+        return block->host + offset;
+    }
+
+    qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
+
+    QLIST_FOREACH(block, &ram.blocks, next) {
+        if (!strncmp(name, block->name, sizeof(name)))
+            return block->host + offset;
+    }
+
+    fprintf(stderr, "Can't find block %s!\n", name);
+    return NULL;
+}
+
 int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
     ram_addr_t addr;
@@ -337,23 +370,11 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
             void *host;
             uint8_t ch;
 
-            if (version_id == 3) {
+            if (version_id == 3)
                 host = qemu_get_ram_ptr(addr);
-            } else {
-                RAMBlock *block;
-                char name[64];
-
-                qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
+            else
+                host = host_from_stream_offset(f, addr, flags);
 
-                QLIST_FOREACH(block, &ram.blocks, next) {
-                    if (!strncmp(name, block->name, sizeof(name)))
-                        break;
-                }
-                if (!block)
-                    return -EINVAL;
-
-                host = block->host + addr;
-            }
             ch = qemu_get_byte(f);
             memset(host, ch, TARGET_PAGE_SIZE);
 #ifndef _WIN32
@@ -365,23 +386,11 @@ int ram_load(QEMUFile *f, void *opaque, int version_id)
         } else if (flags & RAM_SAVE_FLAG_PAGE) {
             void *host;
 
-            if (version_id == 3) {
+            if (version_id == 3)
                 host = qemu_get_ram_ptr(addr);
-            } else {
-                RAMBlock *block;
-                char name[64];
+            else
+                host = host_from_stream_offset(f, addr, flags);
 
-                qemu_get_buffer(f, (uint8_t *)name, sizeof(name));
-
-                QLIST_FOREACH(block, &ram.blocks, next) {
-                    if (!strncmp(name, block->name, sizeof(name)))
-                        break;
-                }
-                if (!block)
-                    return -EINVAL;
-
-                host = block->host + addr;
-            }
             qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
         }
         if (qemu_file_has_error(f)) {

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux