From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=33214 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OM66G-00074a-Sc for qemu-devel@nongnu.org; Tue, 08 Jun 2010 17:12:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OM66E-0004Vf-MV for qemu-devel@nongnu.org; Tue, 08 Jun 2010 17:12:43 -0400 Received: from qmta07.emeryville.ca.mail.comcast.net ([76.96.30.64]:60255) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OM66E-0004Sx-Bj for qemu-devel@nongnu.org; Tue, 08 Jun 2010 17:12:42 -0400 From: Alex Williamson Date: Tue, 08 Jun 2010 15:11:57 -0600 Message-ID: <20100608211131.10053.73203.stgit@localhost.localdomain> In-Reply-To: <0100608191447.4451.47795.stgit@localhost.localdomain> References: <0100608191447.4451.47795.stgit@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, anthony@codemonkey.ws Cc: chrisw@redhat.com, alex.williamson@redhat.com, kvm@vger.kernel.org, quintela@redhat.com Allows us to compress the protocol a bit. Signed-off-by: Alex Williamson --- 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)) {