From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=33026 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ORfWf-0002z2-75 for qemu-devel@nongnu.org; Thu, 24 Jun 2010 02:03:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1ORfLI-0001gd-JN for qemu-devel@nongnu.org; Thu, 24 Jun 2010 01:51:18 -0400 Received: from mail-fx0-f45.google.com ([209.85.161.45]:39616) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1ORfLI-0001gR-BA for qemu-devel@nongnu.org; Thu, 24 Jun 2010 01:51:16 -0400 Received: by fxm9 with SMTP id 9so4164236fxm.4 for ; Wed, 23 Jun 2010 22:51:15 -0700 (PDT) Sender: Paolo Bonzini Message-ID: <4C22F250.2080508@redhat.com> Date: Thu, 24 Jun 2010 07:51:12 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: <20100624044046.16168.32804.stgit@localhost.localdomain> <20100624044215.16168.51019.stgit@localhost.localdomain> In-Reply-To: <20100624044215.16168.51019.stgit@localhost.localdomain> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH 12/15] 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: Alex Williamson Cc: jan.kiszka@siemens.com, qemu-devel@nongnu.org, armbru@redhat.com, paul@codesourcery.com, cam@cs.ualberta.ca, kraxel@redhat.com On 06/24/2010 06:42 AM, Alex Williamson wrote: > Allows us to compress the protocol a bit by setting a flag on the > offset which indicates we're still working within the same block > as last time. That way we can avoid sending the block name for > every page. Suggested by Anthony Liguori. > > Signed-off-by: Alex Williamson > --- > > arch_init.c | 94 +++++++++++++++++++++++++++++++---------------------------- > 1 files changed, 50 insertions(+), 44 deletions(-) > > diff --git a/arch_init.c b/arch_init.c > index 186645b..2f082f3 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,17 +130,21 @@ 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_byte(f, strlen(block->idstr)); > - qemu_put_buffer(f, (uint8_t *)block->idstr, > - strlen(block->idstr)); > + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS); > + if (!cont) { > + qemu_put_byte(f, strlen(block->idstr)); > + qemu_put_buffer(f, (uint8_t *)block->idstr, > + strlen(block->idstr)); > + } > qemu_put_byte(f, *p); > bytes_sent = 1; > } else { > - qemu_put_be64(f, offset | RAM_SAVE_FLAG_PAGE); > - qemu_put_byte(f, strlen(block->idstr)); > - qemu_put_buffer(f, (uint8_t *)block->idstr, > - strlen(block->idstr)); > + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE); > + if (!cont) { > + qemu_put_byte(f, strlen(block->idstr)); > + qemu_put_buffer(f, (uint8_t *)block->idstr, > + strlen(block->idstr)); > + } > qemu_put_buffer(f, p, TARGET_PAGE_SIZE); > bytes_sent = TARGET_PAGE_SIZE; > } > @@ -289,6 +295,36 @@ 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 id[256]; > + uint8_t len; > + > + if (flags& RAM_SAVE_FLAG_CONTINUE) { > + if (!block) { > + fprintf(stderr, "Ack, bad migration stream!\n"); > + return NULL; > + } > + > + return block->host + offset; > + } > + > + len = qemu_get_byte(f); > + qemu_get_buffer(f, (uint8_t *)id, len); > + id[len] = 0; > + > + QLIST_FOREACH(block,&ram_list.blocks, next) { > + if (!strncmp(id, block->idstr, sizeof(id))) > + return block->host + offset; > + } > + > + fprintf(stderr, "Can't find block %s!\n", id); > + return NULL; > +} > + > int ram_load(QEMUFile *f, void *opaque, int version_id) > { > ram_addr_t addr; > @@ -346,26 +382,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 id[256]; > - uint8_t len; > - > - len = qemu_get_byte(f); > - qemu_get_buffer(f, (uint8_t *)id, len); > - id[len] = 0; > + else > + host = host_from_stream_offset(f, addr, flags); > > - QLIST_FOREACH(block,&ram_list.blocks, next) { > - if (!strncmp(id, block->idstr, sizeof(id))) > - break; > - } > - if (!block) > - return -EINVAL; > - > - host = block->host + addr; > - } > ch = qemu_get_byte(f); > memset(host, ch, TARGET_PAGE_SIZE); > #ifndef _WIN32 > @@ -377,26 +398,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 id[256]; > - uint8_t len; > + else > + host = host_from_stream_offset(f, addr, flags); > > - len = qemu_get_byte(f); > - qemu_get_buffer(f, (uint8_t *)id, len); > - id[len] = 0; > - > - QLIST_FOREACH(block,&ram_list.blocks, next) { > - if (!strncmp(id, block->idstr, sizeof(id))) > - break; > - } > - if (!block) > - return -EINVAL; > - > - host = block->host + addr; > - } > qemu_get_buffer(f, host, TARGET_PAGE_SIZE); > } > if (qemu_file_has_error(f)) { Gah, sorry. :) This also takes care of the code duplication, great. Paolo