@@ -130,7 +130,7 @@ static int write_batch(struct xc_sr_cont
ctx->save.batch_pfns[i]);
/* Likely a ballooned page. */
- if ( mfns[i] == INVALID_MFN )
+ if ( mfns[i] == INVALID_MFN && ctx->save.deferred_pages )
{
set_bit(ctx->save.batch_pfns[i], ctx->save.deferred_pages);
++ctx->save.nr_deferred_pages;
@@ -196,8 +196,12 @@ static int write_batch(struct xc_sr_cont
{
if ( rc == -1 && errno == EAGAIN )
{
- set_bit(ctx->save.batch_pfns[i], ctx->save.deferred_pages);
- ++ctx->save.nr_deferred_pages;
+ if ( ctx->save.deferred_pages )
+ {
+ set_bit(ctx->save.batch_pfns[i],
+ ctx->save.deferred_pages);
+ ++ctx->save.nr_deferred_pages;
+ }
types[i] = XEN_DOMCTL_PFINFO_XTAB;
--nr_pages;
}
@@ -665,7 +669,8 @@ static int suspend_and_send_dirty(struct
else
xc_set_progress_prefix(xch, "Checkpointed save");
- bitmap_or(dirty_bitmap, ctx->save.deferred_pages, ctx->save.p2m_size);
+ if ( ctx->save.deferred_pages )
+ bitmap_or(dirty_bitmap, ctx->save.deferred_pages, ctx->save.p2m_size);
if ( !ctx->save.live && ctx->stream_type == XC_STREAM_COLO )
{
@@ -682,7 +687,8 @@ static int suspend_and_send_dirty(struct
if ( rc )
goto out;
- bitmap_clear(ctx->save.deferred_pages, ctx->save.p2m_size);
+ if ( ctx->save.deferred_pages )
+ bitmap_clear(ctx->save.deferred_pages, ctx->save.p2m_size);
ctx->save.nr_deferred_pages = 0;
out:
@@ -791,24 +797,31 @@ static int setup(struct xc_sr_context *c
{
xc_interface *xch = ctx->xch;
int rc;
- DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
- &ctx->save.dirty_bitmap_hbuf);
rc = ctx->save.ops.setup(ctx);
if ( rc )
goto err;
- dirty_bitmap = ctx->save.live || ctx->stream_type != XC_STREAM_PLAIN
- ? xc_hypercall_buffer_alloc_pages(
- xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size)))
- : (void *)-1L;
+ if ( ctx->save.live || ctx->stream_type != XC_STREAM_PLAIN )
+ {
+ 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.deferred_pages = bitmap_alloc(ctx->save.p2m_size);
+
+ if ( !dirty_bitmap || !ctx->save.deferred_pages )
+ goto enomem;
+ }
ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE *
sizeof(*ctx->save.batch_pfns));
- ctx->save.deferred_pages = bitmap_alloc(ctx->save.p2m_size);
- if ( !ctx->save.batch_pfns || !dirty_bitmap || !ctx->save.deferred_pages )
+ if ( !ctx->save.batch_pfns )
{
+ enomem:
ERROR("Unable to allocate memory for dirty bitmaps, batch pfns and"
" deferred pages");
rc = -1;
Like for the dirty bitmap, it is unnecessary to allocate the deferred- pages bitmap when all that's ever going to happen is a single all-dirty run. Signed-off-by: Jan Beulich <jbeulich@suse.com>