debuggers.hg

changeset 22245:7659c107b2f3

libxl: add 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.

[fixed up for conflicts with libxl__ naming policy changes -iwj]

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
date Wed Sep 22 17:39:32 2010 +0100 (2010-09-22)
parents 4b00f89e15f1
children 49a3c1721734
files tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_internal.h
line diff
     1.1 --- a/tools/libxl/libxl.c	Wed Sep 22 17:37:09 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Wed Sep 22 17:39:32 2010 +0100
     1.3 @@ -2778,9 +2778,11 @@ static int libxl__fill_dom0_memory_info(
     1.4  {
     1.5      int rc;
     1.6      libxl_dominfo info;
     1.7 +    libxl_physinfo physinfo;
     1.8      char *target = NULL, *endptr = NULL;
     1.9      char *target_path = "/local/domain/0/memory/target";
    1.10      char *max_path = "/local/domain/0/memory/static-max";
    1.11 +    char *free_mem_slack_path = "/local/domain/0/memory/freemem-slack";
    1.12      xs_transaction_t t;
    1.13      libxl_ctx *ctx = libxl__gc_owner(gc);
    1.14  
    1.15 @@ -2804,10 +2806,16 @@ retry_transaction:
    1.16      if (rc < 0)
    1.17          return rc;
    1.18  
    1.19 +    rc = libxl_get_physinfo(ctx, &physinfo);
    1.20 +    if (rc < 0)
    1.21 +        return rc;
    1.22 +
    1.23      libxl__xs_write(gc, t, target_path, "%"PRIu32,
    1.24              (uint32_t) info.current_memkb);
    1.25      libxl__xs_write(gc, t, max_path, "%"PRIu32,
    1.26              (uint32_t) info.max_memkb);
    1.27 +    libxl__xs_write(gc, t, free_mem_slack_path, "%"PRIu32, (uint32_t)
    1.28 +            (PAGE_TO_MEMKB(physinfo.total_pages) - info.current_memkb));
    1.29  
    1.30      *target_memkb = (uint32_t) info.current_memkb;
    1.31      rc = 0;
    1.32 @@ -2821,6 +2829,33 @@ out:
    1.33      return rc;
    1.34  }
    1.35  
    1.36 +/* returns how much memory should be left free in the system */
    1.37 +static int libxl__get_free_memory_slack(libxl__gc *gc, uint32_t *free_mem_slack)
    1.38 +{
    1.39 +    int rc;
    1.40 +    char *free_mem_slack_path = "/local/domain/0/memory/freemem-slack";
    1.41 +    char *free_mem_slack_s, *endptr;
    1.42 +    uint32_t target_memkb;
    1.43 +
    1.44 +retry:
    1.45 +    free_mem_slack_s = libxl__xs_read(gc, XBT_NULL, free_mem_slack_path);
    1.46 +    if (!free_mem_slack_s) {
    1.47 +        rc = libxl__fill_dom0_memory_info(gc, &target_memkb);
    1.48 +        if (rc < 0)
    1.49 +            return rc;
    1.50 +        goto retry;
    1.51 +    } else {
    1.52 +        *free_mem_slack = strtoul(free_mem_slack_s, &endptr, 10);
    1.53 +        if (*endptr != '\0') {
    1.54 +            LIBXL__LOG_ERRNO(gc->owner, LIBXL__LOG_ERROR,
    1.55 +                    "invalid free_mem_slack %s from %s\n",
    1.56 +                    free_mem_slack_s, free_mem_slack_path);
    1.57 +            return ERROR_FAIL;
    1.58 +        }
    1.59 +    }
    1.60 +    return 0;
    1.61 +}
    1.62 +
    1.63  int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid,
    1.64          int32_t target_memkb, int relative, int enforce)
    1.65  {
    1.66 @@ -2979,6 +3014,102 @@ out:
    1.67      return rc;
    1.68  }
    1.69  
    1.70 +int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
    1.71 +        libxl_device_model_info *dm_info, uint32_t *need_memkb)
    1.72 +{
    1.73 +    *need_memkb = b_info->target_memkb;
    1.74 +    if (b_info->hvm) {
    1.75 +        *need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
    1.76 +        if (strstr(dm_info->device_model, "stubdom-dm"))
    1.77 +            *need_memkb += 32 * 1024;
    1.78 +    } else
    1.79 +        *need_memkb += LIBXL_PV_EXTRA_MEMORY;
    1.80 +    if (*need_memkb % (2 * 1024))
    1.81 +        *need_memkb += (2 * 1024) - (*need_memkb % (2 * 1024));
    1.82 +    return 0;
    1.83 +}
    1.84 +
    1.85 +int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb)
    1.86 +{
    1.87 +    int rc = 0;
    1.88 +    libxl_physinfo info;
    1.89 +    uint32_t freemem_slack;
    1.90 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
    1.91 +
    1.92 +    rc = libxl_get_physinfo(ctx, &info);
    1.93 +    if (rc < 0)
    1.94 +        goto out;
    1.95 +    rc = libxl__get_free_memory_slack(&gc, &freemem_slack);
    1.96 +    if (rc < 0)
    1.97 +        goto out;
    1.98 +
    1.99 +    if ((info.free_pages + info.scrub_pages) * 4 > freemem_slack)
   1.100 +        *memkb = (info.free_pages + info.scrub_pages) * 4 - freemem_slack;
   1.101 +    else
   1.102 +        *memkb = 0;
   1.103 +
   1.104 +out:
   1.105 +    libxl__free_all(&gc);
   1.106 +    return rc;
   1.107 +}
   1.108 +
   1.109 +int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t
   1.110 +        memory_kb, int wait_secs)
   1.111 +{
   1.112 +    int rc = 0;
   1.113 +    libxl_physinfo info;
   1.114 +    uint32_t freemem_slack;
   1.115 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   1.116 +
   1.117 +    rc = libxl__get_free_memory_slack(&gc, &freemem_slack);
   1.118 +    if (rc < 0)
   1.119 +        goto out;
   1.120 +    while (wait_secs > 0) {
   1.121 +        rc = libxl_get_physinfo(ctx, &info);
   1.122 +        if (rc < 0)
   1.123 +            goto out;
   1.124 +        if (info.free_pages * 4 - freemem_slack >= memory_kb) {
   1.125 +            rc = 0;
   1.126 +            goto out;
   1.127 +        }
   1.128 +        wait_secs--;
   1.129 +        sleep(1);
   1.130 +    }
   1.131 +    rc = ERROR_NOMEM;
   1.132 +
   1.133 +out:
   1.134 +    libxl__free_all(&gc);
   1.135 +    return rc;
   1.136 +}
   1.137 +
   1.138 +int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
   1.139 +{
   1.140 +    int rc = 0;
   1.141 +    uint32_t target_memkb = 0;
   1.142 +    libxl_dominfo info;
   1.143 +
   1.144 +    do {
   1.145 +        wait_secs--;
   1.146 +        sleep(1);
   1.147 +
   1.148 +        rc = libxl_get_memory_target(ctx, domid, &target_memkb);
   1.149 +        if (rc < 0)
   1.150 +            goto out;
   1.151 +
   1.152 +        rc = libxl_domain_info(ctx, &info, domid);
   1.153 +        if (rc < 0)
   1.154 +            return rc;
   1.155 +    } while (wait_secs > 0 && info.current_memkb > target_memkb);
   1.156 +
   1.157 +    if (info.current_memkb <= target_memkb)
   1.158 +        rc = 0;
   1.159 +    else
   1.160 +        rc = ERROR_FAIL;
   1.161 +
   1.162 +out:
   1.163 +    return 0;
   1.164 +}
   1.165 +
   1.166  int libxl_button_press(libxl_ctx *ctx, uint32_t domid, libxl_button button)
   1.167  {
   1.168      int rc = -1;
     2.1 --- a/tools/libxl/libxl.h	Wed Sep 22 17:37:09 2010 +0100
     2.2 +++ b/tools/libxl/libxl.h	Wed Sep 22 17:39:32 2010 +0100
     2.3 @@ -334,6 +334,15 @@ int libxl_domain_core_dump(libxl_ctx *ct
     2.4  int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb);
     2.5  int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t target_memkb, int relative, int enforce);
     2.6  int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target);
     2.7 +/* how much free memory in the system a domain needs to be built */
     2.8 +int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
     2.9 +        libxl_device_model_info *dm_info, uint32_t *need_memkb);
    2.10 +/* how much free memory is available in the system */
    2.11 +int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb);
    2.12 +/* wait for a given amount of memory to be free in the system */
    2.13 +int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t memory_kb, int wait_secs);
    2.14 +/* wait for the memory target of a domain to be reached */
    2.15 +int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs);
    2.16  
    2.17  int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass);
    2.18  int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, libxl_console_constype type);
     3.1 --- a/tools/libxl/libxl_internal.h	Wed Sep 22 17:37:09 2010 +0100
     3.2 +++ b/tools/libxl/libxl_internal.h	Wed Sep 22 17:39:32 2010 +0100
     3.3 @@ -41,6 +41,8 @@
     3.4  #define LIBXL_XENCONSOLE_LIMIT 1048576
     3.5  #define LIBXL_XENCONSOLE_PROTOCOL "vt100"
     3.6  #define LIBXL_MAXMEM_CONSTANT 1024
     3.7 +#define LIBXL_PV_EXTRA_MEMORY 1024
     3.8 +#define LIBXL_HVM_EXTRA_MEMORY 2048
     3.9  #define QEMU_SIGNATURE "QemuDeviceModelRecord"
    3.10  
    3.11  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))