Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:olh:xen-unstable
xen
xen.sr-precopy_policy.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xen.sr-precopy_policy.patch of Package xen
From: Olaf Hering <olaf@aepfle.de> Date: Fri, 8 Jan 2021 18:19:49 +0100 Subject: sr precopy_policy tools: add callback to libxl for precopy_policy and precopy_stats This duplicates simple_precopy_policy. To recap its purpose: - do up to 5 iterations of copying dirty domU memory to target, including the initial copying of all domU memory, excluding the final copying while the domU is suspended - do fewer iterations in case the domU dirtied less than 50 pages Take the opportunity to also move xen_pfn_t into qw(). Signed-off-by: Olaf Hering <olaf@aepfle.de> v02: - use plain struct precopy_stats instead of inventing a new precopy_stats_t (anthony) --- tools/libs/light/libxl_dom_save.c | 19 +++++++++ tools/libs/light/libxl_internal.h | 2 + tools/libs/light/libxl_save_msgs_gen.pl | 3 +- 3 files changed, 23 insertions(+), 1 deletion(-) --- a/tools/libs/light/libxl_dom_save.c +++ b/tools/libs/light/libxl_dom_save.c @@ -364,24 +364,42 @@ int libxl__save_emulator_xenstore_data(libxl__domain_save_state *dss, rc = 0; out: if (!rc) { *callee_buf = buf; *callee_len = len; } return rc; } +static int libxl__domain_save_precopy_policy(struct precopy_stats stats, void *user) +{ + libxl__save_helper_state *shs = user; + libxl__domain_save_state *dss = shs->caller_state; + STATE_AO_GC(dss->ao); + + LOGD(DEBUG, shs->domid, "iteration %u dirty_count %ld total_written %lu", + stats.iteration, stats.dirty_count, stats.total_written); + if (stats.dirty_count >= 0 && stats.dirty_count < LIBXL_XGS_POLICY_TARGET_DIRTY_COUNT) + goto stop_copy; + if (stats.iteration >= LIBXL_XGS_POLICY_MAX_ITERATIONS) + goto stop_copy; + return XGS_POLICY_CONTINUE_PRECOPY; + +stop_copy: + return XGS_POLICY_STOP_AND_COPY; +} + /*----- main code for saving, in order of execution -----*/ void libxl__domain_save(libxl__egc *egc, libxl__domain_save_state *dss) { STATE_AO_GC(dss->ao); int rc, ret; /* Convenience aliases */ const uint32_t domid = dss->domid; const libxl_domain_type type = dss->type; const int live = dss->live; const int debug = dss->debug; @@ -421,24 +439,25 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_save_state *dss) ret = xc_domain_getvnuma(CTX->xch, domid, &nr_vnodes, &nr_vmemranges, &nr_vcpus, NULL, NULL, NULL); if (ret != -1 || errno != EOPNOTSUPP) { LOGD(ERROR, domid, "Cannot save a guest with vNUMA configured"); rc = ERROR_FAIL; goto out; } if (dss->checkpointed_stream == LIBXL_CHECKPOINTED_STREAM_NONE) callbacks->suspend = libxl__domain_suspend_callback; callbacks->switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty; + callbacks->precopy_policy = libxl__domain_save_precopy_policy; dss->sws.ao = dss->ao; dss->sws.dss = dss; dss->sws.fd = dss->fd; dss->sws.back_channel = false; dss->sws.completion_callback = stream_done; libxl__stream_write_start(egc, &dss->sws); return; out: domain_save_done(egc, dss, rc); --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -116,24 +116,26 @@ #define QEMU_SIGNATURE "DeviceModelRecord0002" #define STUBDOM_CONSOLE_LOGGING 0 #define STUBDOM_CONSOLE_SAVE 1 #define STUBDOM_CONSOLE_RESTORE 2 #define STUBDOM_CONSOLE_SERIAL 3 #define STUBDOM_SPECIAL_CONSOLES 3 #define LIBXL_LINUX_STUBDOM_MEM 128 #define LIBXL_STUBDOM_EMPTY_CDROM XEN_RUN_DIR "/empty-cdrom" /* .$domid */ #define TAP_DEVICE_SUFFIX "-emu" #define DOMID_XS_PATH "domid" #define PVSHIM_BASENAME "xen-shim" #define PVSHIM_CMDLINE "pv-shim console=xen,pv" +#define LIBXL_XGS_POLICY_MAX_ITERATIONS 5 +#define LIBXL_XGS_POLICY_TARGET_DIRTY_COUNT 50 #define DIV_ROUNDUP(n, d) (((n) + (d) - 1) / (d)) #define LIBXL__LOGGING_ENABLED #ifdef LIBXL__LOGGING_ENABLED #define LIBXL__LOG(ctx, loglevel, _f, _a...) libxl__log(ctx, loglevel, -1, __FILE__, __LINE__, __func__, INVALID_DOMID, _f, ##_a) #define LIBXL__LOG_ERRNO(ctx, loglevel, _f, _a...) libxl__log(ctx, loglevel, errno, __FILE__, __LINE__, __func__, INVALID_DOMID, _f, ##_a) #define LIBXL__LOG_ERRNOVAL(ctx, loglevel, errnoval, _f, _a...) libxl__log(ctx, loglevel, errnoval, __FILE__, __LINE__, __func__, INVALID_DOMID, _f, ##_a) /* Same log functions as above, but with _d being a domain id. */ #define LIBXL__LOGD(ctx, loglevel, _d, _f, _a...) libxl__log(ctx, loglevel, -1, __FILE__, __LINE__, __func__, _d, _f, ##_a) --- a/tools/libs/light/libxl_save_msgs_gen.pl +++ b/tools/libs/light/libxl_save_msgs_gen.pl @@ -14,24 +14,25 @@ our @msgs = ( # x - function pointer is in struct {save,restore}_callbacks # and its null-ness needs to be passed through to the helper's xc # W - needs a return value; callback is synchronous # A - needs a return value; callback is asynchronous [ 'sr', "log", [qw(uint32_t level uint32_t errnoval STRING context STRING formatted)] ], [ 'sr', "progress", [qw(STRING context STRING doing_what), 'unsigned long', 'done', 'unsigned long', 'total'] ], + [ 'scxW', "precopy_policy", ['struct precopy_stats', 'stats'] ], [ 'srcxA', "suspend", [] ], [ 'srcxA', "postcopy", [] ], [ 'srcxA', "checkpoint", [] ], [ 'srcxA', "wait_checkpoint", [] ], [ 'scxA', "switch_qemu_logdirty", [qw(uint32_t domid unsigned enable)] ], [ 'rcxW', "static_data_done", [qw(unsigned missing)] ], [ 'rcx', "restore_results", ['xen_pfn_t', 'store_gfn', 'xen_pfn_t', 'console_gfn'] ], [ 'srW', "complete", [qw(int retval int errnoval)] ], ); @@ -133,25 +134,25 @@ END $out_body{'helper'} .= <<END; static void bytes_put(unsigned char *const buf, int *len, const void *value, int vlen) { assert(vlen < INT_MAX/2 - *len); if (buf) memcpy(buf + *len, value, vlen); *len += vlen; } END -foreach my $simpletype (qw(int uint16_t uint32_t unsigned), 'unsigned long', 'xen_pfn_t') { +foreach my $simpletype (qw(int uint16_t uint32_t unsigned xen_pfn_t), 'struct precopy_stats', 'unsigned long') { my $typeid = typeid($simpletype); $out_body{'callout'} .= <<END; static int ${typeid}_get(const unsigned char **msg, const unsigned char *const endmsg, $simpletype *result) { return bytes_get(msg, endmsg, result, sizeof(*result)); } END $out_body{'helper'} .= <<END; static void ${typeid}_put(unsigned char *const buf, int *len,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor