From patchwork Mon Jun 4 09:57:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 162709 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D2097B703D for ; Mon, 4 Jun 2012 20:26:20 +1000 (EST) Received: from localhost ([::1]:38103 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SbU3e-00014x-RZ for incoming@patchwork.ozlabs.org; Mon, 04 Jun 2012 05:58:42 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50958) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SbU2y-0008SU-GB for qemu-devel@nongnu.org; Mon, 04 Jun 2012 05:58:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SbU2o-0004aL-2A for qemu-devel@nongnu.org; Mon, 04 Jun 2012 05:58:00 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:46352) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SbU2n-0004Zr-JP for qemu-devel@nongnu.org; Mon, 04 Jun 2012 05:57:49 -0400 Received: from ps.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with SMTP id B2A894897B; Mon, 4 Jun 2012 18:57:44 +0900 (JST) Received: (nullmailer pid 5095 invoked by uid 1000); Mon, 04 Jun 2012 09:57:44 -0000 From: Isaku Yamahata To: qemu-devel@nongnu.org, kvm@vger.kernel.org Date: Mon, 4 Jun 2012 18:57:08 +0900 Message-Id: X-Mailer: git-send-email 1.7.1.1 In-Reply-To: References: In-Reply-To: References: X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 210.128.90.3 Cc: benoit.hudzia@gmail.com, aarcange@redhat.com, aliguori@us.ibm.com, quintela@redhat.com, stefanha@gmail.com, t.hirofuchi@aist.go.jp, dlaor@redhat.com, satoshi.itoh@aist.go.jp, mdroth@linux.vnet.ibm.com, yoshikawa.takuya@oss.ntt.co.jp, owasserm@redhat.com, avi@redhat.com, pbonzini@redhat.com Subject: [Qemu-devel] [PATCH v2 06/41] arch_init: refactor ram_save_block() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Isaku Yamahata --- Chnages v1 -> v2: - don't refer last_block which can be NULL. And avoid possible infinite loop. --- arch_init.c | 82 +++++++++++++++++++++++++++++++++------------------------- arch_init.h | 1 + 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/arch_init.c b/arch_init.c index 28e5abb..900cc8e 100644 --- a/arch_init.c +++ b/arch_init.c @@ -154,6 +154,44 @@ static int is_dup_page(uint8_t *page) return 1; } +static RAMBlock *last_block_sent = NULL; + +int ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset) +{ + MemoryRegion *mr = block->mr; + uint8_t *p; + int cont; + + if (!memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE, + DIRTY_MEMORY_MIGRATION)) { + return 0; + } + memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE, + DIRTY_MEMORY_MIGRATION); + + cont = (block == last_block_sent) ? RAM_SAVE_FLAG_CONTINUE : 0; + p = memory_region_get_ram_ptr(mr) + offset; + last_block_sent = block; + + if (is_dup_page(p)) { + 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); + return 1; + } + + 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); + return TARGET_PAGE_SIZE; +} + static RAMBlock *last_block; static ram_addr_t last_offset; @@ -162,45 +200,14 @@ int ram_save_block(QEMUFile *f) RAMBlock *block = last_block; ram_addr_t offset = last_offset; int bytes_sent = 0; - MemoryRegion *mr; - if (!block) + if (!block) { block = QLIST_FIRST(&ram_list.blocks); + last_block = block; + } do { - mr = block->mr; - if (memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE, - DIRTY_MEMORY_MIGRATION)) { - uint8_t *p; - int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0; - - memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE, - DIRTY_MEMORY_MIGRATION); - - p = memory_region_get_ram_ptr(mr) + offset; - - if (is_dup_page(p)) { - 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 | 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; - } - - break; - } + bytes_sent = ram_save_page(f, block, offset); offset += TARGET_PAGE_SIZE; if (offset >= block->length) { @@ -209,6 +216,10 @@ int ram_save_block(QEMUFile *f) if (!block) block = QLIST_FIRST(&ram_list.blocks); } + + if (bytes_sent > 0) { + break; + } } while (block != last_block || offset != last_offset); last_block = block; @@ -318,6 +329,7 @@ int ram_save_live(QEMUFile *f, int stage, void *opaque) if (stage == 1) { RAMBlock *block; bytes_transferred = 0; + last_block_sent = NULL; last_block = NULL; last_offset = 0; sort_ram_list(); diff --git a/arch_init.h b/arch_init.h index d84eac7..0a39082 100644 --- a/arch_init.h +++ b/arch_init.h @@ -40,6 +40,7 @@ int xen_available(void); #define RAM_SAVE_VERSION_ID 4 /* currently version 4 */ #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) +int ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset); void *ram_load_host_from_stream_offset(QEMUFile *f, ram_addr_t offset, int flags,