[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 06/41] arch_init: refactor ram_save_block()
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH v2 06/41] arch_init: refactor ram_save_block() |
Date: |
Mon, 4 Jun 2012 18:57:08 +0900 |
Signed-off-by: Isaku Yamahata <address@hidden>
---
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,
--
1.7.1.1
- [Qemu-devel] [PATCH v2 00/41] postcopy live migration, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 16/41] savevm: qemu_pending_size() to return pending buffered size, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 04/41] arch_init: refactor host_from_stream_offset(), Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 06/41] arch_init: refactor ram_save_block(),
Isaku Yamahata <=
- [Qemu-devel] [PATCH v2 03/41] arch_init/ram_save: introduce constant for ram save version = 4, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 17/41] savevm, buffered_file: introduce method to drain buffer of buffered file, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 20/41] savevm/QEMUFileSocket: drop duplicated member fd, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 01/41] arch_init: export sort_ram_list() and ram_save_block(), Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 18/41] QEMUFile: add qemu_file_fd() for later use, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 24/41] migration: export migrate_fd_completed() and migrate_fd_cleanup(), Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 05/41] arch_init/ram_save_live: factor out RAM_SAVE_FLAG_MEM_SIZE case, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 31/41] configure: add CONFIG_POSTCOPY option, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 22/41] savevm/QEMUFile: introduce qemu_fopen_fd, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 09/41] arch_init: introduce helper function to find ram block with id string, Isaku Yamahata, 2012/06/04