diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2010-11-22 19:52:34 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2010-12-02 21:13:39 +0200 |
commit | b2e0a138e77245290428a7d599a929e2e1bfe510 (patch) | |
tree | 5c483ccf4927fbdd9a1000695a36658574d8f542 /arch_init.c | |
parent | c924f36a300cbc54d3cb511116e8e2bae17f5ae6 (diff) |
migration: stable ram block ordering
This makes ram block ordering under migration stable, ordered by offset.
This is especially useful for migration to exec, for debugging.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'arch_init.c')
-rw-r--r-- | arch_init.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/arch_init.c b/arch_init.c index 44869255ef..e32e289c8f 100644 --- a/arch_init.c +++ b/arch_init.c @@ -23,6 +23,7 @@ */ #include <stdint.h> #include <stdarg.h> +#include <stdlib.h> #ifndef _WIN32 #include <sys/types.h> #include <sys/mman.h> @@ -212,6 +213,39 @@ uint64_t ram_bytes_total(void) return total; } +static int block_compar(const void *a, const void *b) +{ + RAMBlock * const *ablock = a; + RAMBlock * const *bblock = b; + if ((*ablock)->offset < (*bblock)->offset) { + return -1; + } else if ((*ablock)->offset > (*bblock)->offset) { + return 1; + } + return 0; +} + +static void sort_ram_list(void) +{ + RAMBlock *block, *nblock, **blocks; + int n; + n = 0; + QLIST_FOREACH(block, &ram_list.blocks, next) { + ++n; + } + blocks = qemu_malloc(n * sizeof *blocks); + n = 0; + QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) { + blocks[n++] = block; + QLIST_REMOVE(block, next); + } + qsort(blocks, n, sizeof *blocks, block_compar); + while (--n >= 0) { + QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next); + } + qemu_free(blocks); +} + int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) { ram_addr_t addr; @@ -234,6 +268,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred = 0; last_block = NULL; last_offset = 0; + sort_ram_list(); /* Make sure all dirty bits are set */ QLIST_FOREACH(block, &ram_list.blocks, next) { |