aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_tmem.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-05-26 11:05:04 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-05-26 11:05:04 +0100
commit6009f4ddb2cdb8555d2d5e030d351893e971b995 (patch)
tree6f146a530b5065a1688aa456280f965e1751f2c8 /tools/libxc/xc_tmem.c
parentff811c2bc429a70798cf65913549c0ddaab70c3d (diff)
downloadxen-6009f4ddb2cdb8555d2d5e030d351893e971b995.tar.gz
xen-6009f4ddb2cdb8555d2d5e030d351893e971b995.tar.bz2
xen-6009f4ddb2cdb8555d2d5e030d351893e971b995.zip
Transcendent memory ("tmem") for Xen.
Tmem, when called from a tmem-capable (paravirtualized) guest, makes use of otherwise unutilized ("fallow") memory to create and manage pools of pages that can be accessed from the guest either as "ephemeral" pages or as "persistent" pages. In either case, the pages are not directly addressible by the guest, only copied to and fro via the tmem interface. Ephemeral pages are a nice place for a guest to put recently evicted clean pages that it might need again; these pages can be reclaimed synchronously by Xen for other guests or other uses. Persistent pages are a nice place for a guest to put "swap" pages to avoid sending them to disk. These pages retain data as long as the guest lives, but count against the guest memory allocation. Tmem pages may optionally be compressed and, in certain cases, can be shared between guests. Tmem also handles concurrency nicely and provides limited QoS settings to combat malicious DoS attempts. Save/restore and live migration support is not yet provided. Tmem is primarily targeted for an x86 64-bit hypervisor. On a 32-bit x86 hypervisor, it has limited functionality and testing due to limitations of the xen heap. Nearly all of tmem is architecture-independent; three routines remain to be ported to ia64 and it should work on that architecture too. It is also structured to be portable to non-Xen environments. Tmem defaults off (for now) and must be enabled with a "tmem" xen boot option (and does nothing unless a tmem-capable guest is running). The "tmem_compress" boot option enables compression which takes about 10x more CPU but approximately doubles the number of pages that can be stored. Tmem can be controlled via several "xm" commands and many interesting tmem statistics can be obtained. A README and internal specification will follow, but lots of useful prose about tmem, as well as Linux patches, can be found at http://oss.oracle.com/projects/tmem . Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
Diffstat (limited to 'tools/libxc/xc_tmem.c')
-rw-r--r--tools/libxc/xc_tmem.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/tools/libxc/xc_tmem.c b/tools/libxc/xc_tmem.c
new file mode 100644
index 0000000000..ba618ef98c
--- /dev/null
+++ b/tools/libxc/xc_tmem.c
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * xc_tmem.c
+ *
+ * Copyright (C) 2008 Oracle Corp.
+ */
+
+#include "xc_private.h"
+#include <xen/tmem.h>
+
+static int do_tmem_op(int xc, tmem_op_t *op)
+{
+ int ret;
+ DECLARE_HYPERCALL;
+
+ hypercall.op = __HYPERVISOR_tmem_op;
+ hypercall.arg[0] = (unsigned long)op;
+ if (lock_pages(op, sizeof(*op)) != 0)
+ {
+ PERROR("Could not lock memory for Xen hypercall");
+ return -EFAULT;
+ }
+ if ((ret = do_xen_hypercall(xc, &hypercall)) < 0)
+ {
+ if ( errno == EACCES )
+ DPRINTF("tmem operation failed -- need to"
+ " rebuild the user-space tool set?\n");
+ }
+ unlock_pages(op, sizeof(*op));
+
+ return ret;
+}
+
+int xc_tmem_control(int xc,
+ int32_t pool_id,
+ uint32_t subop,
+ uint32_t cli_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ void *buf)
+{
+ tmem_op_t op;
+ int rc;
+
+ op.cmd = TMEM_CONTROL;
+ op.pool_id = pool_id;
+ op.subop = subop;
+ op.cli_id = cli_id;
+ op.arg1 = arg1;
+ op.arg2 = arg2;
+ op.buf.p = buf;
+
+ if (subop == TMEMC_LIST) {
+ if ((arg1 != 0) && (lock_pages(buf, arg1) != 0))
+ {
+ PERROR("Could not lock memory for Xen hypercall");
+ return -ENOMEM;
+ }
+ }
+
+#ifdef VALGRIND
+ if (arg1 != 0)
+ memset(buf, 0, arg1);
+#endif
+
+ rc = do_tmem_op(xc, &op);
+
+ if (subop == TMEMC_LIST) {
+ if (arg1 != 0)
+ unlock_pages(buf, arg1);
+ }
+
+ return rc;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */