File xen.sr-restore-map_errs.patch of Package xen
From: Olaf Hering <olaf@aepfle.de>
Date: Fri, 23 Oct 2020 14:44:09 +0200
Subject: sr restore map_errs
tools/guest: restore: move map_errs array
Remove allocation from hotpath, move map_errs array into preallocated space.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/libs/guest/xg_sr_common.h | 1 +
tools/libs/guest/xg_sr_restore.c | 12 +-----------
2 files changed, 2 insertions(+), 11 deletions(-)
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -220,24 +220,25 @@ struct xc_sr_save_arrays {
/* write_batch */
uint64_t rec_pfns[MAX_BATCH_SIZE];
/* write_batch: Pointers to page data to send. Mapped gfns or local allocations. */
void *guest_data[MAX_BATCH_SIZE];
};
struct xc_sr_restore_arrays {
/* handle_page_data */
xen_pfn_t pfns[MAX_BATCH_SIZE];
uint32_t types[MAX_BATCH_SIZE];
/* process_page_data */
xen_pfn_t mfns[MAX_BATCH_SIZE];
+ int map_errs[MAX_BATCH_SIZE];
};
struct xc_sr_context
{
xc_interface *xch;
uint32_t domid;
int fd;
/* Plain VM, or checkpoints over time. */
xc_stream_type_t stream_type;
xc_dominfo_t dominfo;
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -197,39 +197,31 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
}
/*
* Given a list of pfns, their types, and a block of page data from the
* stream, populate and record their types, map the relevant subset and copy
* the data into the guest.
*/
static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
xen_pfn_t *pfns, uint32_t *types, void *page_data)
{
xc_interface *xch = ctx->xch;
xen_pfn_t *mfns = ctx->restore.m->mfns;
- int *map_errs = malloc(count * sizeof(*map_errs));
+ int *map_errs = ctx->restore.m->map_errs;
int rc;
void *mapping = NULL, *guest_page = NULL;
unsigned int i, /* i indexes the pfns from the record. */
j, /* j indexes the subset of pfns we decide to map. */
nr_pages = 0;
- if ( !map_errs )
- {
- rc = -1;
- ERROR("Failed to allocate %zu bytes to process page data",
- count * (sizeof(*mfns) + sizeof(*map_errs)));
- goto err;
- }
-
rc = populate_pfns(ctx, count, pfns, types);
if ( rc )
{
ERROR("Failed to populate pfns for batch of %u pages", count);
goto err;
}
for ( i = 0; i < count; ++i )
{
ctx->restore.ops.set_page_type(ctx, pfns[i], types[i]);
if ( page_type_has_stream_data(types[i]) == true )
@@ -289,26 +281,24 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
++j;
guest_page += PAGE_SIZE;
page_data += PAGE_SIZE;
}
done:
rc = 0;
err:
if ( mapping )
xenforeignmemory_unmap(xch->fmem, mapping, nr_pages);
- free(map_errs);
-
return rc;
}
/*
* Validate a PAGE_DATA record from the stream, and pass the results to
* process_page_data() to actually perform the legwork.
*/
static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
{
xc_interface *xch = ctx->xch;
struct xc_sr_rec_page_data_header *pages = rec->data;
unsigned int i, pages_of_data = 0;