From patchwork Tue Jun 8 21:11:57 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 105043 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o58LI8N3025660 for ; Tue, 8 Jun 2010 21:18:08 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756217Ab0FHVSF (ORCPT ); Tue, 8 Jun 2010 17:18:05 -0400 Received: from qmta15.emeryville.ca.mail.comcast.net ([76.96.27.228]:47013 "EHLO qmta15.emeryville.ca.mail.comcast.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750925Ab0FHVSE (ORCPT ); Tue, 8 Jun 2010 17:18:04 -0400 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 08 Jun 2010 21:18:08 +0000 (UTC) X-Greylist: delayed 349 seconds by postgrey-1.27 at vger.kernel.org; Tue, 08 Jun 2010 17:18:04 EDT Received: from omta12.emeryville.ca.mail.comcast.net ([76.96.30.44]) by qmta15.emeryville.ca.mail.comcast.net with comcast id TQLP1e0010x6nqcAFZCEVs; Tue, 08 Jun 2010 21:12:14 +0000 Received: from localhost.localdomain ([75.71.122.219]) by omta12.emeryville.ca.mail.comcast.net with comcast id TZCD1e0014k7Kz78YZCDlW; Tue, 08 Jun 2010 21:12:14 +0000 From: Alex Williamson Subject: [RFC PATCH 7/6] savevm: Create a new continue flag to avoid resending block name To: qemu-devel@nongnu.org, anthony@codemonkey.ws Cc: kvm@vger.kernel.org, quintela@redhat.com, chrisw@redhat.com, alex.williamson@redhat.com 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> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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)) {