From mboxrd@z Thu Jan 1 00:00:00 1970 From: Isaku Yamahata Subject: [PATCH 06/21] arch_init: refactor ram_save_block() Date: Thu, 29 Dec 2011 10:25:45 +0900 Message-ID: References: Cc: yamahata@valinux.co.jp, t.hirofuchi@aist.go.jp, satoshi.itoh@aist.go.jp To: kvm@vger.kernel.org, qemu-devel@nongnu.org Return-path: Received: from mail.valinux.co.jp ([210.128.90.3]:47815 "EHLO mail.valinux.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754689Ab1L2B0D (ORCPT ); Wed, 28 Dec 2011 20:26:03 -0500 In-Reply-To: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org List-ID: Signed-off-by: Isaku Yamahata --- arch_init.c | 82 +++++++++++++++++++++++++++++++--------------------------- arch_init.h | 1 + 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/arch_init.c b/arch_init.c index 9bc313e..982c846 100644 --- a/arch_init.c +++ b/arch_init.c @@ -102,6 +102,44 @@ static int is_dup_page(uint8_t *page, uint8_t ch) return 1; } +static RAMBlock *last_block_sent = NULL; + +int ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset) +{ + ram_addr_t current_addr = block->offset + offset; + uint8_t *p; + int cont; + + if (!cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { + return 0; + } + cpu_physical_memory_reset_dirty(current_addr, + current_addr + TARGET_PAGE_SIZE, + MIGRATION_DIRTY_FLAG); + + p = block->host + offset; + cont = (block == last_block_sent) ? RAM_SAVE_FLAG_CONTINUE : 0; + last_block_sent = block; + + if (is_dup_page(p, *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; @@ -109,47 +147,13 @@ int ram_save_block(QEMUFile *f) { RAMBlock *block = last_block; ram_addr_t offset = last_offset; - ram_addr_t current_addr; int bytes_sent = 0; if (!block) block = QLIST_FIRST(&ram_list.blocks); - current_addr = block->offset + offset; - 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, - MIGRATION_DIRTY_FLAG); - - p = block->host + offset; - - if (is_dup_page(p, *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) { @@ -159,9 +163,10 @@ int ram_save_block(QEMUFile *f) block = QLIST_FIRST(&ram_list.blocks); } - current_addr = block->offset + offset; - - } while (current_addr != last_block->offset + last_offset); + if (bytes_sent > 0) { + break; + } + } while (block->offset + offset != last_block->offset + last_offset); last_block = block; last_offset = offset; @@ -277,6 +282,7 @@ int ram_save_live(Monitor *mon, 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 14d6644..118461a 100644 --- a/arch_init.h +++ b/arch_init.h @@ -44,6 +44,7 @@ int xen_available(void); #define RAM_SAVE_VERSION_ID 4 /* currently version 4 */ #ifdef NEED_CPU_H +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, -- 1.7.1.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:33858) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rg4l4-00058T-1P for qemu-devel@nongnu.org; Wed, 28 Dec 2011 20:26:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rg4l0-0004JR-0c for qemu-devel@nongnu.org; Wed, 28 Dec 2011 20:26:13 -0500 Received: from mail.valinux.co.jp ([210.128.90.3]:42978) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rg4kz-0004I9-DC for qemu-devel@nongnu.org; Wed, 28 Dec 2011 20:26:09 -0500 From: Isaku Yamahata Date: Thu, 29 Dec 2011 10:25:45 +0900 Message-Id: In-Reply-To: References: In-Reply-To: References: Subject: [Qemu-devel] [PATCH 06/21] arch_init: refactor ram_save_block() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: kvm@vger.kernel.org, qemu-devel@nongnu.org Cc: yamahata@valinux.co.jp, t.hirofuchi@aist.go.jp, satoshi.itoh@aist.go.jp Signed-off-by: Isaku Yamahata --- arch_init.c | 82 +++++++++++++++++++++++++++++++--------------------------- arch_init.h | 1 + 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/arch_init.c b/arch_init.c index 9bc313e..982c846 100644 --- a/arch_init.c +++ b/arch_init.c @@ -102,6 +102,44 @@ static int is_dup_page(uint8_t *page, uint8_t ch) return 1; } +static RAMBlock *last_block_sent = NULL; + +int ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset) +{ + ram_addr_t current_addr = block->offset + offset; + uint8_t *p; + int cont; + + if (!cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { + return 0; + } + cpu_physical_memory_reset_dirty(current_addr, + current_addr + TARGET_PAGE_SIZE, + MIGRATION_DIRTY_FLAG); + + p = block->host + offset; + cont = (block == last_block_sent) ? RAM_SAVE_FLAG_CONTINUE : 0; + last_block_sent = block; + + if (is_dup_page(p, *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; @@ -109,47 +147,13 @@ int ram_save_block(QEMUFile *f) { RAMBlock *block = last_block; ram_addr_t offset = last_offset; - ram_addr_t current_addr; int bytes_sent = 0; if (!block) block = QLIST_FIRST(&ram_list.blocks); - current_addr = block->offset + offset; - 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, - MIGRATION_DIRTY_FLAG); - - p = block->host + offset; - - if (is_dup_page(p, *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) { @@ -159,9 +163,10 @@ int ram_save_block(QEMUFile *f) block = QLIST_FIRST(&ram_list.blocks); } - current_addr = block->offset + offset; - - } while (current_addr != last_block->offset + last_offset); + if (bytes_sent > 0) { + break; + } + } while (block->offset + offset != last_block->offset + last_offset); last_block = block; last_offset = offset; @@ -277,6 +282,7 @@ int ram_save_live(Monitor *mon, 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 14d6644..118461a 100644 --- a/arch_init.h +++ b/arch_init.h @@ -44,6 +44,7 @@ int xen_available(void); #define RAM_SAVE_VERSION_ID 4 /* currently version 4 */ #ifdef NEED_CPU_H +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, -- 1.7.1.1