[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH Remus v2 01/10] tools/libxc: adjust the memory allocation for migration
Move the memory allocation before the concrete live/nolive save in order to avoid the free/alloc memory loop when using Remus. Rename the to_send bitmap to dirty_bitmap. Signed-off-by: Yang Hongyang <yanghy@xxxxxxxxxxxxxx> --- tools/libxc/xc_sr_common.h | 1 + tools/libxc/xc_sr_save.c | 68 ++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 38 deletions(-) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index ef42412..95e3f5d 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -182,6 +182,7 @@ struct xc_sr_context unsigned nr_batch_pfns; unsigned long *deferred_pages; unsigned long nr_deferred_pages; + xc_hypercall_buffer_t dirty_bitmap_hbuf; } save; struct /* Restore data. */ diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c index 5d9c267..cc3e6b1 100644 --- a/tools/libxc/xc_sr_save.c +++ b/tools/libxc/xc_sr_save.c @@ -475,24 +475,12 @@ static int update_progress_string(struct xc_sr_context *ctx, static int send_domain_memory_live(struct xc_sr_context *ctx) { xc_interface *xch = ctx->xch; - DECLARE_HYPERCALL_BUFFER(unsigned long, to_send); xc_shadow_op_stats_t stats = { 0, ctx->save.p2m_size }; char *progress_str = NULL; unsigned x; int rc = -1; - - to_send = xc_hypercall_buffer_alloc_pages( - xch, to_send, NRPAGES(bitmap_size(ctx->save.p2m_size))); - - ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE * - sizeof(*ctx->save.batch_pfns)); - ctx->save.deferred_pages = calloc(1, bitmap_size(ctx->save.p2m_size)); - - if ( !ctx->save.batch_pfns || !to_send || !ctx->save.deferred_pages ) - { - ERROR("Unable to allocate memory for to_{send,fix}/batch bitmaps"); - goto out; - } + DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, + (&ctx->save.dirty_bitmap_hbuf)); rc = enable_logdirty(ctx); if ( rc ) @@ -512,7 +500,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) { if ( xc_shadow_control( xch, ctx->domid, XEN_DOMCTL_SHADOW_OP_CLEAN, - HYPERCALL_BUFFER(to_send), ctx->save.p2m_size, + HYPERCALL_BUFFER(dirty_bitmap), ctx->save.p2m_size, NULL, 0, &stats) != ctx->save.p2m_size ) { PERROR("Failed to retrieve logdirty bitmap"); @@ -527,7 +515,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) if ( rc ) goto out; - rc = send_some_pages(ctx, to_send, stats.dirty_count); + rc = send_some_pages(ctx, dirty_bitmap, stats.dirty_count); if ( rc ) goto out; } @@ -538,7 +526,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) if ( xc_shadow_control( xch, ctx->domid, XEN_DOMCTL_SHADOW_OP_CLEAN, - HYPERCALL_BUFFER(to_send), ctx->save.p2m_size, + HYPERCALL_BUFFER(dirty_bitmap), ctx->save.p2m_size, NULL, 0, &stats) != ctx->save.p2m_size ) { PERROR("Failed to retrieve logdirty bitmap"); @@ -550,9 +538,9 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) if ( rc ) goto out; - bitmap_or(to_send, ctx->save.deferred_pages, ctx->save.p2m_size); + bitmap_or(dirty_bitmap, ctx->save.deferred_pages, ctx->save.p2m_size); - rc = send_some_pages(ctx, to_send, + rc = send_some_pages(ctx, dirty_bitmap, stats.dirty_count + ctx->save.nr_deferred_pages); if ( rc ) goto out; @@ -578,7 +566,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) if ( xc_shadow_control( xch, ctx->domid, XEN_DOMCTL_SHADOW_OP_PEEK, - HYPERCALL_BUFFER(to_send), ctx->save.p2m_size, + HYPERCALL_BUFFER(dirty_bitmap), ctx->save.p2m_size, NULL, 0, &stats) != ctx->save.p2m_size ) { PERROR("Failed to retrieve logdirty bitmap"); @@ -593,10 +581,6 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) out: xc_set_progress_prefix(xch, NULL); free(progress_str); - xc_hypercall_buffer_free_pages(xch, to_send, - NRPAGES(bitmap_size(ctx->save.p2m_size))); - free(ctx->save.deferred_pages); - free(ctx->save.batch_pfns); return rc; } @@ -609,17 +593,6 @@ static int send_domain_memory_nonlive(struct xc_sr_context *ctx) xc_interface *xch = ctx->xch; int rc = -1; - ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE * - sizeof(*ctx->save.batch_pfns)); - ctx->save.deferred_pages = calloc(1, bitmap_size(ctx->save.p2m_size)); - - if ( !ctx->save.batch_pfns || !ctx->save.deferred_pages ) - { - PERROR("Failed to allocate memory for nonlive tracking structures"); - errno = ENOMEM; - goto err; - } - rc = suspend_domain(ctx); if ( rc ) goto err; @@ -631,9 +604,6 @@ static int send_domain_memory_nonlive(struct xc_sr_context *ctx) goto err; err: - free(ctx->save.deferred_pages); - free(ctx->save.batch_pfns); - return rc; } @@ -644,6 +614,23 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) { xc_interface *xch = ctx->xch; int rc, saved_rc = 0, saved_errno = 0; + DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, + (&ctx->save.dirty_bitmap_hbuf)); + + dirty_bitmap = xc_hypercall_buffer_alloc_pages( + xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size))); + ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE * + sizeof(*ctx->save.batch_pfns)); + ctx->save.deferred_pages = calloc(1, bitmap_size(ctx->save.p2m_size)); + + if ( !ctx->save.batch_pfns || !dirty_bitmap || !ctx->save.deferred_pages ) + { + ERROR("Unable to allocate memory for dirty bitmaps, batch pfns and" + " deferred pages"); + rc = -1; + errno = ENOMEM; + goto err; + } IPRINTF("Saving domain %d, type %s", ctx->domid, dhdr_type_to_str(guest_type)); @@ -704,6 +691,11 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) if ( rc ) PERROR("Failed to clean up"); + xc_hypercall_buffer_free_pages(xch, dirty_bitmap, + NRPAGES(bitmap_size(ctx->save.p2m_size))); + free(ctx->save.deferred_pages); + free(ctx->save.batch_pfns); + if ( saved_rc ) { rc = saved_rc; -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |