[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] RFC: initial libxl support for xenpaging
# HG changeset patch # User Olaf Hering <olaf@xxxxxxxxx> # Date 1329378376 -3600 # Node ID d368cf36d66c1e8df60bd0a4868c171b6a929edc # Parent bf0a7c205687857a8f8d3bd3841654ed61828193 RFC: initial libxl support for xenpaging After the previous discussion about integration of xenpaging into xl/libxl it was not clear to me wether my proposal as a whole or only parts of it were rejected. So here is my current understanding of the comments I received. Add initial support to libxl to start xenpaging for a HVM guest. These are the considerations: - a knob in domU.cfg is needed to start xenpaging - xenpaging needs a target in KiB in "memory/target-tot_pages" -> the knob should be the target value in MiB: mem_target_paging=NUM if the value is 0, xenpaging is not started - an cmdline interface is needed to adjust "memory/target-tot_pages" at runtime -> it was suggested to use 'xl mem-set' which should adjust both "memory/target" and "memory/target-tot_pages" at the same time -> maybe another cmdline interface should be 'xl mem-target-paging' which adjusts "memory/target-tot_pages", and maybe 'xl mem-target-balloon' which adjusts "memory/target" - libxl starts xenpaging with at least two cmdline options which specifys the pagefile to use and the dom_id. An optional "xenpaging_file=path" specifies the pagefile name. Optional additional cmdline options for xenpaging can be specified with a domU.cfg option "xenpaging_extra=[ 'opt', 'opt' ]" - currently maxmem= + memory= and mem_target_paging= can not be used because paging for a PoD guest is not implemented. This does not affect ballooning within the guest. - I have some ideas to add runtime tuneables for xenpaging. Should there be a "xl xenpaging_ctrl tuneable_name value" command, or should it be done with a new tool xenpaging_ctrl? If the latter, the proposed 'xl mem-target-*' commands are not needed and this new helper could also adjust "memory/target-tot_pages". The patch below is just a forward port of my previous version. It adds three new config options, no xl or other changes: mem_target_paging=<int>, the amount of memory in MiB for the guest xenpaging_file=<string>, pagefile to use (optional) xenpaging_extra=[ 'string', 'string' ], optional cmdline args for xenpaging If 'mem_target_paging=' is not specified in config file, xenpaging will not start. If 'xenpaging_file=' is not specified in config file, /var/lib/xen/xenpaging/<domain_name>.<domaind_id>.paging is used. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> diff -r bf0a7c205687 -r d368cf36d66c tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -322,6 +322,7 @@ int libxl_init_build_info(libxl_ctx *ctx typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv); int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid); int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd); +int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config, uint32_t domid, char *path); void libxl_domain_config_dispose(libxl_domain_config *d_config); int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, uint32_t domid, int fd); diff -r bf0a7c205687 -r d368cf36d66c tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -457,6 +457,132 @@ static int store_libxl_entry(libxl__gc * libxl_device_model_version_to_string(b_info->device_model_version)); } +static int create_xenpaging(libxl__gc *gc, char *dom_name, uint32_t domid, + libxl_domain_build_info *b_info) +{ + libxl__spawner_starting *buf_starting; + libxl_string_list xpe = b_info->u.hvm.xenpaging_extra; + int i, rc; + char *logfile; + int logfile_w, null, need_pagefile; + char *path, *dom_path, *value; + char **args; + char *xp; + flexarray_t *xp_args; + libxl_ctx *ctx = libxl__gc_owner(gc); + + /* Nothing to do */ + if (!b_info->tot_memkb) + return 0; + + /* Check if paging is already enabled */ + dom_path = libxl__xs_get_dompath(gc, domid); + if (!dom_path ) { + rc = ERROR_NOMEM; + goto out; + } + path = libxl__sprintf(gc, "%s/xenpaging/state", dom_path); + if (!path ) { + rc = ERROR_NOMEM; + goto out; + } + value = xs_read(ctx->xsh, XBT_NULL, path, NULL); + rc = value && strcmp(value, "running") == 0; + free(value); + /* Already running, nothing to do */ + if (rc) + return 0; + + /* Check if xenpaging is present */ + xp = libxl__abs_path(gc, "xenpaging", libxl_libexec_path()); + if (access(xp, X_OK) < 0) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "%s is not executable", xp); + rc = ERROR_FAIL; + goto out; + } + + /* Initialise settings for child */ + buf_starting = calloc(sizeof(*buf_starting), 1); + if (!buf_starting) { + rc = ERROR_NOMEM; + goto out; + } + buf_starting->domid = domid; + buf_starting->dom_path = dom_path; + buf_starting->pid_path = "xenpaging/xenpaging-pid"; + buf_starting->for_spawn = calloc(sizeof(libxl__spawn_starting), 1); + if (!buf_starting->for_spawn) { + rc = ERROR_NOMEM; + goto out; + } + + /* Assemble arguments for xenpaging */ + xp_args = flexarray_make(8, 1); + if (!xp_args) { + rc = ERROR_NOMEM; + goto out; + } + /* Set executable path */ + flexarray_append(xp_args, xp); + + /* Search pagefile option in extra flags */ + need_pagefile = 1; + for (i = 0; xpe && xpe[i]; i++) { + if (strcmp(xpe[i], "-f") == 0) { + need_pagefile = 0; + break; + } + } + /* Append pagefile option if its not in extra flags */ + if (need_pagefile) { + flexarray_append(xp_args, "-f"); + if (b_info->u.hvm.xenpaging_file) + flexarray_append(xp_args, b_info->u.hvm.xenpaging_file); + else + flexarray_append(xp_args, libxl__sprintf(gc, "%s/%s.%u.paging", + libxl_xenpaging_dir_path(), dom_name, domid)); + } + + /* Set maximum amount of memory xenpaging should handle */ + flexarray_append(xp_args, "-m"); + flexarray_append(xp_args, libxl__sprintf(gc, "%d", b_info->max_memkb)); + + /* Append extra args for pager */ + for (i = 0; xpe && xpe[i]; i++) + flexarray_append(xp_args, xpe[i]); + /* Append domid for pager */ + flexarray_append(xp_args, "-d"); + flexarray_append(xp_args, libxl__sprintf(gc, "%u", domid)); + flexarray_append(xp_args, NULL); + args = (char **) flexarray_contents(xp_args); + + /* Initialise logfile */ + libxl_create_logfile(ctx, libxl__sprintf(gc, "xenpaging-%s", dom_name), + &logfile); + logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); + free(logfile); + null = open("/dev/null", O_RDONLY); + + /* Spawn the child */ + rc = libxl__spawn_spawn(gc, buf_starting->for_spawn, "xenpaging", + libxl_spawner_record_pid, buf_starting); + if (rc < 0) + goto out_close; + if (!rc) { /* inner child */ + setsid(); + /* Finally run xenpaging */ + libxl__exec(null, logfile_w, logfile_w, xp, args); + } + rc = libxl__spawn_confirm_offspring_startup(gc, 5, "xenpaging", path, + "running", buf_starting); +out_close: + close(null); + close(logfile_w); + free(args); +out: + return rc; +} + static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid_out, int restore_fd) @@ -633,6 +759,16 @@ static int do_domain_create(libxl__gc *g goto error_out; } + if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) { + ret = create_xenpaging(gc, d_config->c_info.name, domid, + &d_config->b_info); + if (ret) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "Failed to start xenpaging.\n"); + goto error_out; + } + } + *domid_out = domid; return 0; diff -r bf0a7c205687 -r d368cf36d66c tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -127,7 +127,7 @@ int libxl__build_post(libxl__gc *gc, uin if (info->cpuid != NULL) libxl_cpuid_set(ctx, domid, info->cpuid); - ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); + ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; ents[1] = libxl__sprintf(gc, "%d", info->max_memkb); ents[2] = "memory/target"; @@ -140,9 +140,11 @@ int libxl__build_post(libxl__gc *gc, uin ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port); ents[10] = "store/ring-ref"; ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn); + ents[12] = "memory/target-tot_pages"; + ents[13] = libxl__sprintf(gc, "%d", info->tot_memkb); for (i = 0; i < info->max_vcpus; i++) { - ents[12+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i); - ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) + ents[14+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i); + ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) ? "offline" : "online"; } diff -r bf0a7c205687 -r d368cf36d66c tools/libxl/libxl_memory.txt --- a/tools/libxl/libxl_memory.txt +++ b/tools/libxl/libxl_memory.txt @@ -1,28 +1,28 @@ /* === Domain memory breakdown: HVM guests ================================== - + +----------+ + - | | shadow | | - | +----------+ | - overhead | | extra | | - | | external | | - | +----------+ + | - | | extra | | | - | | internal | | | - + +----------+ + | | footprint - | | video | | | | - | +----------+ + + | | xen | - | | | | | | actual | maximum | - | | | | | | target | | - | | guest | | | build | | | - | | | | | start | | | - static | | | | | | | | - maximum | +----------+ | + + + + - | | | | - | | | | - | | balloon | | build - | | | | maximum - | | | | - + +----------+ + + + +----------+ + + | | shadow | | + | +----------+ | + overhead | | extra | | + | | external | | + | +----------+ + | + | | extra | | | + | | internal | | | + + +----------+ + | | footprint + | | video | | | | + | +----------+ + + + | | xen | + | | | | guest OS | | | actual | maximum | + | | guest | | real RAM | | | target | | + | | | | | | build | | | + | |----------+ + | | start + | | + static | | paging | | | | | + maximum | +----------+ | + + + + | | | | + | | | | + | | balloon | | build + | | | | maximum + | | | | + + +----------+ + extra internal = LIBXL_MAXMEM_CONSTANT @@ -34,6 +34,17 @@ libxl_domain_setmaxmem -> xen maximum libxl_set_memory_target -> actual target + build maximum = RAM as seen inside the virtual machine + Guest OS has to configure itself for this amount of memory + Increase/Decrease via memory hotplug of virtual hardware. + xl mem-max + build start = RAM usable by the guest OS + Guest OS sees balloon driver as memory hog + Increase/Decrease via commands to the balloon driver + xl mem-set + actual target = RAM allocated for the guest + Increase/Decrease via commands to paging daemon + xl mem-paging_target (?) === Domain memory breakdown: PV guests ================================== diff -r bf0a7c205687 -r d368cf36d66c tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -207,6 +207,7 @@ libxl_domain_build_info = Struct("domain ("tsc_mode", libxl_tsc_mode), ("max_memkb", uint32), ("target_memkb", uint32), + ("tot_memkb", uint32), ("video_memkb", uint32), ("shadow_memkb", uint32), ("disable_migrate", bool), @@ -240,6 +241,8 @@ libxl_domain_build_info = Struct("domain ("vpt_align", bool), ("timer_mode", libxl_timer_mode), ("nested_hvm", bool), + ("xenpaging_file", string), + ("xenpaging_extra", libxl_string_list), ("no_incr_generationid", bool), ("nographic", bool), ("stdvga", bool), diff -r bf0a7c205687 -r d368cf36d66c tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -508,6 +508,28 @@ vcpp_out: return rc; } +static void parse_xenpaging_extra(const XLU_Config *config, libxl_string_list *xpe) +{ + XLU_ConfigList *args; + libxl_string_list l; + const char *val; + int nr_args = 0, i; + + if (xlu_cfg_get_list(config, "xenpaging_extra", &args, &nr_args, 1)) + return; + + l = xmalloc(sizeof(char*)*(nr_args + 1)); + if (!l) + return; + + l[nr_args] = NULL; + for (i = 0; i < nr_args; i++) { + val = xlu_cfg_get_listitem(args, i); + l[i] = val ? strdup(val) : NULL; + } + *xpe = l; +} + static void parse_config_data(const char *configfile_filename_report, const char *configfile_data, int configfile_len, @@ -629,6 +651,9 @@ static void parse_config_data(const char if (!xlu_cfg_get_long (config, "maxmem", &l, 0)) b_info->max_memkb = l * 1024; + if (!xlu_cfg_get_long (config, "mem_target_paging", &l, 0)) + b_info->tot_memkb = l * 1024; + if (xlu_cfg_get_string (config, "on_poweroff", &buf, 0)) buf = "destroy"; if (!parse_action_on_shutdown(buf, &d_config->on_poweroff)) { @@ -747,6 +772,10 @@ static void parse_config_data(const char if (!xlu_cfg_get_long (config, "nestedhvm", &l, 0)) b_info->u.hvm.nested_hvm = l; + + xlu_cfg_replace_string (config, "xenpaging_file", &b_info->u.hvm.xenpaging_file, 0); + parse_xenpaging_extra(config, &b_info->u.hvm.xenpaging_extra); + break; case LIBXL_DOMAIN_TYPE_PV: { diff -r bf0a7c205687 -r d368cf36d66c tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -39,6 +39,8 @@ /* Defines number of mfns a guest should use at a time, in KiB */ #define WATCH_TARGETPAGES "memory/target-tot_pages" +/* Defines path to startup confirmation */ +#define WATCH_STARTUP "xenpaging/state" static char *watch_target_tot_pages; static char *dom_path; static char watch_token[16]; @@ -845,6 +847,20 @@ static int evict_pages(struct xenpaging return num; } +static void xenpaging_confirm_startup(struct xenpaging *paging) +{ + xc_interface *xch = paging->xc_handle; + char *path; + int len; + + len = asprintf(&path, "%s/%s", dom_path, WATCH_STARTUP); + if ( len < 0 ) + return; + DPRINTF("confirming startup in %s\n", path); + xs_write(paging->xs_handle, XBT_NULL, path, "running", strlen("running")); + free(path); +} + int main(int argc, char *argv[]) { struct sigaction act; @@ -880,6 +896,9 @@ int main(int argc, char *argv[]) /* listen for page-in events to stop pager */ create_page_in_thread(paging); + /* Confirm startup to caller */ + xenpaging_confirm_startup(paging); + /* Swap pages in and out */ while ( 1 ) { _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |