[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 5 of 12] libxl: adds few more memory operations



libxl_domain_need_memory: calculate how much memory a domain needs in
order to be built and start correctly.

libxl_get_free_memory: calculate the total free memory in the system.

libxl_wait_for_free_memory: wait for a certain amount of memory to
become free in the system.

libxl_wait_for_memory_target: wait for a domain to reach its memory
target.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

diff -r 0c3fa43db985 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Fri Sep 03 11:47:07 2010 +0100
+++ b/tools/libxl/libxl.c       Fri Sep 03 11:47:45 2010 +0100
@@ -2756,9 +2756,11 @@ static int libxl__fill_dom0_memory_info(
 {
     int rc;
     libxl_dominfo info;
+    libxl_physinfo physinfo;
     char *target = NULL, *endptr = NULL;
     char *target_path = "/local/domain/0/memory/target";
     char *max_path = "/local/domain/0/memory/static-max";
+    char *free_mem_slack_path = "/local/domain/0/memory/freemem-slack";
     xs_transaction_t t;
     libxl_ctx *ctx = libxl_gc_owner(gc);
 
@@ -2782,10 +2784,16 @@ retry_transaction:
     if (rc < 0)
         return rc;
 
+    rc = libxl_get_physinfo(ctx, &physinfo);
+    if (rc < 0)
+        return rc;
+
     libxl_xs_write(gc, t, target_path, "%"PRIu32,
             (uint32_t) info.current_memkb);
     libxl_xs_write(gc, t, max_path, "%"PRIu32,
             (uint32_t) info.max_memkb);
+    libxl_xs_write(gc, t, free_mem_slack_path, "%"PRIu32, (uint32_t)
+            (PAGE_TO_MEMKB(physinfo.total_pages) - info.current_memkb));
 
     *target_memkb = (uint32_t) info.current_memkb;
     rc = 0;
@@ -2799,6 +2807,33 @@ out:
     return rc;
 }
 
+/* returns how much memory should be left free in the system */
+static int libxl__get_free_memory_slack(libxl_gc *gc, uint32_t *free_mem_slack)
+{
+    int rc;
+    char *free_mem_slack_path = "/local/domain/0/memory/freemem-slack";
+    char *free_mem_slack_s, *endptr;
+    uint32_t target_memkb;
+
+retry:
+    free_mem_slack_s = libxl_xs_read(gc, XBT_NULL, free_mem_slack_path);
+    if (!free_mem_slack_s) {
+        rc = libxl__fill_dom0_memory_info(gc, &target_memkb);
+        if (rc < 0)
+            return rc;
+        goto retry;
+    } else {
+        *free_mem_slack = strtoul(free_mem_slack_s, &endptr, 10);
+        if (*endptr != '\0') {
+            XL_LOG_ERRNO(gc->owner, XL_LOG_ERROR,
+                    "invalid free_mem_slack %s from %s\n",
+                    free_mem_slack_s, free_mem_slack_path);
+            return ERROR_FAIL;
+        }
+    }
+    return 0;
+}
+
 int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
         int32_t target_memkb, int relative, int enforce)
 {
@@ -2957,6 +2992,102 @@ out:
     return rc;
 }
 
+int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
+        libxl_device_model_info *dm_info, uint32_t *need_memkb)
+{
+    *need_memkb = b_info->target_memkb;
+    if (b_info->hvm) {
+        *need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
+        if (strstr(dm_info->device_model, "stubdom-dm"))
+            *need_memkb += 32 * 1024;
+    } else
+        *need_memkb += LIBXL_PV_EXTRA_MEMORY;
+    if (*need_memkb % (2 * 1024))
+        *need_memkb += (2 * 1024) - (*need_memkb % (2 * 1024));
+    return 0;
+}
+
+int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb)
+{
+    int rc = 0;
+    libxl_physinfo info;
+    uint32_t freemem_slack;
+    libxl_gc gc = LIBXL_INIT_GC(ctx);
+
+    rc = libxl_get_physinfo(ctx, &info);
+    if (rc < 0)
+        goto out;
+    rc = libxl__get_free_memory_slack(&gc, &freemem_slack);
+    if (rc < 0)
+        goto out;
+
+    if ((info.free_pages + info.scrub_pages) * 4 > freemem_slack)
+        *memkb = (info.free_pages + info.scrub_pages) * 4 - freemem_slack;
+    else
+        *memkb = 0;
+
+out:
+    libxl_free_all(&gc);
+    return rc;
+}
+
+int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t
+        memory_kb, int wait_secs)
+{
+    int rc = 0;
+    libxl_physinfo info;
+    uint32_t freemem_slack;
+    libxl_gc gc = LIBXL_INIT_GC(ctx);
+
+    rc = libxl__get_free_memory_slack(&gc, &freemem_slack);
+    if (rc < 0)
+        goto out;
+    while (wait_secs > 0) {
+        rc = libxl_get_physinfo(ctx, &info);
+        if (rc < 0)
+            goto out;
+        if (info.free_pages * 4 - freemem_slack >= memory_kb) {
+            rc = 0;
+            goto out;
+        }
+        wait_secs--;
+        sleep(1);
+    }
+    rc = ERROR_NOMEM;
+
+out:
+    libxl_free_all(&gc);
+    return rc;
+}
+
+int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
+{
+    int rc = 0;
+    uint32_t target_memkb = 0;
+    libxl_dominfo info;
+
+    do {
+        wait_secs--;
+        sleep(1);
+
+        rc = libxl_get_memory_target(ctx, domid, &target_memkb);
+        if (rc < 0)
+            goto out;
+
+        rc = libxl_domain_info(ctx, &info, domid);
+        if (rc < 0)
+            return rc;
+    } while (wait_secs > 0 && info.current_memkb > target_memkb);
+
+    if (info.current_memkb <= target_memkb)
+        rc = 0;
+    else
+        rc = ERROR_FAIL;
+
+out:
+    return 0;
+}
+
 int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button)
 {
     int rc = -1;
diff -r 0c3fa43db985 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Fri Sep 03 11:47:07 2010 +0100
+++ b/tools/libxl/libxl.h       Fri Sep 03 11:47:45 2010 +0100
@@ -317,6 +317,15 @@ int libxl_domain_core_dump(libxl_ctx *ct
 int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t 
target_memkb);
 int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t 
target_memkb, int relative, int enforce);
 int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t 
*out_target);
+/* how much free memory in the system a domain needs to be built */
+int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
+        libxl_device_model_info *dm_info, uint32_t *need_memkb);
+/* how much free memory is available in the system */
+int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb);
+/* wait for a given amount of memory to be free in the system */
+int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t 
memory_kb, int wait_secs);
+/* wait for the memory target of a domain to be reached */
+int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int 
wait_secs);
 
 int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass);
 int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, 
libxl_console_constype type);
diff -r 0c3fa43db985 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Fri Sep 03 11:47:07 2010 +0100
+++ b/tools/libxl/libxl_internal.h      Fri Sep 03 11:47:45 2010 +0100
@@ -41,6 +41,8 @@
 #define LIBXL_XENCONSOLE_LIMIT 1048576
 #define LIBXL_XENCONSOLE_PROTOCOL "vt100"
 #define LIBXL_MAXMEM_CONSTANT 1024
+#define LIBXL_PV_EXTRA_MEMORY 1024
+#define LIBXL_HVM_EXTRA_MEMORY 2048
 #define QEMU_SIGNATURE "QemuDeviceModelRecord"
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.