198 lines
6.2 KiB
Diff
198 lines
6.2 KiB
Diff
|
From: Olaf Hering <olaf@aepfle.de>
|
||
|
Date: Fri, 5 Feb 2021 20:16:02 +0100
|
||
|
Subject: libxc sr xg_sr_bitmap populated_pfns
|
||
|
|
||
|
tools: use xg_sr_bitmap for populated_pfns
|
||
|
|
||
|
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||
|
---
|
||
|
tools/libs/guest/xg_sr_common.h | 20 ++++++-
|
||
|
tools/libs/guest/xg_sr_restore.c | 69 ------------------------
|
||
|
tools/libs/guest/xg_sr_restore_x86_hvm.c | 9 ++++
|
||
|
tools/libs/guest/xg_sr_restore_x86_pv.c | 7 +++
|
||
|
4 files changed, 34 insertions(+), 71 deletions(-)
|
||
|
|
||
|
--- a/tools/libs/guest/xg_sr_common.h
|
||
|
+++ b/tools/libs/guest/xg_sr_common.h
|
||
|
@@ -375,8 +375,7 @@ struct xc_sr_context
|
||
|
uint32_t xenstore_domid, console_domid;
|
||
|
|
||
|
/* Bitmap of currently populated PFNs during restore. */
|
||
|
- unsigned long *populated_pfns;
|
||
|
- xen_pfn_t max_populated_pfn;
|
||
|
+ struct sr_bitmap populated_pfns;
|
||
|
|
||
|
/* Sender has invoked verify mode on the stream. */
|
||
|
bool verify;
|
||
|
@@ -632,6 +631,23 @@ static inline bool page_type_has_stream_
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+static inline bool pfn_is_populated(struct xc_sr_context *ctx, xen_pfn_t pfn)
|
||
|
+{
|
||
|
+ return sr_test_bit(pfn, &ctx->restore.populated_pfns);
|
||
|
+}
|
||
|
+
|
||
|
+static inline int pfn_set_populated(struct xc_sr_context *ctx, xen_pfn_t pfn)
|
||
|
+{
|
||
|
+ xc_interface *xch = ctx->xch;
|
||
|
+
|
||
|
+ if ( sr_set_bit(pfn, &ctx->restore.populated_pfns) == false )
|
||
|
+ {
|
||
|
+ PERROR("Failed to realloc populated_pfns bitmap");
|
||
|
+ errno = ENOMEM;
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
#endif
|
||
|
/*
|
||
|
* Local variables:
|
||
|
--- a/tools/libs/guest/xg_sr_restore.c
|
||
|
+++ b/tools/libs/guest/xg_sr_restore.c
|
||
|
@@ -72,64 +72,6 @@ static int read_headers(struct xc_sr_con
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * Is a pfn populated?
|
||
|
- */
|
||
|
-static bool pfn_is_populated(const struct xc_sr_context *ctx, xen_pfn_t pfn)
|
||
|
-{
|
||
|
- if ( pfn > ctx->restore.max_populated_pfn )
|
||
|
- return false;
|
||
|
- return test_bit(pfn, ctx->restore.populated_pfns);
|
||
|
-}
|
||
|
-
|
||
|
-/*
|
||
|
- * Set a pfn as populated, expanding the tracking structures if needed. To
|
||
|
- * avoid realloc()ing too excessively, the size increased to the nearest power
|
||
|
- * of two large enough to contain the required pfn.
|
||
|
- */
|
||
|
-static int pfn_set_populated(struct xc_sr_context *ctx, xen_pfn_t pfn)
|
||
|
-{
|
||
|
- xc_interface *xch = ctx->xch;
|
||
|
-
|
||
|
- if ( pfn > ctx->restore.max_populated_pfn )
|
||
|
- {
|
||
|
- xen_pfn_t new_max;
|
||
|
- size_t old_sz, new_sz;
|
||
|
- unsigned long *p;
|
||
|
-
|
||
|
- /* Round up to the nearest power of two larger than pfn, less 1. */
|
||
|
- new_max = pfn;
|
||
|
- new_max |= new_max >> 1;
|
||
|
- new_max |= new_max >> 2;
|
||
|
- new_max |= new_max >> 4;
|
||
|
- new_max |= new_max >> 8;
|
||
|
- new_max |= new_max >> 16;
|
||
|
-#ifdef __x86_64__
|
||
|
- new_max |= new_max >> 32;
|
||
|
-#endif
|
||
|
-
|
||
|
- old_sz = bitmap_size(ctx->restore.max_populated_pfn + 1);
|
||
|
- new_sz = bitmap_size(new_max + 1);
|
||
|
- p = realloc(ctx->restore.populated_pfns, new_sz);
|
||
|
- if ( !p )
|
||
|
- {
|
||
|
- ERROR("Failed to realloc populated bitmap");
|
||
|
- errno = ENOMEM;
|
||
|
- return -1;
|
||
|
- }
|
||
|
-
|
||
|
- memset((uint8_t *)p + old_sz, 0x00, new_sz - old_sz);
|
||
|
-
|
||
|
- ctx->restore.populated_pfns = p;
|
||
|
- ctx->restore.max_populated_pfn = new_max;
|
||
|
- }
|
||
|
-
|
||
|
- assert(!test_bit(pfn, ctx->restore.populated_pfns));
|
||
|
- set_bit(pfn, ctx->restore.populated_pfns);
|
||
|
-
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-/*
|
||
|
* Given a set of pfns, obtain memory from Xen to fill the physmap for the
|
||
|
* unpopulated subset. If types is NULL, no page type checking is performed
|
||
|
* and all unpopulated pfns are populated.
|
||
|
@@ -911,16 +853,6 @@ static int setup(struct xc_sr_context *c
|
||
|
if ( rc )
|
||
|
goto err;
|
||
|
|
||
|
- ctx->restore.max_populated_pfn = (32 * 1024 / 4) - 1;
|
||
|
- ctx->restore.populated_pfns = bitmap_alloc(
|
||
|
- ctx->restore.max_populated_pfn + 1);
|
||
|
- if ( !ctx->restore.populated_pfns )
|
||
|
- {
|
||
|
- ERROR("Unable to allocate memory for populated_pfns bitmap");
|
||
|
- rc = -1;
|
||
|
- goto err;
|
||
|
- }
|
||
|
-
|
||
|
ctx->restore.pfns = malloc(MAX_BATCH_SIZE * sizeof(*ctx->restore.pfns));
|
||
|
ctx->restore.types = malloc(MAX_BATCH_SIZE * sizeof(*ctx->restore.types));
|
||
|
ctx->restore.mfns = malloc(MAX_BATCH_SIZE * sizeof(*ctx->restore.mfns));
|
||
|
@@ -969,7 +901,6 @@ static void cleanup(struct xc_sr_context
|
||
|
xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->restore.p2m_size)));
|
||
|
|
||
|
free(ctx->restore.buffered_records);
|
||
|
- free(ctx->restore.populated_pfns);
|
||
|
free(ctx->restore.pages);
|
||
|
free(ctx->restore.iov);
|
||
|
free(ctx->restore.guest_data);
|
||
|
--- a/tools/libs/guest/xg_sr_restore_x86_hvm.c
|
||
|
+++ b/tools/libs/guest/xg_sr_restore_x86_hvm.c
|
||
|
@@ -136,6 +136,7 @@ static int x86_hvm_localise_page(struct
|
||
|
static int x86_hvm_setup(struct xc_sr_context *ctx)
|
||
|
{
|
||
|
xc_interface *xch = ctx->xch;
|
||
|
+ unsigned long max_pfn, max_pages = ctx->dominfo.max_pages;
|
||
|
|
||
|
if ( ctx->restore.guest_type != DHDR_TYPE_X86_HVM )
|
||
|
{
|
||
|
@@ -161,6 +162,13 @@ static int x86_hvm_setup(struct xc_sr_co
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
+ max_pfn = max(ctx->restore.p2m_size, max_pages);
|
||
|
+ if ( !sr_bitmap_expand(&ctx->restore.populated_pfns, max_pfn) )
|
||
|
+ {
|
||
|
+ PERROR("Unable to allocate memory for populated_pfns bitmap");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -241,6 +249,7 @@ static int x86_hvm_stream_complete(struc
|
||
|
|
||
|
static int x86_hvm_cleanup(struct xc_sr_context *ctx)
|
||
|
{
|
||
|
+ sr_bitmap_free(&ctx->restore.populated_pfns);
|
||
|
free(ctx->x86.hvm.restore.context.ptr);
|
||
|
|
||
|
free(ctx->x86.restore.cpuid.ptr);
|
||
|
--- a/tools/libs/guest/xg_sr_restore_x86_pv.c
|
||
|
+++ b/tools/libs/guest/xg_sr_restore_x86_pv.c
|
||
|
@@ -1060,6 +1060,12 @@ static int x86_pv_setup(struct xc_sr_con
|
||
|
if ( rc )
|
||
|
return rc;
|
||
|
|
||
|
+ if ( !sr_bitmap_expand(&ctx->restore.populated_pfns, 32 * 1024 / 4) )
|
||
|
+ {
|
||
|
+ PERROR("Unable to allocate memory for populated_pfns bitmap");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
ctx->x86.pv.restore.nr_vcpus = ctx->dominfo.max_vcpu_id + 1;
|
||
|
ctx->x86.pv.restore.vcpus = calloc(sizeof(struct xc_sr_x86_pv_restore_vcpu),
|
||
|
ctx->x86.pv.restore.nr_vcpus);
|
||
|
@@ -1153,6 +1159,7 @@ static int x86_pv_stream_complete(struct
|
||
|
*/
|
||
|
static int x86_pv_cleanup(struct xc_sr_context *ctx)
|
||
|
{
|
||
|
+ sr_bitmap_free(&ctx->restore.populated_pfns);
|
||
|
free(ctx->x86.pv.p2m);
|
||
|
free(ctx->x86.pv.p2m_pfns);
|
||
|
|