xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Stefano Stabellini <sstabellini@kernel.org>
To: xen-devel@lists.xen.org
Cc: Stefano Stabellini <stefanos@xilinx.com>,
	sstabellini@kernel.org, wei.liu2@citrix.com,
	blackskygg@gmail.com, ian.jackson@eu.citrix.com,
	julien.grall@arm.com
Subject: [PATCH v9 4/7] libxl: support unmapping static shared memory areas during domain destruction
Date: Wed,  5 Dec 2018 14:16:00 -0800	[thread overview]
Message-ID: <1544048163-27499-4-git-send-email-sstabellini@kernel.org> (raw)
In-Reply-To: <alpine.DEB.2.10.1812051413450.527@sstabellini-ThinkPad-X260>

From: Zhongze Liu <blackskygg@gmail.com>

Add libxl__sshm_del to unmap static shared memory areas mapped by
libxl__sshm_add during domain creation. The unmapping process is:

* For a owner: decrease the refcount of the sshm region, if the refcount
  reaches 0, cleanup the whole sshm path.

* For a borrower:
  1) unmap the shared pages, and cleanup related xs entries. If the
     system works normally, all the shared pages will be unmapped, so there
     won't be page leaks. In case of errors, the unmapping process will go
     on and unmap all the other pages that can be unmapped, so the other
     pages won't be leaked, either.
  2) Decrease the refcount of the sshm region, if the refcount reaches
     0, cleanup the whole sshm path.

This is for the proposal "Allow setting up shared memory areas between VMs
from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Signed-off-by: Zhongze Liu <blackskygg@gmail.com>
Signed-off-by: Stefano Stabellini <stefanos@xilinx.com>

Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Julien Grall <julien.grall@arm.com>
Cc: xen-devel@lists.xen.org

---
Changes in v9:
- rename master to owner and slave to borrower
- remove useless isretry parameter and variable
- code style
- add in-code comments
- call libxl__xs_directory directly
- check errno
- check for count_string == NULL
- fail for cases != owner and != borrower

Changes in v5:
- fix typos
- add comments
- cannot move unmap before xenstore transaction because it needs to
  retrieve begin/size values from xenstore
---
 tools/libxl/libxl_domain.c   |   8 +++
 tools/libxl/libxl_internal.h |   2 +
 tools/libxl/libxl_sshm.c     | 131 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 3377bba..f241edb 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1060,6 +1060,14 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
         goto out;
     }
 
+    /*
+     * Only possible errors are unrecoverable xenstore transaction
+     * errors.
+     */
+    rc = libxl__sshm_del(gc, domid);
+    if (rc)
+        LOGD(ERROR, domid, "Deleting static shm failed.");
+
     if (libxl__device_pci_destroy_all(gc, domid) < 0)
         LOGD(ERROR, domid, "Pci shutdown failed");
     rc = xc_domain_pause(ctx->xch, domid);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 6f31a3d..e86d356 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -4442,6 +4442,8 @@ static inline const char *libxl__qemu_qmp_path(libxl__gc *gc, int domid)
 _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                             libxl_static_shm *sshm, int len);
 
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
 _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                       libxl_static_shm *sshms, int len);
 _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c
index d00981b..8395396 100644
--- a/tools/libxl/libxl_sshm.c
+++ b/tools/libxl/libxl_sshm.c
@@ -94,6 +94,137 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
     return 0;
 }
 
+/*
+ * Decrease the refcount of an sshm. When refcount reaches 0,
+ * clean up the whole sshm path.
+ * Xenstore operations are done within the same transaction.
+ */
+static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt,
+                               const char *sshm_path)
+{
+    int count;
+    const char *count_path, *count_string;
+
+    count_path = GCSPRINTF("%s/usercnt", sshm_path);
+    if (libxl__xs_read_checked(gc, xt, count_path, &count_string) ||
+        count_string == NULL)
+        return;
+    count = atoi(count_string);
+
+    if (--count == 0) {
+        libxl__xs_path_cleanup(gc, xt, sshm_path);
+        return;
+    }
+
+    count_string = GCSPRINTF("%d", count);
+    libxl__xs_write_checked(gc, xt, count_path, count_string);
+
+    return;
+}
+
+static void libxl__sshm_do_unmap(libxl__gc *gc, uint32_t domid, const char *id,
+                                 uint64_t begin, uint64_t size)
+{
+    uint64_t end;
+    begin >>= XC_PAGE_SHIFT;
+    size >>= XC_PAGE_SHIFT;
+    end = begin + size;
+    for (; begin < end; ++begin) {
+        if (xc_domain_remove_from_physmap(CTX->xch, domid, begin)) {
+            SSHM_ERROR(domid, id,
+                       "unable to unmap shared page at 0x%"PRIx64".",
+                       begin);
+        }
+    }
+}
+
+/* unmap static shared memory areas mapped by libxl__sshm_add */
+static void libxl__sshm_del_borrower(libxl__gc *gc, xs_transaction_t xt,
+                                     uint32_t domid, const char *id)
+{
+    const char *borrower_path, *begin_str, *size_str;
+    uint64_t begin, size;
+
+    borrower_path = GCSPRINTF("%s/borrowers/%"PRIu32, SSHM_PATH(id), domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", borrower_path));
+    size_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/size", borrower_path));
+    begin = strtoull(begin_str, NULL, 16);
+    size = strtoull(size_str, NULL, 16);
+
+    libxl__sshm_do_unmap(gc, domid, id, begin, size);
+    libxl__xs_path_cleanup(gc, xt, borrower_path);
+}
+
+/*
+ * Add libxl__sshm_del to unmap static shared memory areas mapped by
+ * libxl__sshm_add during domain creation. The unmapping process is:
+ *
+ * For a owner: decrease the refcount of the sshm region, if the refcount
+ * reaches 0, cleanup the whole sshm path.
+ *
+ * For a borrower:
+ * 1) unmap the shared pages, and cleanup related xs entries. If the
+ *    system works normally, all the shared pages will be unmapped, so there
+ *    won't be page leaks. In case of errors, the unmapping process will go
+ *    on and unmap all the other pages that can be unmapped, so the other
+ *    pages won't be leaked, either.
+ * 2) Decrease the refcount of the sshm region, if the refcount reaches
+ *    0, cleanup the whole sshm path.
+ */
+int libxl__sshm_del(libxl__gc *gc,  uint32_t domid)
+{
+    int rc, i;
+    xs_transaction_t xt = XBT_NULL;
+    const char *dom_path, *dom_sshm_path, *role;
+    char **sshm_ents;
+    unsigned int sshm_num;
+
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    dom_sshm_path = GCSPRINTF("%s/static_shm", dom_path);
+
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &xt);
+        if (rc) goto out;
+
+        sshm_ents = libxl__xs_directory(gc, xt, dom_sshm_path, &sshm_num);
+        if (!sshm_ents) {
+            if (errno != ENOENT) {
+                LOGE(ERROR, "unable to get xenstore device listing %s",
+                     dom_sshm_path);
+                goto out;
+            }
+            continue;
+        }
+
+        for (i = 0; i < sshm_num; ++i) {
+            role = libxl__xs_read(gc, xt,
+                    GCSPRINTF("%s/%s/role",
+                        dom_sshm_path,
+                        sshm_ents[i]));
+            assert(role);
+            if (!strncmp(role, "borrower", 8))
+                libxl__sshm_del_borrower(gc, xt, domid, sshm_ents[i]);
+            else if (strncmp(role, "owner", 5)) {
+                rc = ERROR_INVAL;
+                goto out;
+            }
+
+
+            libxl__sshm_decref(gc, xt, SSHM_PATH(sshm_ents[i]));
+        }
+
+        rc = libxl__xs_transaction_commit(gc, &xt);
+        if (!rc) break;
+        if (rc < 0) goto out;
+    }
+
+    rc = 0;
+out:
+    libxl__xs_transaction_abort(gc, &xt);
+    return rc;
+}
+
 /*   libxl__sshm_do_map -- map pages into borrower's physmap
  *
  *   This functions maps
-- 
1.9.1


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

  parent reply	other threads:[~2018-12-05 22:16 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-05 22:15 [PATCH v9 0/7] Allow setting up shared memory areas between VMs from xl config files Stefano Stabellini
2018-12-05 22:15 ` [PATCH v9 1/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing Stefano Stabellini
2018-12-07 19:33   ` Daniel De Graaf
2018-12-05 22:15 ` [PATCH v9 2/7] libxl: introduce a new structure to represent static shared memory regions Stefano Stabellini
2018-12-05 22:15 ` [PATCH v9 3/7] libxl: support mapping static shared memory areas during domain creation Stefano Stabellini
2018-12-05 22:16 ` Stefano Stabellini [this message]
2018-12-05 22:16 ` [PATCH v9 5/7] libxl:xl: add parsing code to parse "libxl_static_sshm" from xl config files Stefano Stabellini
2018-12-05 22:16 ` [PATCH v9 6/7] docs: documentation about static shared memory regions Stefano Stabellini
2018-12-05 22:16 ` [PATCH v9 7/7] xen/arm: export shared memory regions as reserved-memory on device tree Stefano Stabellini
2018-12-07 21:06   ` Stefano Stabellini

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=1544048163-27499-4-git-send-email-sstabellini@kernel.org \
    --to=sstabellini@kernel.org \
    --cc=blackskygg@gmail.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=julien.grall@arm.com \
    --cc=stefanos@xilinx.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).