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>, Ian Jackson <iwj@xenproject.org>,
	Wei Liu <wl@xen.org>
Subject: [PATCH v20210601 24/38] tools/guest: restore: split record processing
Date: Tue,  1 Jun 2021 18:11:04 +0200	[thread overview]
Message-ID: <20210601161118.18986-25-olaf@aepfle.de> (raw)
In-Reply-To: <20210601161118.18986-1-olaf@aepfle.de>

handle_page_data must be able to read directly into mapped guest memory.
This will avoid unneccesary memcpy calls for data which can be consumed verbatim.

Rearrange the code to allow decisions based on the incoming record.

This change is preparation for future changes in handle_page_data,
no change in behavior is intended.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/saverestore/common.c  | 33 ++++++++++++---------
 tools/libs/saverestore/common.h  |  4 ++-
 tools/libs/saverestore/restore.c | 49 ++++++++++++++++++++++----------
 tools/libs/saverestore/save.c    |  7 ++++-
 4 files changed, 63 insertions(+), 30 deletions(-)

diff --git a/tools/libs/saverestore/common.c b/tools/libs/saverestore/common.c
index 77128bc747..7da7fa4e2c 100644
--- a/tools/libs/saverestore/common.c
+++ b/tools/libs/saverestore/common.c
@@ -91,26 +91,33 @@ int write_split_record(struct xc_sr_context *ctx, struct xc_sr_record *rec,
     return -1;
 }
 
-int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
+int read_record_header(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rhdr rhdr;
-    size_t datasz;
 
-    if ( read_exact(fd, &rhdr, sizeof(rhdr)) )
+    if ( read_exact(fd, rhdr, sizeof(*rhdr)) )
     {
         PERROR("Failed to read Record Header from stream");
         return -1;
     }
 
-    if ( rhdr.length > REC_LENGTH_MAX )
+    if ( rhdr->length > REC_LENGTH_MAX )
     {
-        ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr.type,
-              rec_type_to_str(rhdr.type), rhdr.length, REC_LENGTH_MAX);
+        ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr->type,
+              rec_type_to_str(rhdr->type), rhdr->length, REC_LENGTH_MAX);
         return -1;
     }
 
-    datasz = ROUNDUP(rhdr.length, REC_ALIGN_ORDER);
+    return 0;
+}
+
+int read_record_data(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr,
+                     struct xc_sr_record *rec)
+{
+    xc_interface *xch = ctx->xch;
+    size_t datasz;
+
+    datasz = ROUNDUP(rhdr->length, REC_ALIGN_ORDER);
 
     if ( datasz )
     {
@@ -119,7 +126,7 @@ int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
         if ( !rec->data )
         {
             ERROR("Unable to allocate %zu bytes for record data (0x%08x, %s)",
-                  datasz, rhdr.type, rec_type_to_str(rhdr.type));
+                  datasz, rhdr->type, rec_type_to_str(rhdr->type));
             return -1;
         }
 
@@ -128,18 +135,18 @@ int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
             free(rec->data);
             rec->data = NULL;
             PERROR("Failed to read %zu bytes of data for record (0x%08x, %s)",
-                   datasz, rhdr.type, rec_type_to_str(rhdr.type));
+                   datasz, rhdr->type, rec_type_to_str(rhdr->type));
             return -1;
         }
     }
     else
         rec->data = NULL;
 
-    rec->type   = rhdr.type;
-    rec->length = rhdr.length;
+    rec->type   = rhdr->type;
+    rec->length = rhdr->length;
 
     return 0;
-};
+}
 
 static void __attribute__((unused)) build_assertions(void)
 {
diff --git a/tools/libs/saverestore/common.h b/tools/libs/saverestore/common.h
index 9de09ae64a..73256f08ab 100644
--- a/tools/libs/saverestore/common.h
+++ b/tools/libs/saverestore/common.h
@@ -487,7 +487,9 @@ static inline int write_record(struct xc_sr_context *ctx,
  *
  * On failure, the contents of the record structure are undefined.
  */
-int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec);
+int read_record_header(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr);
+int read_record_data(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr,
+                     struct xc_sr_record *rec);
 
 /*
  * This would ideally be private in restore.c, but is needed by
diff --git a/tools/libs/saverestore/restore.c b/tools/libs/saverestore/restore.c
index 598a4aa06d..bb1574ed74 100644
--- a/tools/libs/saverestore/restore.c
+++ b/tools/libs/saverestore/restore.c
@@ -471,7 +471,7 @@ static int send_checkpoint_dirty_pfn_list(struct xc_sr_context *ctx)
     return rc;
 }
 
-static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
+static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
 static int handle_checkpoint(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
@@ -510,7 +510,7 @@ static int handle_checkpoint(struct xc_sr_context *ctx)
 
         for ( i = 0; i < ctx->restore.buffered_rec_num; i++ )
         {
-            rc = process_record(ctx, &ctx->restore.buffered_records[i]);
+            rc = process_buffered_record(ctx, &ctx->restore.buffered_records[i]);
             if ( rc )
                 goto err;
         }
@@ -571,10 +571,11 @@ static int handle_checkpoint(struct xc_sr_context *ctx)
     return rc;
 }
 
-static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
+static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_rhdr *rhdr)
 {
     xc_interface *xch = ctx->xch;
     unsigned int new_alloc_num;
+    struct xc_sr_record rec;
     struct xc_sr_record *p;
 
     if ( ctx->restore.buffered_rec_num >= ctx->restore.allocated_rec_num )
@@ -592,8 +593,13 @@ static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         ctx->restore.allocated_rec_num = new_alloc_num;
     }
 
+    if ( read_record_data(ctx, ctx->fd, rhdr, &rec) )
+    {
+        return -1;
+    }
+
     memcpy(&ctx->restore.buffered_records[ctx->restore.buffered_rec_num++],
-           rec, sizeof(*rec));
+           &rec, sizeof(rec));
 
     return 0;
 }
@@ -624,7 +630,7 @@ int handle_static_data_end(struct xc_sr_context *ctx)
     return rc;
 }
 
-static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
+static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
     int rc = 0;
@@ -662,6 +668,19 @@ static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     return rc;
 }
 
+static int process_incoming_record_header(struct xc_sr_context *ctx, struct xc_sr_rhdr *rhdr)
+{
+    struct xc_sr_record rec;
+    int rc;
+
+    rc = read_record_data(ctx, ctx->fd, rhdr, &rec);
+    if ( rc )
+        return rc;
+
+    return process_buffered_record(ctx, &rec);
+}
+
+
 static int setup(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
@@ -745,7 +764,7 @@ static void cleanup(struct xc_sr_context *ctx)
 static int restore(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_record rec;
+    struct xc_sr_rhdr rhdr;
     int rc, saved_rc = 0, saved_errno = 0;
 
     IPRINTF("Restoring domain");
@@ -756,7 +775,7 @@ static int restore(struct xc_sr_context *ctx)
 
     do
     {
-        rc = read_record(ctx, ctx->fd, &rec);
+        rc = read_record_header(ctx, ctx->fd, &rhdr);
         if ( rc )
         {
             if ( ctx->restore.buffer_all_records )
@@ -766,25 +785,25 @@ static int restore(struct xc_sr_context *ctx)
         }
 
         if ( ctx->restore.buffer_all_records &&
-             rec.type != REC_TYPE_END &&
-             rec.type != REC_TYPE_CHECKPOINT )
+             rhdr.type != REC_TYPE_END &&
+             rhdr.type != REC_TYPE_CHECKPOINT )
         {
-            rc = buffer_record(ctx, &rec);
+            rc = buffer_record(ctx, &rhdr);
             if ( rc )
                 goto err;
         }
         else
         {
-            rc = process_record(ctx, &rec);
+            rc = process_incoming_record_header(ctx, &rhdr);
             if ( rc == RECORD_NOT_PROCESSED )
             {
-                if ( rec.type & REC_TYPE_OPTIONAL )
+                if ( rhdr.type & REC_TYPE_OPTIONAL )
                     DPRINTF("Ignoring optional record %#x (%s)",
-                            rec.type, rec_type_to_str(rec.type));
+                            rhdr.type, rec_type_to_str(rhdr.type));
                 else
                 {
                     ERROR("Mandatory record %#x (%s) not handled",
-                          rec.type, rec_type_to_str(rec.type));
+                          rhdr.type, rec_type_to_str(rhdr.type));
                     rc = -1;
                     goto err;
                 }
@@ -795,7 +814,7 @@ static int restore(struct xc_sr_context *ctx)
                 goto err;
         }
 
-    } while ( rec.type != REC_TYPE_END );
+    } while ( rhdr.type != REC_TYPE_END );
 
  remus_failover:
     if ( ctx->stream_type == XC_STREAM_COLO )
diff --git a/tools/libs/saverestore/save.c b/tools/libs/saverestore/save.c
index c4876ba24c..b59cb069ed 100644
--- a/tools/libs/saverestore/save.c
+++ b/tools/libs/saverestore/save.c
@@ -590,6 +590,7 @@ static int send_memory_live(struct xc_sr_context *ctx)
 static int colo_merge_secondary_dirty_bitmap(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
+    struct xc_sr_rhdr rhdr;
     struct xc_sr_record rec;
     uint64_t *pfns = NULL;
     uint64_t pfn;
@@ -598,7 +599,11 @@ static int colo_merge_secondary_dirty_bitmap(struct xc_sr_context *ctx)
     DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
                                     &ctx->save.dirty_bitmap_hbuf);
 
-    rc = read_record(ctx, ctx->save.recv_fd, &rec);
+    rc = read_record_header(ctx, ctx->save.recv_fd, &rhdr);
+    if ( rc )
+        goto err;
+
+    rc = read_record_data(ctx, ctx->save.recv_fd, &rhdr, &rec);
     if ( rc )
         goto err;
 


  parent reply	other threads:[~2021-06-01 16:14 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-01 16:10 [PATCH v20210601 00/38] leftover from 2020 Olaf Hering
2021-06-01 16:10 ` [PATCH v20210601 01/38] tools: add API to work with sevaral bits at once Olaf Hering
2021-06-02  6:19   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 02/38] xl: fix description of migrate --debug Olaf Hering
2021-06-02  6:09   ` Juergen Gross
2021-06-02 10:43     ` Olaf Hering
2021-06-02 11:43       ` Juergen Gross
2021-06-02 12:32   ` [PATCH v20210602 " Olaf Hering
2021-06-02 13:48     ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 03/38] tools: create libxensaverestore Olaf Hering
2021-06-01 16:10 ` [PATCH v20210601 04/38] tools: add readv_exact to libxenctrl Olaf Hering
2021-06-02  6:30   ` Juergen Gross
2021-06-02 10:57     ` Olaf Hering
2021-06-02 11:05       ` Olaf Hering
2021-06-02 11:41       ` Juergen Gross
2021-06-07  9:46         ` Olaf Hering
2021-06-07 11:31         ` Olaf Hering
2021-06-01 16:10 ` [PATCH v20210601 05/38] tools: add xc_is_known_page_type " Olaf Hering
2021-06-02  6:51   ` Juergen Gross
2021-06-02 11:10     ` Olaf Hering
2021-06-02 11:48       ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 06/38] tools: use xc_is_known_page_type Olaf Hering
2021-06-02  6:53   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 07/38] tools: unify type checking for data pfns in migration stream Olaf Hering
2021-06-02  6:59   ` Juergen Gross
2021-06-02 11:21     ` Olaf Hering
2021-06-02 12:03       ` Juergen Gross
2021-06-07 10:12         ` Olaf Hering
2021-06-07 10:22           ` Juergen Gross
2021-06-18 12:25     ` Olaf Hering
2021-06-01 16:10 ` [PATCH v20210601 08/38] tools: show migration transfer rate in send_dirty_pages Olaf Hering
2021-06-02  7:10   ` Juergen Gross
2021-06-08  8:58     ` Olaf Hering
2021-06-08 10:07       ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 09/38] tools/guest: prepare to allocate arrays once Olaf Hering
2021-06-02  7:29   ` Juergen Gross
2021-06-02 12:03     ` Olaf Hering
2021-06-02 12:09       ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 10/38] tools/guest: save: move batch_pfns Olaf Hering
2021-06-02  7:31   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 11/38] tools/guest: save: move mfns array Olaf Hering
2021-06-02  7:32   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 12/38] tools/guest: save: move types array Olaf Hering
2021-06-02  7:32   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 13/38] tools/guest: save: move errors array Olaf Hering
2021-06-02  7:33   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 14/38] tools/guest: save: move iov array Olaf Hering
2021-06-02  7:34   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 15/38] tools/guest: save: move rec_pfns array Olaf Hering
2021-06-02  7:35   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 16/38] tools/guest: save: move guest_data array Olaf Hering
2021-06-02  7:39   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 17/38] tools/guest: save: move local_pages array Olaf Hering
2021-06-02  7:47   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 18/38] tools/guest: restore: move pfns array Olaf Hering
2021-06-02  7:55   ` Juergen Gross
2021-06-01 16:10 ` [PATCH v20210601 19/38] tools/guest: restore: move types array Olaf Hering
2021-06-02  7:56   ` Juergen Gross
2021-06-01 16:11 ` [PATCH v20210601 20/38] tools/guest: restore: move mfns array Olaf Hering
2021-06-02  7:57   ` Juergen Gross
2021-06-01 16:11 ` [PATCH v20210601 21/38] tools/guest: restore: move map_errs array Olaf Hering
2021-06-02  7:58   ` Juergen Gross
2021-06-01 16:11 ` [PATCH v20210601 22/38] tools/guest: restore: move mfns array in populate_pfns Olaf Hering
2021-06-02  7:59   ` Juergen Gross
2021-06-01 16:11 ` [PATCH v20210601 23/38] tools/guest: restore: move pfns " Olaf Hering
2021-06-02  7:59   ` Juergen Gross
2021-06-01 16:11 ` Olaf Hering [this message]
2021-06-02  9:57   ` [PATCH v20210601 24/38] tools/guest: restore: split record processing Juergen Gross
2021-06-01 16:11 ` [PATCH v20210601 25/38] tools/guest: restore: split handle_page_data Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 26/38] tools/guest: restore: write data directly into guest Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 27/38] tools: recognize LIBXL_API_VERSION for 4.16 Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 28/38] tools: adjust libxl_domain_suspend to receive a struct props Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 29/38] tools: change struct precopy_stats to precopy_stats_t Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 30/38] tools: add callback to libxl for precopy_policy and precopy_stats_t Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 31/38] tools: add --max_iters to libxl_domain_suspend Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 32/38] tools: add --min_remaining " Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 33/38] tools: add --abort_if_busy " Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 34/38] tools: add API for expandable bitmaps Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 35/38] tools: use xg_sr_bitmap for populated_pfns Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 36/38] tools: use superpages during restore of HVM guest Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 37/38] tools: remove migration stream verify code Olaf Hering
2021-06-01 16:11 ` [PATCH v20210601 38/38] hotplug/Linux: fix starting of xenstored with restarting systemd Olaf Hering
2021-06-02  6:10 ` [PATCH v20210601 00/38] leftover from 2020 Juergen Gross
2021-06-02  6:54   ` Olaf Hering
2021-06-02  7:00     ` Juergen Gross
2021-06-02 12:07       ` Olaf Hering
2021-06-02 12:15         ` 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=20210601161118.18986-25-olaf@aepfle.de \
    --to=olaf@aepfle.de \
    --cc=iwj@xenproject.org \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.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.