|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH Remus v1 1/8] tools/libxc: adjust the memory allocation for migration
On 07/05/15 07:37, Yang Hongyang wrote:
> Move the memory allocation before the concrete live/nolive save
> in order to avoid the free/alloc memory loop when using Remus.
>
> Signed-off-by: Yang Hongyang <yanghy@xxxxxxxxxxxxxx>
> ---
> tools/libxc/xc_sr_save.c | 53
> +++++++++++++++++++-----------------------------
> 1 file changed, 21 insertions(+), 32 deletions(-)
>
> diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
> index 5d9c267..7fed668 100644
> --- a/tools/libxc/xc_sr_save.c
> +++ b/tools/libxc/xc_sr_save.c
> @@ -3,6 +3,8 @@
>
> #include "xc_sr_common.h"
>
> +DECLARE_HYPERCALL_BUFFER(unsigned long, to_send);
This unfortunately causes an issue when concurrent calls to
xc_domain_save() in the same process. While this is a highly
ill-advised action, I did try to avoid breaking it.
Please move this declaration into the ctx.save union.
> +
> /*
> * Writes an Image header and Domain header into the stream.
> */
> @@ -475,25 +477,11 @@ 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;
> - }
> -
> rc = enable_logdirty(ctx);
> if ( rc )
> goto out;
> @@ -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;
> }
>
> @@ -645,6 +615,20 @@ 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;
>
> + to_send = xc_hypercall_buffer_alloc_pages(
> + xch, to_send,
> NRPAGES(bitmap_size(ctx->save.p2m_size)));
This allocation only needs to be made if ctx->save.live is set. For
plain suspend and resume, logdirty handling is not required.
> + 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");
> + rc = -1;
> + errno = ENOMEM;
> + goto err;
> + }
> +
Instead of complicating save() like this, could you introduce two new
static functions setup() and cleanup() which subsume the
ctx->save.ops.{setup,cleanup}() calls and also do these allocations and
free.
I think the SHADOW_OP_OFF hypercall can also be moved into the cleanup()
function.
~Andrew
> IPRINTF("Saving domain %d, type %s",
> ctx->domid, dhdr_type_to_str(guest_type));
>
> @@ -704,6 +688,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, to_send,
> + NRPAGES(bitmap_size(ctx->save.p2m_size)));
> + free(ctx->save.deferred_pages);
> + free(ctx->save.batch_pfns);
> +
> if ( saved_rc )
> {
> rc = saved_rc;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |