All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Juergen Gross <jgross@suse.com>,
	xen-devel@lists.xen.org, Ian.Campbell@citrix.com,
	ian.jackson@eu.citrix.com, stefano.stabellini@eu.citrix.com,
	wei.liu2@citrix.com
Subject: Re: [PATCH] libxc: try to find last used pfn when migrating
Date: Fri, 27 Nov 2015 16:42:31 +0000	[thread overview]
Message-ID: <565887F7.9080206@citrix.com> (raw)
In-Reply-To: <1448635853-24865-1-git-send-email-jgross@suse.com>

On 27/11/15 14:50, Juergen Gross wrote:
> For migration the last used pfn of a guest is needed to size the
> logdirty bitmap and as an upper bound of the page loop. Unfortunately
> there are pv-kernels advertising a much higher maximum pfn as they
> are really using in order to support memory hotplug. This will lead
> to allocation of much more memory in Xen tools during migration as
> really needed.
>
> Try to find the last used guest pfn of a pv-domu by scanning the p2m
> tree from the last entry towards it's start and search for an entry
> not being invalid.
>
> Normally the mid pages of the p2m tree containing all invalid entries
> are being reused, so we can just scan the top page for identical
> entries and skip them but the first one.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
>  tools/libxc/xc_sr_save.c        |  8 ++++----
>  tools/libxc/xc_sr_save_x86_pv.c | 34 +++++++++++++++++++++++++++++++---
>  2 files changed, 35 insertions(+), 7 deletions(-)
>
> diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
> index 0c12e56..22b3f18 100644
> --- a/tools/libxc/xc_sr_save.c
> +++ b/tools/libxc/xc_sr_save.c
> @@ -677,6 +677,10 @@ static int setup(struct xc_sr_context *ctx)
>      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 = xc_hypercall_buffer_alloc_pages(
>                     xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size)));
>      ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE *
> @@ -692,10 +696,6 @@ static int setup(struct xc_sr_context *ctx)
>          goto err;
>      }
>  
> -    rc = ctx->save.ops.setup(ctx);
> -    if ( rc )
> -        goto err;
> -
>      rc = 0;
>  
>   err:

While moving this, the restore side should be consistent (turns out it
already is), and the docs updated.  There was an inaccuracy, so I went
ahead and did it.

--8<--
diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 64f6082..ae77155 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -54,9 +54,11 @@ struct xc_sr_save_ops
                           void **page);
 
     /**
-     * Set up local environment to restore a domain.  This is called before
-     * any records are written to the stream.  (Typically querying running
-     * domain state, setting up mappings etc.)
+     * Set up local environment to save a domain. (Typically querying
+     * running domain state, setting up mappings etc.)
+     *
+     * This is called once before any common setup has occurred,
allowing for
+     * guest-specific adjustments to be made to common state.
      */
     int (*setup)(struct xc_sr_context *ctx);
 
@@ -121,8 +123,10 @@ struct xc_sr_restore_ops
     int (*localise_page)(struct xc_sr_context *ctx, uint32_t type, void
*page);
 
     /**
-     * Set up local environment to restore a domain.  This is called before
-     * any records are read from the stream.
+     * Set up local environment to restore a domain.
+     *
+     * This is called once before any common setup has occurred,
allowing for
+     * guest-specific adjustments to be made to common state.
      */
     int (*setup)(struct xc_sr_context *ctx);
 
--8<--

Feel free to fold this into your patch, or I can submit it alone as a
cleanup prerequisite for your functional change below.

> diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c
> index f63f40b..6189fda 100644
> --- a/tools/libxc/xc_sr_save_x86_pv.c
> +++ b/tools/libxc/xc_sr_save_x86_pv.c
> @@ -83,8 +83,8 @@ static int map_p2m(struct xc_sr_context *ctx)
>       */
>      xc_interface *xch = ctx->xch;
>      int rc = -1;
> -    unsigned x, fpp, fll_entries, fl_entries;
> -    xen_pfn_t fll_mfn;
> +    unsigned x, saved_x, fpp, fll_entries, fl_entries;
> +    xen_pfn_t fll_mfn, saved_mfn, max_pfn;
>  
>      xen_pfn_t *local_fll = NULL;
>      void *guest_fll = NULL;
> @@ -96,7 +96,6 @@ static int map_p2m(struct xc_sr_context *ctx)
>  
>      fpp = PAGE_SIZE / ctx->x86_pv.width;
>      fll_entries = (ctx->x86_pv.max_pfn / (fpp * fpp)) + 1;
> -    fl_entries  = (ctx->x86_pv.max_pfn / fpp) + 1;
>  
>      fll_mfn = GET_FIELD(ctx->x86_pv.shinfo, arch.pfn_to_mfn_frame_list_list,
>                          ctx->x86_pv.width);
> @@ -131,6 +130,8 @@ static int map_p2m(struct xc_sr_context *ctx)
>      }
>  
>      /* Check for bad mfns in frame list list. */
> +    saved_mfn = 0;
> +    saved_x = 0;
>      for ( x = 0; x < fll_entries; ++x )
>      {
>          if ( local_fll[x] == 0 || local_fll[x] > ctx->x86_pv.max_mfn )
> @@ -139,8 +140,35 @@ static int map_p2m(struct xc_sr_context *ctx)
>                    local_fll[x], x, fll_entries);
>              goto err;
>          }
> +        if ( local_fll[x] != saved_mfn )
> +        {
> +            saved_mfn = local_fll[x];
> +            saved_x = x;
> +        }
>      }
>  
> +    /*
> +     * Check for actual lower max_pfn:
> +     * If the trailing entries of the frame list list were all the same we can
> +     * assume they all reference mid pages all referencing p2m pages with all
> +     * invalid entries. Otherwise there would be multiple pfns referencing all
> +     * the same mfn which can't work across migration, as this sharing would be
> +     * broken by the migration process.
> +     * Adjust max_pfn if possible to avoid allocating much larger areas as
> +     * needed for p2m and logdirty map.
> +     */
> +    max_pfn = (saved_x + 1) * fpp * fpp - 1;
> +    if ( max_pfn < ctx->x86_pv.max_pfn )
> +    {
> +        ctx->x86_pv.max_pfn = max_pfn;
> +        ctx->x86_pv.p2m_frames = (ctx->x86_pv.max_pfn + fpp) / fpp;
> +        ctx->save.p2m_size = max_pfn + 1;
> +        fll_entries = (ctx->x86_pv.max_pfn / (fpp * fpp)) + 1;
> +        DPRINTF("lowering max_pfn to %#lx, p2m_frames %d", max_pfn,
> +                ctx->x86_pv.p2m_frames);
> +    }
> +    fl_entries  = (ctx->x86_pv.max_pfn / fpp) + 1;
> +
>      /* Map the guest mid p2m frames. */
>      guest_fl = xc_map_foreign_pages(xch, ctx->domid, PROT_READ,
>                                      local_fll, fll_entries);

For the actual change, Reviewed-by: Andrew Cooper
<andrew.cooper3@citrix.com>

  parent reply	other threads:[~2015-11-27 16:42 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-27 14:50 [PATCH] libxc: try to find last used pfn when migrating Juergen Gross
2015-11-27 15:01 ` David Vrabel
2015-11-27 15:11   ` Juergen Gross
2015-11-27 15:18     ` Ian Campbell
2015-11-27 15:20     ` David Vrabel
2015-11-27 15:22     ` Ian Jackson
2015-11-27 15:50       ` Juergen Gross
2015-11-27 15:33 ` Wei Liu
2015-11-27 15:53   ` Juergen Gross
2015-11-27 17:16     ` Andrew Cooper
2015-11-30  8:17       ` Juergen Gross
2015-11-30  9:47         ` Andrew Cooper
2015-11-30 12:16           ` Juergen Gross
2015-11-27 16:42 ` Andrew Cooper [this message]
2015-11-27 16:51   ` Juergen Gross

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=565887F7.9080206@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jgross@suse.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.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.