From: Olaf Hering <olaf@aepfle.de>
To: xen-devel@lists.xenproject.org
Cc: Olaf Hering <olaf@aepfle.de>, Ian Jackson <iwj@xenproject.org>,
Wei Liu <wl@xen.org>, Anthony PERARD <anthony.perard@citrix.com>
Subject: [PATCH v1 23/23] tools/guest: restore: write data directly into guest
Date: Thu, 29 Oct 2020 18:20:03 +0100 [thread overview]
Message-ID: <20201029172004.17219-24-olaf@aepfle.de> (raw)
In-Reply-To: <20201029172004.17219-1-olaf@aepfle.de>
Read incoming migration stream directly into the guest memory.
This avoids the memory allocation and copying, and the resulting
performance penalty.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/libs/guest/xg_sr_common.h | 1 +
tools/libs/guest/xg_sr_restore.c | 132 ++++++++++++++++++++++++++++++-
2 files changed, 129 insertions(+), 4 deletions(-)
diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 7ec8867b88..f76af23bcc 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -231,6 +231,7 @@ struct xc_sr_restore_arrays {
xen_pfn_t mfns[MAX_BATCH_SIZE];
int map_errs[MAX_BATCH_SIZE];
void *guest_data[MAX_BATCH_SIZE];
+ struct iovec iov[MAX_BATCH_SIZE];
/* populate_pfns */
xen_pfn_t pp_mfns[MAX_BATCH_SIZE];
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 060f3d1f4e..2f575d7dd9 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -392,6 +392,122 @@ err:
return rc;
}
+/*
+ * Handle PAGE_DATA record from the stream.
+ * Given a list of pfns, their types, and a block of page data from the
+ * stream, populate and record their types, map the relevant subset and copy
+ * the data into the guest.
+ */
+static int handle_incoming_page_data(struct xc_sr_context *ctx,
+ struct xc_sr_rhdr *rhdr)
+{
+ xc_interface *xch = ctx->xch;
+ struct xc_sr_restore_arrays *m = ctx->restore.m;
+ struct xc_sr_rec_page_data_header *pages = &m->pages;
+ uint64_t *pfn_nums = m->pages.pfn;
+ uint32_t i;
+ int rc, iov_idx;
+
+ rc = handle_static_data_end_v2(ctx);
+ if ( rc )
+ goto err;
+
+ /* First read and verify the header */
+ rc = read_exact(ctx->fd, pages, sizeof(*pages));
+ if ( rc )
+ {
+ PERROR("Could not read rec_pfn header");
+ goto err;
+ }
+
+ if ( verify_rec_page_hdr(ctx, rhdr->length, pages) == false )
+ {
+ rc = -1;
+ goto err;
+ }
+
+ /* Then read and verify the incoming pfn numbers */
+ rc = read_exact(ctx->fd, pfn_nums, sizeof(*pfn_nums) * pages->count);
+ if ( rc )
+ {
+ PERROR("Could not read rec_pfn data");
+ goto err;
+ }
+
+ if ( verify_rec_page_pfns(ctx, rhdr->length, pages) == false )
+ {
+ rc = -1;
+ goto err;
+ }
+
+ /* Finally read and verify the incoming pfn data */
+ rc = map_guest_pages(ctx, pages);
+ if ( rc )
+ goto err;
+
+ /* Prepare read buffers, either guest or throw away memory */
+ for ( i = 0, iov_idx = 0; i < pages->count; i++ )
+ {
+ if ( !m->guest_data[i] )
+ continue;
+
+ m->iov[iov_idx].iov_len = PAGE_SIZE;
+ if ( ctx->restore.verify )
+ m->iov[iov_idx].iov_base = ctx->restore.verify_buf + i * PAGE_SIZE;
+ else
+ m->iov[iov_idx].iov_base = m->guest_data[i];
+ iov_idx++;
+ }
+
+ if ( !iov_idx )
+ goto done;
+
+ rc = readv_exact(ctx->fd, m->iov, iov_idx);
+ if ( rc )
+ {
+ PERROR("read of %d pages failed", iov_idx);
+ goto err;
+ }
+
+ /* Post-processing of pfn data */
+ for ( i = 0, iov_idx = 0; i < pages->count; i++ )
+ {
+ if ( !m->guest_data[i] )
+ continue;
+
+ rc = ctx->restore.ops.localise_page(ctx, m->types[i], m->iov[iov_idx].iov_base);
+ if ( rc )
+ {
+ ERROR("Failed to localise pfn %#"PRIpfn" (type %#"PRIx32")",
+ m->pfns[i], m->types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+ goto err;
+
+ }
+
+ if ( ctx->restore.verify )
+ {
+ if ( memcmp(m->guest_data[i], m->iov[iov_idx].iov_base, PAGE_SIZE) )
+ {
+ ERROR("verify pfn %#"PRIpfn" failed (type %#"PRIx32")",
+ m->pfns[i], m->types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+ }
+ }
+
+ iov_idx++;
+ }
+
+done:
+ rc = 0;
+
+err:
+ if ( ctx->restore.guest_mapping )
+ {
+ xenforeignmemory_unmap(xch->fmem, ctx->restore.guest_mapping, ctx->restore.nr_mapped_pages);
+ ctx->restore.guest_mapping = NULL;
+ }
+ return rc;
+}
+
/*
* Handle PAGE_DATA record from an existing buffer
* Given a list of pfns, their types, and a block of page data from the
@@ -773,11 +889,19 @@ static int process_incoming_record_header(struct xc_sr_context *ctx, struct xc_s
struct xc_sr_record rec;
int rc;
- rc = read_record_data(ctx, ctx->fd, rhdr, &rec);
- if ( rc )
- return rc;
+ switch ( rhdr->type )
+ {
+ case REC_TYPE_PAGE_DATA:
+ rc = handle_incoming_page_data(ctx, rhdr);
+ break;
+ default:
+ rc = read_record_data(ctx, ctx->fd, rhdr, &rec);
+ if ( rc == 0 )
+ rc = process_buffered_record(ctx, &rec);;
+ break;
+ }
- return process_buffered_record(ctx, &rec);
+ return rc;
}
next prev parent reply other threads:[~2020-10-29 17:24 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-29 17:19 [PATCH v1 00/23] reduce overhead during live migration Olaf Hering
2020-10-29 17:19 ` [PATCH v1 01/23] tools: add readv_exact to libxenctrl Olaf Hering
2020-10-29 17:19 ` [PATCH v1 02/23] tools: add xc_is_known_page_type " Olaf Hering
2020-10-29 17:19 ` [PATCH v1 03/23] tools: use xc_is_known_page_type Olaf Hering
2020-10-29 17:19 ` [PATCH v1 04/23] tools: unify type checking for data pfns in migration stream Olaf Hering
2020-10-29 17:19 ` [PATCH v1 05/23] tools: show migration transfer rate in send_dirty_pages Olaf Hering
2020-10-29 17:19 ` [PATCH v1 06/23] tools/guest: prepare to allocate arrays once Olaf Hering
2020-10-29 17:19 ` [PATCH v1 07/23] tools/guest: save: move batch_pfns Olaf Hering
2020-10-29 17:19 ` [PATCH v1 08/23] tools/guest: save: move mfns array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 09/23] tools/guest: save: move types array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 10/23] tools/guest: save: move errors array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 11/23] tools/guest: save: move iov array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 12/23] tools/guest: save: move rec_pfns array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 13/23] tools/guest: save: move guest_data array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 14/23] tools/guest: save: move local_pages array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 15/23] tools/guest: restore: move pfns array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 16/23] tools/guest: restore: move types array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 17/23] tools/guest: restore: move mfns array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 18/23] tools/guest: restore: move map_errs array Olaf Hering
2020-10-29 17:19 ` [PATCH v1 19/23] tools/guest: restore: move mfns array in populate_pfns Olaf Hering
2020-10-29 17:20 ` [PATCH v1 20/23] tools/guest: restore: move pfns " Olaf Hering
2020-10-29 17:20 ` [PATCH v1 21/23] tools/guest: restore: split record processing Olaf Hering
2020-10-29 17:20 ` [PATCH v1 22/23] tools/guest: restore: split handle_page_data Olaf Hering
2020-10-29 17:20 ` Olaf Hering [this message]
2020-11-23 16:00 ` [PATCH v1 00/23] reduce overhead during live migration Olaf Hering
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=20201029172004.17219-24-olaf@aepfle.de \
--to=olaf@aepfle.de \
--cc=anthony.perard@citrix.com \
--cc=iwj@xenproject.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.