From: "Dr. David Alan Gilbert (git)" <dgilbert@redhat.com>
To: qemu-devel@nongnu.org
Cc: aarcange@redhat.com, yamahata@private.email.ne.jp,
lilei@linux.vnet.ibm.com, quintela@redhat.com
Subject: [Qemu-devel] [PATCH v2 37/43] Postcopy: Use helpers to map pages during migration
Date: Mon, 11 Aug 2014 15:29:53 +0100 [thread overview]
Message-ID: <1407767399-3030-38-git-send-email-dgilbert@redhat.com> (raw)
In-Reply-To: <1407767399-3030-1-git-send-email-dgilbert@redhat.com>
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
In postcopy, the destination guest is running at the same time
as it's receiving pages; as we receive new pages we must put
them into the guests address space atomically to avoid a running
CPU accessing a partially written page.
Use the helpers in postcopy-ram.c to map these pages.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
arch_init.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 84 insertions(+), 9 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index 58eccc1..35afba1 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1328,9 +1328,20 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
return 0;
}
+/*
+ * Read a RAMBlock ID from the stream f, find the host address of the
+ * start of that block and add on 'offset'
+ *
+ * f: Stream to read from
+ * mis: MigrationIncomingState
+ * offset: Offset within the block
+ * flags: Page flags (mostly to see if it's a continuation of previous block)
+ * rb: Pointer to RAMBlock* that gets filled in with the RB we find
+ */
static inline void *host_from_stream_offset(QEMUFile *f,
+ MigrationIncomingState *mis,
ram_addr_t offset,
- int flags)
+ int flags, RAMBlock **rb)
{
static RAMBlock *block = NULL;
char id[256];
@@ -1341,8 +1352,11 @@ static inline void *host_from_stream_offset(QEMUFile *f,
error_report("Ack, bad migration stream!");
return NULL;
}
+ if (rb) {
+ *rb = block;
+ }
- return memory_region_get_ram_ptr(block->mr) + offset;
+ goto gotit;
}
len = qemu_get_byte(f);
@@ -1350,12 +1364,22 @@ static inline void *host_from_stream_offset(QEMUFile *f,
id[len] = 0;
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- if (!strncmp(id, block->idstr, sizeof(id)))
- return memory_region_get_ram_ptr(block->mr) + offset;
+ if (!strncmp(id, block->idstr, sizeof(id))) {
+ if (rb) {
+ *rb = block;
+ }
+ goto gotit;
+ }
}
error_report("Can't find block %s!", id);
return NULL;
+
+gotit:
+ postcopy_hook_early_receive(mis,
+ (offset + (*rb)->offset) >> TARGET_PAGE_BITS);
+ return memory_region_get_ram_ptr(block->mr) + offset;
+
}
/*
@@ -1385,6 +1409,13 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
ram_addr_t addr;
int flags, ret = 0;
static uint64_t seq_iter;
+ /*
+ * System is running in postcopy mode, page inserts to host memory must be
+ * atomic
+ */
+ MigrationIncomingState *mis = migration_incoming_get_current();
+ bool postcopy_running = mis->postcopy_ram_state >=
+ POSTCOPY_RAM_INCOMING_LISTENING;
seq_iter++;
@@ -1439,8 +1470,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
} else if (flags & RAM_SAVE_FLAG_COMPRESS) {
void *host;
uint8_t ch;
+ RAMBlock *rb;
- host = host_from_stream_offset(f, addr, flags);
+ host = host_from_stream_offset(f, mis, addr, flags, &rb);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
@@ -1448,20 +1480,63 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
}
ch = qemu_get_byte(f);
- ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
+ if (!postcopy_running) {
+ ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
+ } else {
+ if (!ch) {
+ ret = postcopy_place_zero_page(mis, host,
+ (addr + rb->offset) >> TARGET_PAGE_BITS);
+ } else {
+ void *tmp;
+ tmp = postcopy_get_tmp_page(mis);
+ if (!tmp) {
+ return -ENOMEM;
+ }
+ memset(tmp, ch, TARGET_PAGE_SIZE);
+ ret = postcopy_place_page(mis, host, tmp,
+ (addr + rb->offset) >> TARGET_PAGE_BITS);
+ }
+ if (ret) {
+ error_report("ram_load: Failure in postcopy compress @"
+ "%zx/%p;%s+%zx",
+ addr, host, rb->idstr, rb->offset);
+ return ret;
+ }
+ }
} else if (flags & RAM_SAVE_FLAG_PAGE) {
void *host;
+ RAMBlock *rb;
- host = host_from_stream_offset(f, addr, flags);
+ host = host_from_stream_offset(f, mis, addr, flags, &rb);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
break;
}
- qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
+ if (!postcopy_running) {
+ qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
+ } else {
+ void *tmp = postcopy_get_tmp_page(mis);
+ if (!tmp) {
+ return -ENOMEM;
+ }
+ qemu_get_buffer(f, tmp, TARGET_PAGE_SIZE);
+ ret = postcopy_place_page(mis, host, tmp,
+ (addr + rb->offset) >> TARGET_PAGE_BITS);
+ if (ret) {
+ error_report("ram_load: Failure in postcopy simple"
+ "@%zx/%p;%s+%zx",
+ addr, host, rb->idstr, rb->offset);
+ return ret;
+ }
+ }
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
- void *host = host_from_stream_offset(f, addr, flags);
+ if (postcopy_running) {
+ error_report("XBZRLE RAM block in postcopy mode @%zx\n", addr);
+ return -EINVAL;
+ }
+ void *host = host_from_stream_offset(f, mis, addr, flags, NULL);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
--
1.9.3
next prev parent reply other threads:[~2014-08-11 14:31 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-11 14:29 [Qemu-devel] [PATCH v2 00/43] Postcopy implementation Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 01/43] qemu_ram_foreach_block: pass up error value, and down the ramblock name Dr. David Alan Gilbert (git)
2014-08-11 18:29 ` Eric Blake
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 02/43] improve DPRINTF macros, add to savevm Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 03/43] Add qemu_get_counted_string to read a string prefixed by a count byte Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 04/43] Create MigrationIncomingState Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 05/43] Return path: Open a return path on QEMUFile for sockets Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 06/43] Return path: socket_writev_buffer: Block even on non-blocking fd's Dr. David Alan Gilbert (git)
2014-08-12 2:13 ` [Qemu-devel] 答复: " chenliang (T)
2014-08-12 9:36 ` [Qemu-devel] ????: [PATCH v2 06/43] Return path: socket_writev_buffer:?Block " Dr. David Alan Gilbert
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 07/43] Migration commands Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 08/43] Return path: Control commands Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 09/43] Return path: Send responses from destination to source Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 10/43] Return path: Source handling of return path Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 11/43] qemu_loadvm errors and debug Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 12/43] ram_debug_dump_bitmap: Dump a migration bitmap as text Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 13/43] Rework loadvm path for subloops Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 14/43] Add migration-capability boolean for postcopy-ram Dr. David Alan Gilbert (git)
2014-08-11 16:47 ` Eric Blake
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 15/43] Add wrappers and handlers for sending/receiving the postcopy-ram migration messages Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 16/43] QEMU_VM_CMD_PACKAGED: Send a packaged chunk of migration stream Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 17/43] migrate_init: Call from savevm Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 18/43] Allow savevm handlers to state whether they could go into postcopy Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 19/43] postcopy: OS support test Dr. David Alan Gilbert (git)
2014-08-12 5:32 ` zhanghailiang
2014-08-12 8:18 ` Dr. David Alan Gilbert
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 20/43] migrate_start_postcopy: Command to trigger transition to postcopy Dr. David Alan Gilbert (git)
2014-08-11 17:01 ` Eric Blake
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 21/43] MIG_STATE_POSTCOPY_ACTIVE: Add new migration state Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 22/43] qemu_savevm_state_complete: Postcopy changes Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 23/43] Postcopy: Maintain sentmap during postcopy pre phase Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 24/43] Postcopy page-map-incoming (PMI) structure Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 25/43] postcopy: Add incoming_init/cleanup functions Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 26/43] postcopy: Incoming initialisation Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 27/43] postcopy: ram_enable_notify to switch on userfault Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 28/43] Postcopy: postcopy_start Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 29/43] Postcopy: Rework migration thread for postcopy mode Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 30/43] mig fd_connect: open return path Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 31/43] Postcopy: Create a fault handler thread before marking the ram as userfault Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 32/43] Page request: Add MIG_RPCOMM_REQPAGES reverse command Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 33/43] Page request: Process incoming page request Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 34/43] Page request: Consume pages off the post-copy queue Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 35/43] Add assertion to check migration_dirty_pages Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 36/43] postcopy_ram.c: place_page and helpers Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` Dr. David Alan Gilbert (git) [this message]
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 38/43] qemu_ram_block_from_host Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 39/43] Postcopy; Handle userfault requests Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 40/43] Start up a postcopy/listener thread ready for incoming page data Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 41/43] postcopy: Wire up loadvm_postcopy_ram_handle_{run, end} commands Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 42/43] End of migration for postcopy Dr. David Alan Gilbert (git)
2014-08-11 14:29 ` [Qemu-devel] [PATCH v2 43/43] Start documenting how postcopy works Dr. David Alan Gilbert (git)
2014-08-11 17:19 ` Eric Blake
2014-08-11 17:58 ` Dr. David Alan Gilbert
2014-08-12 1:50 ` [Qemu-devel] [PATCH v2 00/43] Postcopy implementation zhanghailiang
2014-08-12 9:19 ` Dr. David Alan Gilbert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1407767399-3030-38-git-send-email-dgilbert@redhat.com \
--to=dgilbert@redhat.com \
--cc=aarcange@redhat.com \
--cc=lilei@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=yamahata@private.email.ne.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).