aboutsummaryrefslogtreecommitdiff
path: root/arch_init.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2010-11-22 19:52:34 +0200
committerMichael S. Tsirkin <mst@redhat.com>2010-12-02 21:13:39 +0200
commitb2e0a138e77245290428a7d599a929e2e1bfe510 (patch)
tree5c483ccf4927fbdd9a1000695a36658574d8f542 /arch_init.c
parentc924f36a300cbc54d3cb511116e8e2bae17f5ae6 (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.c35
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) {