From patchwork Thu Oct 29 17:19:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olaf Hering X-Patchwork-Id: 11866963 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B0A9914B7 for ; Thu, 29 Oct 2020 17:21:24 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6BAD920759 for ; Thu, 29 Oct 2020 17:21:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=aepfle.de header.i=@aepfle.de header.b="DWa+kVf5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6BAD920759 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=aepfle.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.14432.35745 (Exim 4.92) (envelope-from ) id 1kYBbU-0004FL-Ut; Thu, 29 Oct 2020 17:20:48 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 14432.35745; Thu, 29 Oct 2020 17:20:48 +0000 X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kYBbU-0004Ey-HD; Thu, 29 Oct 2020 17:20:48 +0000 Received: by outflank-mailman (input) for mailman id 14432; Thu, 29 Oct 2020 17:20:46 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kYBbS-0003MD-Nd for xen-devel@lists.xenproject.org; Thu, 29 Oct 2020 17:20:46 +0000 Received: from mo4-p02-ob.smtp.rzone.de (unknown [85.215.255.80]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 61498030-9189-4465-82cd-c67210d36d26; Thu, 29 Oct 2020 17:20:20 +0000 (UTC) Received: from sender by smtp.strato.de (RZmta 47.3.0 DYNA|AUTH) with ESMTPSA id j0b1afw9THKD3fK (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)) (Client did not present a certificate); Thu, 29 Oct 2020 18:20:13 +0100 (CET) Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kYBbS-0003MD-Nd for xen-devel@lists.xenproject.org; Thu, 29 Oct 2020 17:20:46 +0000 X-Inumbo-ID: 61498030-9189-4465-82cd-c67210d36d26 Received: from mo4-p02-ob.smtp.rzone.de (unknown [85.215.255.80]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 61498030-9189-4465-82cd-c67210d36d26; Thu, 29 Oct 2020 17:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1603992020; s=strato-dkim-0002; d=aepfle.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=N7Hr2VOfOon4RnvyU1vv7pvNigOvHS1qA+Cy9MD8+GQ=; b=DWa+kVf573alXYUQYv+wjcgQrPIuU7myRbzKwpdCoRWE9DRENK25z/1AaGfD0aCF85 o8pdJfaRypVXbUERwx4iocR2ikDfsAsc38cr+nddBbATVIQ5sfsq6PGecpaPSzu6Gqng iBSyZjZnoBcmAsxcvym+7scgvaJ2u1eENHTPnuGRF3czC0GJrIfEz6eCrVTlu1jzD/Q6 42LbjhLNBvIhxLniORBCyo4s5VOoN+CX4CaGHOYPPGS4UL5eoNbTt8ionwtiw10WeE5o AqiNkgWfc8Ua5PAZd1L9PH+wCOiJ8Ej9YxI7/gDUvFNLBCPJjyBmXMO9k8t50Cj+5nuK 2jiQ== X-RZG-AUTH: ":P2EQZWCpfu+qG7CngxMFH1J+3q8wa/QXkBR9MXjAuzBW/OdlBZQ4AHSS3G1Jjw==" X-RZG-CLASS-ID: mo00 Received: from sender by smtp.strato.de (RZmta 47.3.0 DYNA|AUTH) with ESMTPSA id j0b1afw9THKD3fK (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)) (Client did not present a certificate); Thu, 29 Oct 2020 18:20:13 +0100 (CET) From: Olaf Hering To: xen-devel@lists.xenproject.org Cc: Olaf Hering , Ian Jackson , Wei Liu , Anthony PERARD Subject: [PATCH v1 14/23] tools/guest: save: move local_pages array Date: Thu, 29 Oct 2020 18:19:54 +0100 Message-Id: <20201029172004.17219-15-olaf@aepfle.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201029172004.17219-1-olaf@aepfle.de> References: <20201029172004.17219-1-olaf@aepfle.de> MIME-Version: 1.0 Remove allocation from hotpath, move local_pages array into preallocated space. Adjust the code to use the src page as is in case of HVM. In case of PV the page may need to be normalised, use an private memory area for this purpose. Signed-off-by: Olaf Hering --- tools/libs/guest/xg_sr_common.h | 22 ++++++++++--------- tools/libs/guest/xg_sr_save.c | 25 +++------------------ tools/libs/guest/xg_sr_save_x86_hvm.c | 5 +++-- tools/libs/guest/xg_sr_save_x86_pv.c | 31 ++++++++++++++++++--------- 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h index 33e66678c6..2a020fef5c 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -33,16 +33,12 @@ struct xc_sr_save_ops * Optionally transform the contents of a page from being specific to the * sending environment, to being generic for the stream. * - * The page of data at the end of 'page' may be a read-only mapping of a - * running guest; it must not be modified. If no transformation is - * required, the callee should leave '*pages' untouched. + * The page of data '*src' may be a read-only mapping of a running guest; + * it must not be modified. If no transformation is required, the callee + * should leave '*src' untouched, and return it via '**ptr'. * - * If a transformation is required, the callee should allocate themselves - * a local page using malloc() and return it via '*page'. - * - * The caller shall free() '*page' in all cases. In the case that the - * callee encounters an error, it should *NOT* free() the memory it - * allocated for '*page'. + * If a transformation is required, the callee should provide the + * transformed page in a private buffer and return it via '**ptr'. * * It is valid to fail with EAGAIN if the transformation is not able to be * completed at this point. The page shall be retried later. @@ -50,7 +46,7 @@ struct xc_sr_save_ops * @returns 0 for success, -1 for failure, with errno appropriately set. */ int (*normalise_page)(struct xc_sr_context *ctx, xen_pfn_t type, - void **page); + void *src, unsigned int idx, void **ptr); /** * Set up local environment to save a domain. (Typically querying @@ -371,6 +367,12 @@ struct xc_sr_context union { + struct + { + /* Used by write_batch for modified pages. */ + void *normalised_pages; + } save; + struct { /* State machine for the order of received records. */ diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c index 658f834ae8..804e4ccb3a 100644 --- a/tools/libs/guest/xg_sr_save.c +++ b/tools/libs/guest/xg_sr_save.c @@ -91,11 +91,10 @@ static int write_batch(struct xc_sr_context *ctx) xen_pfn_t *mfns = ctx->save.m->mfns, *types = ctx->save.m->types; void *guest_mapping = NULL; void **guest_data = ctx->save.m->guest_data; - void **local_pages = NULL; int *errors = ctx->save.m->errors, rc = -1; unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0; unsigned int nr_pfns = ctx->save.nr_batch_pfns; - void *page, *orig_page; + void *src; uint64_t *rec_pfns = ctx->save.m->rec_pfns; struct iovec *iov = ctx->save.m->iov; int iovcnt = 0; struct xc_sr_rec_page_data_header hdr = { 0 }; @@ -105,16 +104,6 @@ static int write_batch(struct xc_sr_context *ctx) assert(nr_pfns != 0); - /* Pointers to locally allocated pages. Need freeing. */ - local_pages = calloc(nr_pfns, sizeof(*local_pages)); - - if ( !local_pages ) - { - ERROR("Unable to allocate arrays for a batch of %u pages", - nr_pfns); - goto err; - } - for ( i = 0; i < nr_pfns; ++i ) { types[i] = mfns[i] = ctx->save.ops.pfn_to_gfn(ctx, @@ -176,11 +165,8 @@ static int write_batch(struct xc_sr_context *ctx) goto err; } - orig_page = page = guest_mapping + (p * PAGE_SIZE); - rc = ctx->save.ops.normalise_page(ctx, types[i], &page); - - if ( orig_page != page ) - local_pages[i] = page; + src = guest_mapping + (p * PAGE_SIZE); + rc = ctx->save.ops.normalise_page(ctx, types[i], src, i, &guest_data[i]); if ( rc ) { @@ -195,8 +181,6 @@ static int write_batch(struct xc_sr_context *ctx) else goto err; } - else - guest_data[i] = page; rc = -1; ++p; @@ -255,9 +239,6 @@ static int write_batch(struct xc_sr_context *ctx) err: if ( guest_mapping ) xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped); - for ( i = 0; local_pages && i < nr_pfns; ++i ) - free(local_pages[i]); - free(local_pages); return rc; } diff --git a/tools/libs/guest/xg_sr_save_x86_hvm.c b/tools/libs/guest/xg_sr_save_x86_hvm.c index 1634a7bc43..11232b9f1d 100644 --- a/tools/libs/guest/xg_sr_save_x86_hvm.c +++ b/tools/libs/guest/xg_sr_save_x86_hvm.c @@ -129,9 +129,10 @@ static xen_pfn_t x86_hvm_pfn_to_gfn(const struct xc_sr_context *ctx, return pfn; } -static int x86_hvm_normalise_page(struct xc_sr_context *ctx, - xen_pfn_t type, void **page) +static int x86_hvm_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type, + void *src, unsigned int idx, void **ptr) { + *ptr = src; return 0; } diff --git a/tools/libs/guest/xg_sr_save_x86_pv.c b/tools/libs/guest/xg_sr_save_x86_pv.c index 4964f1f7b8..8165306354 100644 --- a/tools/libs/guest/xg_sr_save_x86_pv.c +++ b/tools/libs/guest/xg_sr_save_x86_pv.c @@ -999,29 +999,31 @@ static xen_pfn_t x86_pv_pfn_to_gfn(const struct xc_sr_context *ctx, * save_ops function. Performs pagetable normalisation on appropriate pages. */ static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type, - void **page) + void *src, unsigned int idx, void **ptr) { xc_interface *xch = ctx->xch; - void *local_page; int rc; + void *dst; type &= XEN_DOMCTL_PFINFO_LTABTYPE_MASK; if ( type < XEN_DOMCTL_PFINFO_L1TAB || type > XEN_DOMCTL_PFINFO_L4TAB ) + { + *ptr = src; return 0; + } - local_page = malloc(PAGE_SIZE); - if ( !local_page ) + if ( idx >= MAX_BATCH_SIZE ) { - ERROR("Unable to allocate scratch page"); - rc = -1; - goto out; + ERROR("idx %u out of range", idx); + errno = ERANGE; + return -1; } - rc = normalise_pagetable(ctx, *page, local_page, type); - *page = local_page; + dst = ctx->x86.pv.save.normalised_pages + idx * PAGE_SIZE; + rc = normalise_pagetable(ctx, src, dst, type); + *ptr = dst; - out: return rc; } @@ -1031,8 +1033,16 @@ static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type, */ static int x86_pv_setup(struct xc_sr_context *ctx) { + xc_interface *xch = ctx->xch; int rc; + ctx->x86.pv.save.normalised_pages = malloc(MAX_BATCH_SIZE * PAGE_SIZE); + if ( !ctx->x86.pv.save.normalised_pages ) + { + PERROR("Failed to allocate normalised_pages"); + return -1; + } + rc = x86_pv_domain_info(ctx); if ( rc ) return rc; @@ -1118,6 +1128,7 @@ static int x86_pv_check_vm_state(struct xc_sr_context *ctx) static int x86_pv_cleanup(struct xc_sr_context *ctx) { + free(ctx->x86.pv.save.normalised_pages); free(ctx->x86.pv.p2m_pfns); if ( ctx->x86.pv.p2m )