diff mbox

[06/21] arch_init: refactor ram_save_block()

Message ID b05ee55f34834f74c716a72140afcc25f369484c.1325055139.git.yamahata@valinux.co.jp
State New
Headers show

Commit Message

Isaku Yamahata Dec. 29, 2011, 1:25 a.m. UTC
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 arch_init.c |   82 +++++++++++++++++++++++++++++++---------------------------
 arch_init.h |    1 +
 2 files changed, 45 insertions(+), 38 deletions(-)
diff mbox

Patch

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,