File xen.sr-restore-mfns.patch of Package xen
From: Olaf Hering <olaf@aepfle.de>
Date: Fri, 23 Oct 2020 14:42:19 +0200
Subject: sr restore mfns
tools/guest: restore: move mfns array
Remove allocation from hotpath, move mfns array into preallocated space.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/libs/guest/xg_sr_common.h | 2 ++
tools/libs/guest/xg_sr_restore.c | 5 ++---
2 files changed, 4 insertions(+), 3 deletions(-)
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -218,24 +218,26 @@ struct xc_sr_save_arrays {
/* write_batch: iovec[] for writev(). */
struct iovec iov[MAX_BATCH_SIZE + 4];
/* 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];
};
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
@@ -196,33 +196,33 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
return rc;
}
/*
* 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 = malloc(count * sizeof(*mfns));
+ xen_pfn_t *mfns = ctx->restore.m->mfns;
int *map_errs = malloc(count * sizeof(*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 ( !mfns || !map_errs )
+ 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;
@@ -290,25 +290,24 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
guest_page += PAGE_SIZE;
page_data += PAGE_SIZE;
}
done:
rc = 0;
err:
if ( mapping )
xenforeignmemory_unmap(xch->fmem, mapping, nr_pages);
free(map_errs);
- free(mfns);
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;