@@ -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();
@@ -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,
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- arch_init.c | 82 +++++++++++++++++++++++++++++++--------------------------- arch_init.h | 1 + 2 files changed, 45 insertions(+), 38 deletions(-)