Re: [Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-08 Thread Ian Campbell
On Wed, 2015-12-02 at 16:30 +0100, Juergen Gross wrote:
> On 02/12/15 16:28, Ian Campbell wrote:
> > On Wed, 2015-12-02 at 12:36 +, Andrew Cooper wrote:
> > > On 02/12/15 07:42, Juergen Gross wrote:
> > > > diff --git a/tools/libxc/xc_sr_save_x86_hvm.c
> > > > b/tools/libxc/xc_sr_save_x86_hvm.c
> > > > index cdee774..3c879ed 100644
> > > > --- a/tools/libxc/xc_sr_save_x86_hvm.c
> > > > +++ b/tools/libxc/xc_sr_save_x86_hvm.c
> > > > @@ -135,6 +135,20 @@ static int x86_hvm_normalise_page(struct
> > > > xc_sr_context *ctx,
> > > >  static int x86_hvm_setup(struct xc_sr_context *ctx)
> > > >  {
> > > >  xc_interface *xch = ctx->xch;
> > > > +xen_pfn_t nr_pfns;
> > > > +
> > > > +if ( xc_domain_nr_gpfns(xch, ctx->domid, _pfns) < 0 )
> > > > +{
> > > > +PERROR("Unable to obtain the guest p2m size");
> > > > +return -1;
> > > > +}
> > > > +if ( nr_pfns > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
> > > > +{
> > > > +PERROR("Cannot save this big a guest");
> > > 
> > > Strictly speaking to match the moved code, this should set errno =
> > > E2BIG.
> > > 
> > > However, the error handling in libxc is in a dire state, and the
> > > error
> > > message is retained, which is the important point.
> > > 
> > > Entire patch Reviewed-by: Andrew Cooper 
> > > with
> > > or without the errno tweaks.
> > 
> > I could make the errno tweak on commit, if there is agreement.
> 
> Sure, go ahead.

Now done, sorry for the delay... distractions...

Ian.


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-02 Thread Ian Campbell
On Wed, 2015-12-02 at 16:30 +0100, Juergen Gross wrote:
> On 02/12/15 16:28, Ian Campbell wrote:
> > On Wed, 2015-12-02 at 12:36 +, Andrew Cooper wrote:
> > > On 02/12/15 07:42, Juergen Gross wrote:
> > > > diff --git a/tools/libxc/xc_sr_save_x86_hvm.c
> > > > b/tools/libxc/xc_sr_save_x86_hvm.c
> > > > index cdee774..3c879ed 100644
> > > > --- a/tools/libxc/xc_sr_save_x86_hvm.c
> > > > +++ b/tools/libxc/xc_sr_save_x86_hvm.c
> > > > @@ -135,6 +135,20 @@ static int x86_hvm_normalise_page(struct
> > > > xc_sr_context *ctx,
> > > >  static int x86_hvm_setup(struct xc_sr_context *ctx)
> > > >  {
> > > >  xc_interface *xch = ctx->xch;
> > > > +xen_pfn_t nr_pfns;
> > > > +
> > > > +if ( xc_domain_nr_gpfns(xch, ctx->domid, _pfns) < 0 )
> > > > +{
> > > > +PERROR("Unable to obtain the guest p2m size");
> > > > +return -1;
> > > > +}
> > > > +if ( nr_pfns > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
> > > > +{
> > > > +PERROR("Cannot save this big a guest");
> > > 
> > > Strictly speaking to match the moved code, this should set errno =
> > > E2BIG.
> > > 
> > > However, the error handling in libxc is in a dire state, and the
> > > error
> > > message is retained, which is the important point.
> > > 
> > > Entire patch Reviewed-by: Andrew Cooper 
> > > with
> > > or without the errno tweaks.
> > 
> > I could make the errno tweak on commit, if there is agreement.
> 
> Sure, go ahead.

Will do it in my next commit pass (likely to be tomorrow).

Ian.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-02 Thread Juergen Gross
On 02/12/15 16:28, Ian Campbell wrote:
> On Wed, 2015-12-02 at 12:36 +, Andrew Cooper wrote:
>> On 02/12/15 07:42, Juergen Gross wrote:
>>> diff --git a/tools/libxc/xc_sr_save_x86_hvm.c
>>> b/tools/libxc/xc_sr_save_x86_hvm.c
>>> index cdee774..3c879ed 100644
>>> --- a/tools/libxc/xc_sr_save_x86_hvm.c
>>> +++ b/tools/libxc/xc_sr_save_x86_hvm.c
>>> @@ -135,6 +135,20 @@ static int x86_hvm_normalise_page(struct
>>> xc_sr_context *ctx,
>>>  static int x86_hvm_setup(struct xc_sr_context *ctx)
>>>  {
>>>  xc_interface *xch = ctx->xch;
>>> +xen_pfn_t nr_pfns;
>>> +
>>> +if ( xc_domain_nr_gpfns(xch, ctx->domid, _pfns) < 0 )
>>> +{
>>> +PERROR("Unable to obtain the guest p2m size");
>>> +return -1;
>>> +}
>>> +if ( nr_pfns > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
>>> +{
>>> +PERROR("Cannot save this big a guest");
>>
>> Strictly speaking to match the moved code, this should set errno = E2BIG.
>>
>> However, the error handling in libxc is in a dire state, and the error
>> message is retained, which is the important point.
>>
>> Entire patch Reviewed-by: Andrew Cooper  with
>> or without the errno tweaks.
> 
> I could make the errno tweak on commit, if there is agreement.

Sure, go ahead.


Juergen


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-02 Thread Ian Campbell
On Wed, 2015-12-02 at 12:36 +, Andrew Cooper wrote:
> On 02/12/15 07:42, Juergen Gross wrote:
> > diff --git a/tools/libxc/xc_sr_save_x86_hvm.c
> > b/tools/libxc/xc_sr_save_x86_hvm.c
> > index cdee774..3c879ed 100644
> > --- a/tools/libxc/xc_sr_save_x86_hvm.c
> > +++ b/tools/libxc/xc_sr_save_x86_hvm.c
> > @@ -135,6 +135,20 @@ static int x86_hvm_normalise_page(struct
> > xc_sr_context *ctx,
> >  static int x86_hvm_setup(struct xc_sr_context *ctx)
> >  {
> >  xc_interface *xch = ctx->xch;
> > +xen_pfn_t nr_pfns;
> > +
> > +if ( xc_domain_nr_gpfns(xch, ctx->domid, _pfns) < 0 )
> > +{
> > +PERROR("Unable to obtain the guest p2m size");
> > +return -1;
> > +}
> > +if ( nr_pfns > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
> > +{
> > +PERROR("Cannot save this big a guest");
> 
> Strictly speaking to match the moved code, this should set errno = E2BIG.
> 
> However, the error handling in libxc is in a dire state, and the error
> message is retained, which is the important point.
> 
> Entire patch Reviewed-by: Andrew Cooper  with
> or without the errno tweaks.

I could make the errno tweak on commit, if there is agreement.

Ian.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-02 Thread Wei Liu
On Wed, Dec 02, 2015 at 08:42:17AM +0100, 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 

Reviewed-by: Wei Liu 

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-02 Thread Andrew Cooper
On 02/12/15 07:42, Juergen Gross wrote:
> diff --git a/tools/libxc/xc_sr_save_x86_hvm.c 
> b/tools/libxc/xc_sr_save_x86_hvm.c
> index cdee774..3c879ed 100644
> --- a/tools/libxc/xc_sr_save_x86_hvm.c
> +++ b/tools/libxc/xc_sr_save_x86_hvm.c
> @@ -135,6 +135,20 @@ static int x86_hvm_normalise_page(struct xc_sr_context 
> *ctx,
>  static int x86_hvm_setup(struct xc_sr_context *ctx)
>  {
>  xc_interface *xch = ctx->xch;
> +xen_pfn_t nr_pfns;
> +
> +if ( xc_domain_nr_gpfns(xch, ctx->domid, _pfns) < 0 )
> +{
> +PERROR("Unable to obtain the guest p2m size");
> +return -1;
> +}
> +if ( nr_pfns > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
> +{
> +PERROR("Cannot save this big a guest");

Strictly speaking to match the moved code, this should set errno = E2BIG.

However, the error handling in libxc is in a dire state, and the error
message is retained, which is the important point.

Entire patch Reviewed-by: Andrew Cooper  with
or without the errno tweaks.

~Andrew

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2] libxc: try to find last used pfn when migrating

2015-12-01 Thread Juergen Gross
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 
---
Changes in V2:
- Modified comments regarding setup callback in structures
  xc_sr_save_ops and xc_sr_restore_ops (suggested by Andrew).
- Got rid of calls of xc_domain_maximum_gpfn() especially in the pv
  case (suggested by Wei).

---
 tools/libxc/xc_sr_common.h| 14 -
 tools/libxc/xc_sr_common_x86_pv.c | 19 +-
 tools/libxc/xc_sr_save.c  | 24 ---
 tools/libxc/xc_sr_save_x86_hvm.c  | 14 +
 tools/libxc/xc_sr_save_x86_pv.c   | 41 ---
 5 files changed, 66 insertions(+), 46 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 64f6082..9aecde2 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);
 
diff --git a/tools/libxc/xc_sr_common_x86_pv.c 
b/tools/libxc/xc_sr_common_x86_pv.c
index eb68c07..f233c87 100644
--- a/tools/libxc/xc_sr_common_x86_pv.c
+++ b/tools/libxc/xc_sr_common_x86_pv.c
@@ -68,8 +68,7 @@ uint64_t mfn_to_cr3(struct xc_sr_context *ctx, xen_pfn_t _mfn)
 int x86_pv_domain_info(struct xc_sr_context *ctx)
 {
 xc_interface *xch = ctx->xch;
-unsigned int guest_width, guest_levels, fpp;
-xen_pfn_t max_pfn;
+unsigned int guest_width, guest_levels;
 
 /* Get the domain width */
 if ( xc_domain_get_guest_width(xch, ctx->domid, _width) )
@@ -89,25 +88,9 @@ int x86_pv_domain_info(struct xc_sr_context *ctx)
 }
 ctx->x86_pv.width = guest_width;
 ctx->x86_pv.levels = guest_levels;
-fpp = PAGE_SIZE / ctx->x86_pv.width;
 
 DPRINTF("%d bits, %d levels", guest_width * 8, guest_levels);
 
-/* Get the domain's size */
-if ( xc_domain_maximum_gpfn(xch, ctx->domid, _pfn) < 0 )
-{
-PERROR("Unable to obtain guests max pfn");
-return -1;
-}
-
-if ( max_pfn > 0 )
-{
-ctx->x86_pv.max_pfn = max_pfn;
-ctx->x86_pv.p2m_frames = (ctx->x86_pv.max_pfn + fpp) / fpp;
-
-DPRINTF("max_pfn %#lx, p2m_frames %d", max_pfn, 
ctx->x86_pv.p2m_frames);
-}
-
 return 0;
 }
 
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index 0c12e56..cefcef5 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,
 >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:
@@ -824,7 +824,6 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
uint32_t max_iters, uint32_t max_factor, uint32_t flags,
struct save_callbacks* callbacks, int hvm)
 {
-xen_pfn_t nr_pfns;