[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 14/35] arch_init: refactor ram_save_block() and e
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH v3 14/35] arch_init: refactor ram_save_block() and export ram_save_block() |
Date: |
Tue, 30 Oct 2012 17:32:50 +0900 |
arch_init: factor out counting transferred bytes.
This will be used by postcopy.
Signed-off-by: Isaku Yamahata <address@hidden>
---
Changes v2 -> v3:
- manual rebase
- report ram_save_block
Chnages v1 -> v2:
- don't refer last_block which can be NULL.
And avoid possible infinite loop.
---
arch_init.c | 122 +++++++++++++++++++++++++++++++----------------------------
arch_init.h | 5 +++
migration.h | 1 +
3 files changed, 70 insertions(+), 58 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index 23717d3..ad1b01b 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -399,59 +399,77 @@ static void migration_bitmap_sync(void)
}
}
+static uint64_t bytes_transferred;
+
+/*
+ * ram_save_page: Writes a page of memory to the stream f
+ *
+ * Returns: true: page written
+ * false: no page written
+ */
+static const RAMBlock *last_sent_block = NULL;
+bool ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
+ bool last_stage)
+{
+ MemoryRegion *mr = block->mr;
+ uint8_t *p;
+ int cont;
+ int bytes_sent = -1;
+ ram_addr_t current_addr;
+
+ if (!migration_bitmap_test_and_reset_dirty(mr, offset)) {
+ return false;
+ }
+
+ cont = (block == last_sent_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
+ last_sent_block = block;
+ p = memory_region_get_ram_ptr(mr) + offset;
+ if (is_dup_page(p)) {
+ acct_info.dup_pages++;
+ save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
+ qemu_put_byte(f, *p);
+ bytes_sent = 1;
+ } else if (migrate_use_xbzrle()) {
+ current_addr = block->offset + offset;
+ bytes_sent = save_xbzrle_page(f, p, current_addr, block,
+ offset, cont, last_stage);
+ if (!last_stage) {
+ p = get_cached_data(XBZRLE.cache, current_addr);
+ }
+ }
+
+ /* either we didn't send yet (we may have had XBZRLE overflow) */
+ if (bytes_sent == -1) {
+ save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
+ qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+ bytes_sent = TARGET_PAGE_SIZE;
+ acct_info.norm_pages++;
+ }
+
+ bytes_transferred += bytes_sent;
+ return true;
+}
+
/*
* ram_save_block: Writes a page of memory to the stream f
*
- * Returns: 0: if the page hasn't changed
- * -1: if there are no more dirty pages
- * n: the amount of bytes written in other case
+ * Returns: true: there may be more dirty pages
+ * false: if there are no more dirty pages
*/
-static int ram_save_block(QEMUFile *f, bool last_stage)
+bool ram_save_block(QEMUFile *f, bool last_stage)
{
RAMBlock *block = last_block;
ram_addr_t offset = last_offset;
- int bytes_sent = -1;
- MemoryRegion *mr;
- ram_addr_t current_addr;
+ bool wrote = false;
if (!block)
block = QLIST_FIRST(&ram_list.blocks);
do {
- mr = block->mr;
- if (migration_bitmap_test_and_reset_dirty(mr, offset)) {
- uint8_t *p;
- int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
-
- p = memory_region_get_ram_ptr(mr) + offset;
-
- if (is_dup_page(p)) {
- acct_info.dup_pages++;
- save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
- qemu_put_byte(f, *p);
- bytes_sent = 1;
- } else if (migrate_use_xbzrle()) {
- current_addr = block->offset + offset;
- bytes_sent = save_xbzrle_page(f, p, current_addr, block,
- offset, cont, last_stage);
- if (!last_stage) {
- p = get_cached_data(XBZRLE.cache, current_addr);
- }
- }
-
- /* either we didn't send yet (we may have had XBZRLE overflow) */
- if (bytes_sent == -1) {
- save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
- qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
- bytes_sent = TARGET_PAGE_SIZE;
- acct_info.norm_pages++;
- }
-
- /* if page is unmodified, continue to the next */
- if (bytes_sent != 0) {
- break;
- }
+ wrote = ram_save_page(f, block, offset, last_stage);
+ if (wrote) {
+ break;
}
offset += TARGET_PAGE_SIZE;
@@ -466,11 +484,9 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
last_block = block;
last_offset = offset;
- return bytes_sent;
+ return wrote;
}
-static uint64_t bytes_transferred;
-
static ram_addr_t ram_save_remaining(void)
{
return migration_dirty_pages;
@@ -547,6 +563,7 @@ static void ram_migration_cancel(void *opaque)
static void reset_ram_globals(void)
{
+ last_sent_block = NULL;
last_block = NULL;
last_offset = 0;
last_version = ram_list.version;
@@ -618,14 +635,10 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
i = 0;
while ((ret = qemu_file_rate_limit(f)) == 0) {
- int bytes_sent;
-
- bytes_sent = ram_save_block(f, false);
- /* no more blocks to sent */
- if (bytes_sent < 0) {
+ if (!ram_save_block(f, false)) {
+ /* no more blocks to sent */
break;
}
- bytes_transferred += bytes_sent;
acct_info.iterations++;
/* we want to check in the 1st loop, just in case it was the 1st time
and we had to sync the dirty bitmap.
@@ -683,15 +696,8 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
/* try transferring iterative blocks of memory */
/* flush all remaining blocks regardless of rate limiting */
- while (true) {
- int bytes_sent;
-
- bytes_sent = ram_save_block(f, true);
- /* no more blocks to sent */
- if (bytes_sent < 0) {
- break;
- }
- bytes_transferred += bytes_sent;
+ while (!ram_save_block(f, true)) {
+ /* nothing */
}
memory_global_dirty_log_stop();
diff --git a/arch_init.h b/arch_init.h
index 780eedf..f2a7ae5 100644
--- a/arch_init.h
+++ b/arch_init.h
@@ -46,4 +46,9 @@ CpuDefinitionInfoList GCC_WEAK_DECL
*arch_query_cpu_definitions(Error **errp);
#define RAM_SAVE_VERSION_ID 4 /* currently version 4 */
+#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
+bool ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
+ bool last_stage);
+#endif
+
#endif
diff --git a/migration.h b/migration.h
index 1c3e9b7..7d1b62d 100644
--- a/migration.h
+++ b/migration.h
@@ -91,6 +91,7 @@ bool migration_has_finished(MigrationState *);
bool migration_has_failed(MigrationState *);
MigrationState *migrate_get_current(void);
+bool ram_save_block(QEMUFile *f, bool last_stage);
uint64_t ram_bytes_remaining(void);
uint64_t ram_bytes_transferred(void);
uint64_t ram_bytes_total(void);
--
1.7.10.4
- [Qemu-devel] [PATCH v3 02/35] arch_init: DPRINTF format error and typo, (continued)
- [Qemu-devel] [PATCH v3 02/35] arch_init: DPRINTF format error and typo, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 05/35] protect the ramlist with a separate mutex, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 08/35] savevm/QEMUFile: consolidate QEMUFile functions a bit, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 06/35] osdep: add qemu_read_full() to read interrupt-safely, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 04/35] add a version number to ram_list, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 03/35] split MRU ram list, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 10/35] savevm/QEMUFile: add read/write QEMUFile on memory buffer, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 12/35] arch_init: export RAM_SAVE_xxx flags for postcopy, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 20/35] osdep: add QEMU_MADV_REMOVE and tirivial fix, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 01/35] migration.c: remove redundant line in migrate_init(), Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 14/35] arch_init: refactor ram_save_block() and export ram_save_block(),
Isaku Yamahata <=
- [Qemu-devel] [PATCH v3 11/35] savevm, buffered_file: introduce method to drain buffer of buffered file, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 33/35] arch_init: export migration_bitmap_sync and helper method to get bitmap, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 29/35] postcopy/outgoing: add movebg mode(-m) to migration command, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 24/35] postcopy outgoing: add -p option to migrate command, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 07/35] savevm: export qemu_peek_buffer, qemu_peek_byte, qemu_file_skip, qemu_fflush, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 15/35] arch_init/ram_save_setup: factor out bitmap alloc/free, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 19/35] uvmem.h: import Linux uvmem.h and teach update-linux-headers.sh, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 31/35] arch_init: export ram_save_iterate(), Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 28/35] arch_init: factor out setting last_block, last_offset, Isaku Yamahata, 2012/10/30
- [Qemu-devel] [PATCH v3 17/35] arch_init: factor out logic to find ram block with id string, Isaku Yamahata, 2012/10/30