qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@redhat.com>
To: qemu-devel@nongnu.org, anthony@codemonkey.ws
Cc: chrisw@redhat.com, alex.williamson@redhat.com,
	kvm@vger.kernel.org, quintela@redhat.com
Subject: [Qemu-devel] [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name
Date: Tue, 08 Jun 2010 15:11:57 -0600	[thread overview]
Message-ID: <20100608211131.10053.73203.stgit@localhost.localdomain> (raw)
In-Reply-To: <0100608191447.4451.47795.stgit@localhost.localdomain>

Allows us to compress the protocol a bit.

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

 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)) {

       reply	other threads:[~2010-06-08 21:12 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <0100608191447.4451.47795.stgit@localhost.localdomain>
2010-06-08 21:11 ` Alex Williamson [this message]
2010-06-08 21:32   ` [Qemu-devel] Re: [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name Alex Williamson
2010-06-08 22:29     ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100608211131.10053.73203.stgit@localhost.localdomain \
    --to=alex.williamson@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=chrisw@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).