All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frediano Ziglio <freddy77@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: "Frediano Ziglio" <frediano.ziglio@citrix.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>,
	"Teddy Astie" <teddy.astie@vates.tech>,
	"Anthony PERARD" <anthony.perard@vates.tech>,
	"Juergen Gross" <jgross@suse.com>
Subject: [PATCH v10 9/10] libs/guest: use new hypercall if available
Date: Mon, 10 Aug 2026 11:30:12 +0100	[thread overview]
Message-ID: <20260810103018.54564-10-frediano.ziglio@citrix.com> (raw)
In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com>

Use new hypercall if available, otherwise fall back to map+copy+unmap
sequence.

I took some statistics while migrating some machines instrumenting the
code to use new and old code and doing it 5 times in a row for each and
the raw operation takes at least 4 (from) or 5 (to) times less.

Specifically for a test done with a machine with Intel Xeon Sapphire
Rapids CPUs and migrating a Windows 10 machine with 12 GB of RAM
the ratios were:
- 4.9 times faster copying from guest to dom0;
- 5.3 times faster copying to guest from dom0.
The test was repeated multiple times resulting consistent in all rans.

Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>
---
Changes since v4:
- use int8_t instead of char for signed type.

Changes since v6:
- add some statistics.

Changes since v9:
- fixed a pointer initialization.
---
 tools/libs/guest/xg_sr_common.c | 47 ++++++++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_common.c
index 90da21c35f..ce5026c707 100644
--- a/tools/libs/guest/xg_sr_common.c
+++ b/tools/libs/guest/xg_sr_common.c
@@ -156,11 +156,6 @@ static void __attribute__((unused)) build_assertions(void)
     BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params)        != 8);
 }
 
-enum {
-    foreigncopy_from,
-    foreigncopy_to
-};
-
 static int xg_foreignmemory_copy(xc_interface *xch, domid_t domid,
                                  int dir, size_t nr_pages, void *buffer,
                                  const xen_pfn_t foreign_pfns[nr_pages])
@@ -174,8 +169,42 @@ static int xg_foreignmemory_copy(xc_interface *xch, domid_t domid,
         return -1;
     }
 
+    /*
+     * If foreign copy is supported, -1 not initialized, 0 not supported,
+     * 1 supported.
+     */
+    static int8_t foreign_copy_supported = -1;
+
+    if ( foreign_copy_supported )
+    {
+        int rc;
+        privcmd_foreigncopy_t copy = {
+            .dom = domid,
+            .dir = dir,
+            .num = nr_pages,
+            .buffer = buffer,
+        };
+        DECLARE_HYPERCALL_BOUNCE_IN(foreign_pfns, nr_pages * sizeof(xen_pfn_t));
+
+        if ( xc_hypercall_bounce_pre(xch, foreign_pfns) )
+            return -1;
+
+        copy.pfns = (xen_pfn_t *)HYPERCALL_BUFFER_AS_ARG(foreign_pfns);
+
+        rc = ioctl(xencall_fd(xch->xcall), IOCTL_PRIVCMD_FOREIGNCOPY, &copy);
+        if ( foreign_copy_supported < 0 )
+            foreign_copy_supported =
+                (!rc || (errno != ENOTTY && errno != ENOSYS));
+
+        xc_hypercall_bounce_post(xch, foreign_pfns);
+
+        if ( foreign_copy_supported )
+            return rc;
+    }
+
+    /* Fallback, emulate. */
     int err[nr_pages];
-    const int prot = (dir == foreigncopy_from) ? PROT_READ : PROT_READ|PROT_WRITE;
+    const int prot = (dir == XENMEM_foreigncopy_from) ? PROT_READ : PROT_READ|PROT_WRITE;
 
     void *p = xenforeignmemory_map(xch->fmem, domid, prot, nr_pages, foreign_pfns, err);
     if ( !p )
@@ -189,7 +218,7 @@ static int xg_foreignmemory_copy(xc_interface *xch, domid_t domid,
             return -1;
         }
 
-    if ( dir == foreigncopy_from )
+    if ( dir == XENMEM_foreigncopy_from )
         memcpy(buffer, p, nr_pages * XC_PAGE_SIZE);
     else
         memcpy(p, buffer, nr_pages * XC_PAGE_SIZE);
@@ -201,7 +230,7 @@ int xg_foreignmemory_copy_from(xc_interface *xch, domid_t dom,
                                size_t nr_pages, void *dest,
                                const xen_pfn_t source[nr_pages])
 {
-    return xg_foreignmemory_copy(xch, dom, foreigncopy_from,
+    return xg_foreignmemory_copy(xch, dom, XENMEM_foreigncopy_from,
                                  nr_pages, dest, source);
 }
 
@@ -209,7 +238,7 @@ int xg_foreignmemory_copy_to(xc_interface *xch, domid_t dom,
                              size_t nr_pages, const xen_pfn_t dest[nr_pages],
                              const void *source)
 {
-    return xg_foreignmemory_copy(xch, dom, foreigncopy_to,
+    return xg_foreignmemory_copy(xch, dom, XENMEM_foreigncopy_to,
                                  nr_pages, (void *) source, dest);
 }
 
-- 
2.43.0



  parent reply	other threads:[~2026-08-10 10:31 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10 10:30 [PATCH v10 0/10] xenguest optimisations Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 1/10] libs/call: cache up to 4 pages in hypercall bounce buffers Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 2/10] libs/guest: move batch_pfns into a separate structure Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 3/10] libs/guest: allocate various migration arrays just once Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 4/10] libs/guest: use Valgrind or sanitizers to detect various buffer overflows Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 5/10] libs/guest: add xg_foreignmemory_copy_{from,to} Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 6/10] libs/guest: use foreign copy API during migration Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 7/10] xen: implement new foreign copy hypercall Frediano Ziglio
2026-08-10 10:30 ` [PATCH v10 8/10] privcmd: Add definition for new Linux privcmd to access new Xen hypercall Frediano Ziglio
2026-08-10 10:30 ` Frediano Ziglio [this message]
2026-08-10 10:30 ` [PATCH Linux v6 10/10] xen/privcmd: Add new ABI to allow copying foreign memory Frediano Ziglio
2026-08-11 11:37 ` [PATCH v10 0/10] xenguest optimisations Anthony PERARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260810103018.54564-10-frediano.ziglio@citrix.com \
    --to=freddy77@gmail.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=anthony.perard@vates.tech \
    --cc=frediano.ziglio@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=roger.pau@citrix.com \
    --cc=teddy.astie@vates.tech \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.