summaryrefslogtreecommitdiff
path: root/migration/ram.c
diff options
context:
space:
mode:
authorAlexey Perevalov <a.perevalov@samsung.com>2017-10-05 14:13:20 +0300
committerJuan Quintela <quintela@redhat.com>2017-10-23 18:03:41 +0200
commitf9494614898f46e59bc2243de6fb11ebbfc9cda6 (patch)
tree4bca843ea17e88237db53722a1f7792bd527257d /migration/ram.c
parent727b9d7e4926755e14d9ac2b09777c51cccb9b80 (diff)
downloadqemu-f9494614898f46e59bc2243de6fb11ebbfc9cda6.tar.gz
migration: add bitmap for received page
This patch adds ability to track down already received pages, it's necessary for calculation vCPU block time in postcopy migration feature, and for recovery after postcopy migration failure. Also it's necessary to solve shared memory issue in postcopy livemigration. Information about received pages will be transferred to the software virtual bridge (e.g. OVS-VSWITCHD), to avoid fallocate (unmap) for already received pages. fallocate syscall is required for remmaped shared memory, due to remmaping itself blocks ioctl(UFFDIO_COPY, ioctl in this case will end with EEXIT error (struct page is exists after remmap). Bitmap is placed into RAMBlock as another postcopy/precopy related bitmaps. Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Alexey Perevalov <a.perevalov@samsung.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
Diffstat (limited to 'migration/ram.c')
-rw-r--r--migration/ram.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/migration/ram.c b/migration/ram.c
index bd4fc5ceb4..7f6327f708 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -45,6 +45,7 @@
#include "qapi/qmp/qerror.h"
#include "trace.h"
#include "exec/ram_addr.h"
+#include "exec/target_page.h"
#include "qemu/rcu_queue.h"
#include "migration/colo.h"
#include "migration/block.h"
@@ -158,6 +159,35 @@ out:
return ret;
}
+static void ramblock_recv_map_init(void)
+{
+ RAMBlock *rb;
+
+ RAMBLOCK_FOREACH(rb) {
+ assert(!rb->receivedmap);
+ rb->receivedmap = bitmap_new(rb->max_length >> qemu_target_page_bits());
+ }
+}
+
+int ramblock_recv_bitmap_test(RAMBlock *rb, void *host_addr)
+{
+ return test_bit(ramblock_recv_bitmap_offset(host_addr, rb),
+ rb->receivedmap);
+}
+
+void ramblock_recv_bitmap_set(RAMBlock *rb, void *host_addr)
+{
+ set_bit_atomic(ramblock_recv_bitmap_offset(host_addr, rb), rb->receivedmap);
+}
+
+void ramblock_recv_bitmap_set_range(RAMBlock *rb, void *host_addr,
+ size_t nr)
+{
+ bitmap_set_atomic(rb->receivedmap,
+ ramblock_recv_bitmap_offset(host_addr, rb),
+ nr);
+}
+
/*
* An outstanding page request, on the source, having been received
* and queued
@@ -2021,6 +2051,8 @@ int ram_discard_range(const char *rbname, uint64_t start, size_t length)
goto err;
}
+ bitmap_clear(rb->receivedmap, start >> qemu_target_page_bits(),
+ length >> qemu_target_page_bits());
ret = ram_block_discard_range(rb, start, length);
err:
@@ -2607,13 +2639,20 @@ static int ram_load_setup(QEMUFile *f, void *opaque)
{
xbzrle_load_setup();
compress_threads_load_setup();
+ ramblock_recv_map_init();
return 0;
}
static int ram_load_cleanup(void *opaque)
{
+ RAMBlock *rb;
xbzrle_load_cleanup();
compress_threads_load_cleanup();
+
+ RAMBLOCK_FOREACH(rb) {
+ g_free(rb->receivedmap);
+ rb->receivedmap = NULL;
+ }
return 0;
}
@@ -2828,6 +2867,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
ret = -EINVAL;
break;
}
+ ramblock_recv_bitmap_set(block, host);
trace_ram_load_loop(block->idstr, (uint64_t)addr, flags, host);
}