|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v2 23/23] libxc/xc_sr_restore.c: use populate_evicted()
From: Joshua Otto <jtotto@xxxxxxxxxxxx>
During the transition downtime phase of postcopy live migration, mark
batches of dirty pfns as paged-out using the new populate_evicted()
paging op rather than populating, nominating and evicting each dirty pfn
individually. This significantly reduces downtime during transitions
with many dirty pfns.
Signed-off-by: Joshua Otto <jtotto@xxxxxxxxxxxx>
---
tools/libxc/xc_sr_restore.c | 71 +++++++++++++++++++++++++++++----------------
1 file changed, 46 insertions(+), 25 deletions(-)
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 3aac0f0..950bbf0 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -672,13 +672,15 @@ static int process_postcopy_pfns(struct xc_sr_context
*ctx, unsigned int count,
xc_interface *xch = ctx->xch;
struct xc_sr_restore_paging *paging = &ctx->restore.paging;
int rc;
- unsigned int i;
+ unsigned int i, nr_bpfns = 0, nr_xapfns = 0;
xen_pfn_t bpfn;
+ xen_pfn_t *bpfns = malloc(count * sizeof(*bpfns)),
+ *xapfns = malloc(count * sizeof(*xapfns));
- rc = populate_pfns(ctx, count, pfns, types);
- if ( rc )
+ if ( !bpfns || !xapfns )
{
- ERROR("Failed to populate pfns for batch of %u pages", count);
+ rc = -1;
+ ERROR("Failed to allocate %zu bytes pfns", 2 * count * sizeof(*bpfns));
goto out;
}
@@ -686,7 +688,7 @@ static int process_postcopy_pfns(struct xc_sr_context *ctx,
unsigned int count,
{
if ( types[i] < XEN_DOMCTL_PFINFO_BROKEN )
{
- bpfn = pfns[i];
+ bpfn = bpfns[nr_bpfns++] = pfns[i];
/* We should never see the same pfn twice at this stage. */
if ( !postcopy_pfn_invalid(ctx, bpfn) )
@@ -695,6 +697,42 @@ static int process_postcopy_pfns(struct xc_sr_context
*ctx, unsigned int count,
ERROR("Duplicate postcopy pfn %"PRI_xen_pfn, bpfn);
goto out;
}
+ }
+ else if ( types[i] == XEN_DOMCTL_PFINFO_XALLOC )
+ {
+ xapfns[nr_xapfns++] = pfns[i];
+ }
+ }
+
+ /* Follow the normal path to populate XALLOC pfns... */
+ rc = populate_pfns(ctx, nr_xapfns, xapfns, NULL);
+ if ( rc )
+ {
+ ERROR("Failed to populate pfns for batch of %u pages", nr_xapfns);
+ goto out;
+ }
+
+ /* ... and 'populate' the backed pfns directly into the evicted state. */
+ if ( nr_bpfns )
+ {
+ rc = xc_mem_paging_populate_evicted(xch, ctx->domid, bpfns, nr_bpfns);
+ if ( rc )
+ {
+ ERROR("Failed to evict batch of %u pfns", nr_bpfns);
+ goto out;
+ }
+
+ for ( i = 0; i < nr_bpfns; ++i )
+ {
+ bpfn = bpfns[i];
+
+ /* If it hasn't yet been populated, mark it as so now. */
+ if ( !pfn_is_populated(ctx, bpfn) )
+ {
+ rc = pfn_set_populated(ctx, bpfn);
+ if ( rc )
+ goto out;
+ }
/*
* We now consider this pfn 'outstanding' - pending, and not yet
@@ -702,32 +740,15 @@ static int process_postcopy_pfns(struct xc_sr_context
*ctx, unsigned int count,
*/
mark_postcopy_pfn_outstanding(ctx, bpfn);
++paging->nr_pending_pfns;
-
- /*
- * Neither nomination nor eviction can be permitted to fail - the
- * guest isn't yet running, so a failure would imply a foreign or
- * hypervisor mapping on the page, and that would be bogus because
- * the migration isn't yet complete.
- */
- rc = xc_mem_paging_nominate(xch, ctx->domid, bpfn);
- if ( rc < 0 )
- {
- PERROR("Error nominating postcopy pfn %"PRI_xen_pfn, bpfn);
- goto out;
- }
-
- rc = xc_mem_paging_evict(xch, ctx->domid, bpfn);
- if ( rc < 0 )
- {
- PERROR("Error evicting postcopy pfn %"PRI_xen_pfn, bpfn);
- goto out;
- }
}
}
rc = 0;
out:
+ free(bpfns);
+ free(xapfns);
+
return rc;
}
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |