All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olaf Hering <olaf@aepfle.de>
To: xen-devel@lists.xenproject.org
Cc: Olaf Hering <olaf@aepfle.de>, Juergen Gross <jgross@suse.com>,
	Ian Jackson <iwj@xenproject.org>, Wei Liu <wl@xen.org>
Subject: [PATCH v20210616 18/36] tools: save: move local_pages array
Date: Wed, 16 Jun 2021 14:51:11 +0200	[thread overview]
Message-ID: <20210616125129.26563-19-olaf@aepfle.de> (raw)
In-Reply-To: <20210616125129.26563-1-olaf@aepfle.de>

Remove allocation from hotpath, move local_pages array into preallocated space.

Adjust the code to use the src page as is in case of HVM.
In case of PV the page may need to be normalised, use a private memory
area for this purpose.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Juergen Gross <jgross@suse.com>
---
 tools/libs/saverestore/common.h       | 22 ++++++++++---------
 tools/libs/saverestore/save.c         | 25 +++------------------
 tools/libs/saverestore/save_x86_hvm.c |  5 +++--
 tools/libs/saverestore/save_x86_pv.c  | 31 ++++++++++++++++++---------
 4 files changed, 39 insertions(+), 44 deletions(-)

diff --git a/tools/libs/saverestore/common.h b/tools/libs/saverestore/common.h
index c4ab843c77..96ae0904fc 100644
--- a/tools/libs/saverestore/common.h
+++ b/tools/libs/saverestore/common.h
@@ -45,16 +45,12 @@ struct xc_sr_save_ops
      * Optionally transform the contents of a page from being specific to the
      * sending environment, to being generic for the stream.
      *
-     * The page of data at the end of 'page' may be a read-only mapping of a
-     * running guest; it must not be modified.  If no transformation is
-     * required, the callee should leave '*pages' untouched.
+     * The page of data '*src' may be a read-only mapping of a running guest;
+     * it must not be modified. If no transformation is required, the callee
+     * should leave '*src' untouched, and return it via '**ptr'.
      *
-     * If a transformation is required, the callee should allocate themselves
-     * a local page using malloc() and return it via '*page'.
-     *
-     * The caller shall free() '*page' in all cases.  In the case that the
-     * callee encounters an error, it should *NOT* free() the memory it
-     * allocated for '*page'.
+     * If a transformation is required, the callee should provide the
+     * transformed page in a private buffer and return it via '**ptr'.
      *
      * It is valid to fail with EAGAIN if the transformation is not able to be
      * completed at this point.  The page shall be retried later.
@@ -62,7 +58,7 @@ struct xc_sr_save_ops
      * @returns 0 for success, -1 for failure, with errno appropriately set.
      */
     int (*normalise_page)(struct xc_sr_context *ctx, xen_pfn_t type,
-                          void **page);
+                          void *src, unsigned int idx, void **ptr);
 
     /**
      * Set up local environment to save a domain. (Typically querying
@@ -385,6 +381,12 @@ struct xc_sr_context
 
                 union
                 {
+                    struct
+                    {
+                        /* Used by write_batch for modified pages. */
+                        void *normalised_pages;
+                    } save;
+
                     struct
                     {
                         /* State machine for the order of received records. */
diff --git a/tools/libs/saverestore/save.c b/tools/libs/saverestore/save.c
index ea04cb1a74..fa83648f9a 100644
--- a/tools/libs/saverestore/save.c
+++ b/tools/libs/saverestore/save.c
@@ -91,11 +91,10 @@ static int write_batch(struct xc_sr_context *ctx)
     xen_pfn_t *mfns = ctx->save.m->mfns, *types = ctx->save.m->types;
     void *guest_mapping = NULL;
     void **guest_data = ctx->save.m->guest_data;
-    void **local_pages = NULL;
     int *errors = ctx->save.m->errors, rc = -1;
     unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0;
     unsigned int nr_pfns = ctx->save.nr_batch_pfns;
-    void *page, *orig_page;
+    void *src;
     uint64_t *rec_pfns = ctx->save.m->rec_pfns;
     struct iovec *iov = ctx->save.m->iov; int iovcnt = 0;
     struct xc_sr_rec_page_data_header hdr = { 0 };
@@ -105,16 +104,6 @@ static int write_batch(struct xc_sr_context *ctx)
 
     assert(nr_pfns != 0);
 
-    /* Pointers to locally allocated pages.  Need freeing. */
-    local_pages = calloc(nr_pfns, sizeof(*local_pages));
-
-    if ( !local_pages )
-    {
-        ERROR("Unable to allocate arrays for a batch of %u pages",
-              nr_pfns);
-        goto err;
-    }
-
     for ( i = 0; i < nr_pfns; ++i )
     {
         types[i] = mfns[i] = ctx->save.ops.pfn_to_gfn(ctx,
@@ -176,11 +165,8 @@ static int write_batch(struct xc_sr_context *ctx)
                 goto err;
             }
 
-            orig_page = page = guest_mapping + (p * PAGE_SIZE);
-            rc = ctx->save.ops.normalise_page(ctx, types[i], &page);
-
-            if ( orig_page != page )
-                local_pages[i] = page;
+            src = guest_mapping + (p * PAGE_SIZE);
+            rc = ctx->save.ops.normalise_page(ctx, types[i], src, i, &guest_data[i]);
 
             if ( rc )
             {
@@ -195,8 +181,6 @@ static int write_batch(struct xc_sr_context *ctx)
                 else
                     goto err;
             }
-            else
-                guest_data[i] = page;
 
             rc = -1;
             ++p;
@@ -255,9 +239,6 @@ static int write_batch(struct xc_sr_context *ctx)
  err:
     if ( guest_mapping )
         xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped);
-    for ( i = 0; local_pages && i < nr_pfns; ++i )
-        free(local_pages[i]);
-    free(local_pages);
 
     return rc;
 }
diff --git a/tools/libs/saverestore/save_x86_hvm.c b/tools/libs/saverestore/save_x86_hvm.c
index 91c2cb99ab..26f49ee267 100644
--- a/tools/libs/saverestore/save_x86_hvm.c
+++ b/tools/libs/saverestore/save_x86_hvm.c
@@ -129,9 +129,10 @@ static xen_pfn_t x86_hvm_pfn_to_gfn(const struct xc_sr_context *ctx,
     return pfn;
 }
 
-static int x86_hvm_normalise_page(struct xc_sr_context *ctx,
-                                  xen_pfn_t type, void **page)
+static int x86_hvm_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type,
+                                  void *src, unsigned int idx, void **ptr)
 {
+    *ptr = src;
     return 0;
 }
 
diff --git a/tools/libs/saverestore/save_x86_pv.c b/tools/libs/saverestore/save_x86_pv.c
index 92f77fad0f..159ff59480 100644
--- a/tools/libs/saverestore/save_x86_pv.c
+++ b/tools/libs/saverestore/save_x86_pv.c
@@ -999,29 +999,31 @@ static xen_pfn_t x86_pv_pfn_to_gfn(const struct xc_sr_context *ctx,
  * save_ops function.  Performs pagetable normalisation on appropriate pages.
  */
 static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type,
-                                 void **page)
+                                  void *src, unsigned int idx, void **ptr)
 {
     xc_interface *xch = ctx->xch;
-    void *local_page;
     int rc;
+    void *dst;
 
     type &= XEN_DOMCTL_PFINFO_LTABTYPE_MASK;
 
     if ( type < XEN_DOMCTL_PFINFO_L1TAB || type > XEN_DOMCTL_PFINFO_L4TAB )
+    {
+        *ptr = src;
         return 0;
+    }
 
-    local_page = malloc(PAGE_SIZE);
-    if ( !local_page )
+    if ( idx >= MAX_BATCH_SIZE )
     {
-        ERROR("Unable to allocate scratch page");
-        rc = -1;
-        goto out;
+        ERROR("idx %u out of range", idx);
+        errno = ERANGE;
+        return -1;
     }
 
-    rc = normalise_pagetable(ctx, *page, local_page, type);
-    *page = local_page;
+    dst = ctx->x86.pv.save.normalised_pages + idx * PAGE_SIZE;
+    rc = normalise_pagetable(ctx, src, dst, type);
+    *ptr = dst;
 
- out:
     return rc;
 }
 
@@ -1031,8 +1033,16 @@ static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type,
  */
 static int x86_pv_setup(struct xc_sr_context *ctx)
 {
+    xc_interface *xch = ctx->xch;
     int rc;
 
+    ctx->x86.pv.save.normalised_pages = malloc(MAX_BATCH_SIZE * PAGE_SIZE);
+    if ( !ctx->x86.pv.save.normalised_pages )
+    {
+        PERROR("Failed to allocate normalised_pages");
+        return -1;
+    }
+
     rc = x86_pv_domain_info(ctx);
     if ( rc )
         return rc;
@@ -1118,6 +1128,7 @@ static int x86_pv_check_vm_state(struct xc_sr_context *ctx)
 
 static int x86_pv_cleanup(struct xc_sr_context *ctx)
 {
+    free(ctx->x86.pv.save.normalised_pages);
     free(ctx->x86.pv.p2m_pfns);
 
     if ( ctx->x86.pv.p2m )


  parent reply	other threads:[~2021-06-16 13:07 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-16 12:50 [PATCH v20210616 00/36] leftover from 2020 Olaf Hering
2021-06-16 12:50 ` [PATCH v20210616 01/36] hotplug/Linux: fix starting of xenstored with restarting systemd Olaf Hering
2021-06-16 12:50 ` [PATCH v20210616 02/36] tools: add API to work with sevaral bits at once Olaf Hering
2021-06-16 12:50 ` [PATCH v20210616 03/36] xl: fix description of migrate --debug Olaf Hering
2021-06-16 12:50 ` [PATCH v20210616 04/36] tools: create libxensaverestore Olaf Hering
2021-06-16 15:17   ` Olaf Hering
2021-06-16 12:50 ` [PATCH v20210616 05/36] MAINTAINERS: add myself as saverestore maintainer Olaf Hering
2021-06-16 12:50 ` [PATCH v20210616 06/36] tools: add readv_exact to libxenctrl Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 07/36] tools: add sr_is_known_page_type to libsaverestore Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 08/36] tools: use sr_is_known_page_type Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 09/36] tools: unify type checking for data pfns in migration stream Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 10/36] tools: show migration transfer rate in send_dirty_pages Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 11/36] tools: prepare to allocate saverestore arrays once Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 12/36] tools: save: move mfns array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 13/36] tools: save: move types array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 14/36] tools: save: move errors array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 15/36] tools: save: move iov array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 16/36] tools: save: move rec_pfns array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 17/36] tools: save: move guest_data array Olaf Hering
2021-06-16 12:51 ` Olaf Hering [this message]
2021-06-16 12:51 ` [PATCH v20210616 19/36] tools: restore: move types array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 20/36] tools: restore: move mfns array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 21/36] tools: restore: move map_errs array Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 22/36] tools: restore: move mfns array in populate_pfns Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 23/36] tools: restore: move pfns " Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 24/36] tools: restore: split record processing Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 25/36] tools: restore: split handle_page_data Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 26/36] tools: restore: write data directly into guest Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 27/36] tools: recognize LIBXL_API_VERSION for 4.16 Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 28/36] tools: adjust libxl_domain_suspend to receive a struct props Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 29/36] tools: change struct precopy_stats to precopy_stats_t Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 30/36] tools: add callback to libxl for precopy_policy and precopy_stats_t Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 31/36] tools: add --max_iters to libxl_domain_suspend Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 32/36] tools: add --min_remaining " Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 33/36] tools: add --abort_if_busy " Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 34/36] tools: add API for expandable bitmaps Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 35/36] tools: use sr_bitmap for populated_pfns Olaf Hering
2021-06-16 12:51 ` [PATCH v20210616 36/36] tools: use superpages during restore of HVM guest Olaf Hering
2021-06-16 14:50 ` [PATCH v20210616 00/36] leftover from 2020 Andrew Cooper
2021-06-16 15:02   ` Olaf Hering
2021-06-17 11:02     ` Julien Grall
2021-06-17 17:40       ` Olaf Hering
2021-06-16 15:38   ` Olaf Hering
2021-06-17 11:24     ` Andrew Cooper
2021-06-17 14:55       ` Olaf Hering
2021-06-17 15:05         ` Andrew Cooper

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=20210616125129.26563-19-olaf@aepfle.de \
    --to=olaf@aepfle.de \
    --cc=iwj@xenproject.org \
    --cc=jgross@suse.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    --subject='Re: [PATCH v20210616 18/36] tools: save: move local_pages array' \
    /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

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.