All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tamas K Lengyel <tamas.lengyel@intel.com>
To: xen-devel@lists.xenproject.org
Cc: Tamas K Lengyel <tamas.lengyel@intel.com>
Subject: [Xen-devel] [PATCH v6 8/9] x86/mem_sharing: reset a fork
Date: Mon, 27 Jan 2020 10:06:36 -0800	[thread overview]
Message-ID: <de8e30d7bdc25e509f7da0affc9c77f8c1a49599.1580148227.git.tamas.lengyel@intel.com> (raw)
In-Reply-To: <cover.1580148227.git.tamas.lengyel@intel.com>

Implement hypercall that allows a fork to shed all memory that got allocated
for it during its execution and re-load its vCPU context from the parent VM.
This allows the forked VM to reset into the same state the parent VM is in a
faster way then creating a new fork would be. Measurements show about a 2x
speedup during normal fuzzing operations. Performance may vary depending how
much memory got allocated for the forked VM. If it has been completely
deduplicated from the parent VM then creating a new fork would likely be more
performant.

Signed-off-by: Tamas K Lengyel <tamas.lengyel@intel.com>
---
 xen/arch/x86/mm/mem_sharing.c | 76 +++++++++++++++++++++++++++++++++++
 xen/include/public/memory.h   |  1 +
 2 files changed, 77 insertions(+)

diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index b6be78486d..88549db7b2 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -1613,6 +1613,59 @@ static int mem_sharing_fork(struct domain *d, struct domain *cd)
     return rc;
 }
 
+/*
+ * The fork reset operation is intended to be used on short-lived forks only.
+ * There is no hypercall continuation operation implemented for this reason.
+ * For forks that obtain a larger memory footprint it is likely going to be
+ * more performant to create a new fork instead of resetting an existing one.
+ *
+ * TODO: In case this hypercall would become useful on forks with larger memory
+ * footprints the hypercall continuation should be implemented.
+ */
+static int mem_sharing_fork_reset(struct domain *d, struct domain *cd)
+{
+    int rc;
+    struct p2m_domain* p2m = p2m_get_hostp2m(cd);
+    struct page_info *page, *tmp;
+
+    domain_pause(cd);
+
+    page_list_for_each_safe(page, tmp, &cd->page_list)
+    {
+        p2m_type_t p2mt;
+        p2m_access_t p2ma;
+        gfn_t gfn;
+        mfn_t mfn = page_to_mfn(page);
+
+        if ( !mfn_valid(mfn) )
+            continue;
+
+        gfn = mfn_to_gfn(cd, mfn);
+        mfn = __get_gfn_type_access(p2m, gfn_x(gfn), &p2mt, &p2ma,
+                                    0, NULL, false);
+
+        if ( !p2m_is_ram(p2mt) || p2m_is_shared(p2mt) )
+            continue;
+
+        /* take an extra reference */
+        if ( !get_page(page, cd) )
+            continue;
+
+        rc = p2m->set_entry(p2m, gfn, INVALID_MFN, PAGE_ORDER_4K,
+                            p2m_invalid, p2m_access_rwx, -1);
+        ASSERT(!rc);
+
+        put_page_alloc_ref(page);
+        put_page(page);
+    }
+
+    if ( !(rc = hvm_copy_context_and_params(d, cd)) )
+        fork_tsc(d, cd);
+
+    domain_unpause(cd);
+    return rc;
+}
+
 int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg)
 {
     int rc;
@@ -1897,6 +1950,29 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg)
         break;
     }
 
+    case XENMEM_sharing_op_fork_reset:
+    {
+        struct domain *pd;
+
+        rc = -EINVAL;
+        if ( mso.u.fork._pad[0] || mso.u.fork._pad[1] ||
+             mso.u.fork._pad[2] )
+            goto out;
+
+        rc = -ENOSYS;
+        if ( !d->parent )
+            goto out;
+
+        rc = rcu_lock_live_remote_domain_by_id(d->parent->domain_id, &pd);
+        if ( rc )
+            goto out;
+
+        rc = mem_sharing_fork_reset(pd, d);
+
+        rcu_unlock_domain(pd);
+        break;
+    }
+
     default:
         rc = -ENOSYS;
         break;
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 90a3f4498e..e3d063e22e 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -483,6 +483,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t);
 #define XENMEM_sharing_op_audit             7
 #define XENMEM_sharing_op_range_share       8
 #define XENMEM_sharing_op_fork              9
+#define XENMEM_sharing_op_fork_reset        10
 
 #define XENMEM_SHARING_OP_S_HANDLE_INVALID  (-10)
 #define XENMEM_SHARING_OP_C_HANDLE_INVALID  (-9)
-- 
2.20.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2020-01-27 18:35 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1580148227.git.tamas.lengyel@intel.com>
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 1/9] x86/p2m: Allow p2m_get_page_from_gfn to return shared entries Tamas K Lengyel
2020-01-28 16:37   ` Jan Beulich
2020-01-28 16:42     ` Tamas K Lengyel
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 2/9] x86/hvm: introduce hvm_copy_context_and_params Tamas K Lengyel
2020-01-28 16:47   ` Jan Beulich
2020-01-28 16:54     ` Tamas K Lengyel
2020-01-28 16:59       ` Jan Beulich
2020-01-28 17:03         ` Tamas K Lengyel
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 3/9] xen/x86: Make hap_get_allocation accessible Tamas K Lengyel
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 4/9] x86/mem_sharing: Replace MEM_SHARING_DEBUG with gdprintk Tamas K Lengyel
2020-01-28 16:52   ` Jan Beulich
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 5/9] x86/mem_sharing: use default_access in add_to_physmap Tamas K Lengyel
2020-01-28 16:55   ` Jan Beulich
2020-01-28 17:02     ` Tamas K Lengyel
2020-01-29 13:27       ` Jan Beulich
2020-01-29 14:05         ` Tamas K Lengyel
2020-01-29 14:29           ` Tamas K Lengyel
2020-01-29 14:44           ` Jan Beulich
2020-01-29 14:56             ` Tamas K Lengyel
2020-01-29 16:09               ` Tamas K Lengyel
2020-01-29 16:16                 ` Tamas K Lengyel
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 6/9] xen/mem_sharing: VM forking Tamas K Lengyel
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 7/9] xen/mem_access: Use __get_gfn_type_access in set_mem_access Tamas K Lengyel
2020-01-29 13:09   ` Jan Beulich
2020-01-29 13:53     ` Tamas K Lengyel
2020-01-29 14:04       ` Jan Beulich
2020-01-27 18:06 ` Tamas K Lengyel [this message]
2020-01-28 15:13   ` [Xen-devel] [PATCH v6 8/9] x86/mem_sharing: reset a fork Tamas K Lengyel
2020-01-27 18:06 ` [Xen-devel] [PATCH v6 9/9] xen/tools: VM forking toolstack side Tamas K Lengyel

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=de8e30d7bdc25e509f7da0affc9c77f8c1a49599.1580148227.git.tamas.lengyel@intel.com \
    --to=tamas.lengyel@intel.com \
    --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.