From: Olaf Hering Date: Fri, 23 Oct 2020 14:39:30 +0200 Subject: libxc sr restore pfns tools: restore: preallocate pfns array Remove repeated allocation from migration loop. There will never be more than MAX_BATCH_SIZE pages to process in an incoming batch. Allocate the space once. Adjust the verification for page count. It must be at least one page, but not more than MAX_BATCH_SIZE. Signed-off-by: Olaf Hering --- tools/libs/guest/xg_sr_common.h | 1 + tools/libs/guest/xg_sr_restore.c | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -256,6 +256,7 @@ struct xc_sr_context { struct xc_sr_restore_ops ops; struct restore_callbacks *callbacks; + xen_pfn_t *pfns; int send_back_fd; unsigned long p2m_size; --- a/tools/libs/guest/xg_sr_restore.c +++ b/tools/libs/guest/xg_sr_restore.c @@ -314,7 +314,7 @@ static int handle_page_data(struct xc_sr unsigned int i, pages_of_data = 0; int rc = -1; - xen_pfn_t *pfns = NULL, pfn; + xen_pfn_t pfn; uint32_t *types = NULL, type; /* @@ -349,9 +349,9 @@ static int handle_page_data(struct xc_sr goto err; } - if ( pages->count < 1 ) + if ( !pages->count || pages->count > MAX_BATCH_SIZE ) { - ERROR("Expected at least 1 pfn in PAGE_DATA record"); + ERROR("Unexpected pfn count %u in PAGE_DATA record", pages->count); goto err; } @@ -362,9 +362,8 @@ static int handle_page_data(struct xc_sr goto err; } - pfns = malloc(pages->count * sizeof(*pfns)); types = malloc(pages->count * sizeof(*types)); - if ( !pfns || !types ) + if ( !types ) { ERROR("Unable to allocate enough memory for %u pfns", pages->count); @@ -393,7 +392,7 @@ static int handle_page_data(struct xc_sr * have a page worth of data in the record. */ pages_of_data++; - pfns[i] = pfn; + ctx->restore.pfns[i] = pfn; types[i] = type; } @@ -407,11 +406,10 @@ static int handle_page_data(struct xc_sr goto err; } - rc = process_page_data(ctx, pages->count, pfns, types, + rc = process_page_data(ctx, pages->count, ctx->restore.pfns, types, &pages->pfn[pages->count]); err: free(types); - free(pfns); return rc; } @@ -715,6 +713,14 @@ static int setup(struct xc_sr_context *c goto err; } + ctx->restore.pfns = malloc(MAX_BATCH_SIZE * sizeof(*ctx->restore.pfns)); + if ( !ctx->restore.pfns ) + { + ERROR("Unable to allocate memory"); + rc = -1; + goto err; + } + ctx->restore.buffered_records = malloc( DEFAULT_BUF_RECORDS * sizeof(struct xc_sr_record)); if ( !ctx->restore.buffered_records ) @@ -745,6 +751,7 @@ static void cleanup(struct xc_sr_context free(ctx->restore.buffered_records); free(ctx->restore.populated_pfns); + free(ctx->restore.pfns); if ( ctx->restore.ops.cleanup(ctx) ) PERROR("Failed to clean up");