From 75d4a9d5e1919b8276b3b7b4a9b80abcdb127be2 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 6 Jul 2010 22:28:57 -0300 Subject: [PATCH 14/24] savevm: Create a new continue flag to avoid resending block name RH-Author: Alex Williamson Message-id: <20100706222857.1033.7384.stgit@localhost.localdomain> Patchwork-id: 10517 O-Subject: [RHEL6.0 qemu-kvm PATCH 14/17] savevm: Create a new continue flag to avoid resending block name Bugzilla: 596328 RH-Acked-by: Juan Quintela RH-Acked-by: Amit Shah RH-Acked-by: Jes Sorensen Bugzilla: 596328 Upstream commit: a55bbe31873a5014fa6457c936858f11e2d22b32 Allows us to compress the protocol a bit by setting a flag on the offset which indicates we're still working within the same block as last time. That way we can avoid sending the block name for every page. Suggested by Anthony Liguori. Signed-off-by: Alex Williamson Signed-off-by: Anthony Liguori --- vl.c | 94 +++++++++++++++++++++++++++++++++++------------------------------- 1 files changed, 50 insertions(+), 44 deletions(-) Signed-off-by: Eduardo Habkost --- vl.c | 94 +++++++++++++++++++++++++++++++++++------------------------------- 1 files changed, 50 insertions(+), 44 deletions(-) diff --git a/vl.c b/vl.c index 4e6f293..571c306 100644 --- a/vl.c +++ b/vl.c @@ -3030,6 +3030,7 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) #define RAM_SAVE_FLAG_MEM_SIZE 0x04 #define RAM_SAVE_FLAG_PAGE 0x08 #define RAM_SAVE_FLAG_EOS 0x10 +#define RAM_SAVE_FLAG_CONTINUE 0x20 static int is_dup_page(uint8_t *page, uint8_t ch) { @@ -3071,6 +3072,7 @@ static int ram_save_block(QEMUFile *f) } 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, @@ -3079,16 +3081,20 @@ static int ram_save_block(QEMUFile *f) p = block->host + offset; if (is_dup_page(p, *p)) { - qemu_put_be64(f, offset | RAM_SAVE_FLAG_COMPRESS); - qemu_put_byte(f, strlen(block->idstr)); - qemu_put_buffer(f, (uint8_t *)block->idstr, - strlen(block->idstr)); + 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); } else { - qemu_put_be64(f, offset | RAM_SAVE_FLAG_PAGE); - qemu_put_byte(f, strlen(block->idstr)); - qemu_put_buffer(f, (uint8_t *)block->idstr, - strlen(block->idstr)); + 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); } @@ -3233,6 +3239,36 @@ static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) return (stage == 2) && (expected_time <= migrate_max_downtime()); } +static inline void *host_from_stream_offset(QEMUFile *f, + ram_addr_t offset, + int flags) +{ + static RAMBlock *block = NULL; + char id[256]; + uint8_t len; + + if (flags & RAM_SAVE_FLAG_CONTINUE) { + if (!block) { + fprintf(stderr, "Ack, bad migration stream!\n"); + return NULL; + } + + return block->host + offset; + } + + len = qemu_get_byte(f); + qemu_get_buffer(f, (uint8_t *)id, len); + id[len] = 0; + + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (!strncmp(id, block->idstr, sizeof(id))) + return block->host + offset; + } + + fprintf(stderr, "Can't find block %s!\n", id); + return NULL; +} + static int ram_load(QEMUFile *f, void *opaque, int version_id) { ram_addr_t addr; @@ -3289,26 +3325,11 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) void *host; uint8_t ch; - if (version_id == 3) { + if (version_id == 3) host = qemu_get_ram_ptr(addr); - } else { - RAMBlock *block; - char id[256]; - uint8_t len; - - len = qemu_get_byte(f); - qemu_get_buffer(f, (uint8_t *)id, len); - id[len] = 0; - - QLIST_FOREACH(block, &ram_list.blocks, next) { - if (!strncmp(id, block->idstr, sizeof(id))) - break; - } - if (!block) - return -EINVAL; + else + host = host_from_stream_offset(f, addr, flags); - host = block->host + addr; - } ch = qemu_get_byte(f); memset(host, ch, TARGET_PAGE_SIZE); #ifndef _WIN32 @@ -3320,26 +3341,11 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } else if (flags & RAM_SAVE_FLAG_PAGE) { void *host; - if (version_id == 3) { + if (version_id == 3) host = qemu_get_ram_ptr(addr); - } else { - RAMBlock *block; - char id[256]; - uint8_t len; - - len = qemu_get_byte(f); - qemu_get_buffer(f, (uint8_t *)id, len); - id[len] = 0; - - QLIST_FOREACH(block, &ram_list.blocks, next) { - if (!strncmp(id, block->idstr, sizeof(id))) - break; - } - if (!block) - return -EINVAL; + else + host = host_from_stream_offset(f, addr, flags); - host = block->host + addr; - } qemu_get_buffer(f, host, TARGET_PAGE_SIZE); } if (qemu_file_has_error(f)) { -- 1.7.0.3