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

[Xen-devel] [PATCH 8 of 9] tools: set number of dirty pages during migration



# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1364481734 -3600
# Node ID 4bf71e887b838dd643399b8b8a65406d5f8eb94f
# Parent  82ff5fb38a092a4b162da90ad0b4d295f18ace13
tools: set number of dirty pages during migration

If a guest is really busy it will not reach the low number of remaining
50 dirty pages for the final suspend. As a result the guest is either
suspendend for a long time during the final transfer, or if the number
of iterations is increased the migration will take a long time.

Add a new option xm/xl migrate --min_remaing <pages> to increase the
default from command line. The default of 50 is 200kb, which is
appearently an arbitrary number. With todays network speeds a larger
block of memory can be transfered quickly without causing too much
suspension time. This knob gives the admin the chance to adapt the
suspension time to the given workload.

The existing default of 50 pages is not altered by this change.

Due to the changed xc_domain_save API, bump SONAME of libxc to 4.3.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>

diff -r 82ff5fb38a09 -r 4bf71e887b83 docs/man/xl.pod.1
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -399,6 +399,11 @@ Number of iterations before final suspen
 
 Max amount of memory to transfer before final suspend (default: 3*RAM)
 
+=item B<--min_remaining>
+
+Number of remaining dirty pages. If the number of dirty pages drops that 
+low the guest is suspended and the remaing pages are transfered to <host>.
+
 =item B<--abort_if_busy>
 
 Abort migration instead of doing final suspend/transfer/resume if the
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/Makefile
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -1,7 +1,7 @@
 XEN_ROOT = $(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-MAJOR    = 4.2
+MAJOR    = 4.3
 MINOR    = 0
 
 CTRL_SRCS-y       :=
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -43,6 +43,7 @@
 */
 #define DEF_MAX_ITERS   29   /* limit us to 30 times round loop   */
 #define DEF_MAX_FACTOR   3   /* never send more than 3x p2m_size  */
+#define DEF_MIN_REMAINING 50 /* low water mark of dirty pages */
 
 struct save_ctx {
     unsigned long hvirt_start; /* virtual starting address of the hypervisor */
@@ -794,7 +795,7 @@ static int save_tsc_info(xc_interface *x
 }
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t 
max_iters,
-                   uint32_t max_factor, uint32_t flags,
+                   uint32_t max_factor, uint32_t min_remaining, uint32_t flags,
                    struct save_callbacks* callbacks, int hvm,
                    unsigned long vm_generationid_addr)
 {
@@ -905,6 +906,7 @@ int xc_domain_save(xc_interface *xch, in
     /* If no explicit control parameters given, use defaults */
     max_iters  = max_iters  ? : DEF_MAX_ITERS;
     max_factor = max_factor ? : DEF_MAX_FACTOR;
+    min_remaining = min_remaining ? : DEF_MIN_REMAINING;
 
     if ( !get_platform_info(xch, dom,
                             &ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, 
&dinfo->guest_width) )
@@ -1528,7 +1530,7 @@ int xc_domain_save(xc_interface *xch, in
 
         if ( live )
         {
-            int min_reached = sent_this_iter + skip_this_iter < 50;
+            int min_reached = sent_this_iter + skip_this_iter < min_remaining;
             if ( (iter >= max_iters) ||
                  min_reached ||
                  (total_sent > dinfo->p2m_size*max_factor) )
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/xc_nomigrate.c
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -22,7 +22,7 @@
 #include <xenguest.h>
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t 
max_iters,
-                   uint32_t max_factor, uint32_t flags,
+                   uint32_t max_factor, uint32_t min_remaining, uint32_t flags,
                    struct save_callbacks* callbacks, int hvm,
                    unsigned long vm_generationid_addr)
 {
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -87,7 +87,7 @@ struct save_callbacks {
  * @return 0 on success, -1 on failure
  */
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t 
max_iters,
-                   uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+                   uint32_t max_factor, uint32_t min_remaining, uint32_t flags 
/* XCFLAGS_xxx */,
                    struct save_callbacks* callbacks, int hvm,
                    unsigned long vm_generationid_addr);
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -783,6 +783,7 @@ int libxl_domain_suspend(libxl_ctx *ctx,
         dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
         dss->max_iters = props->max_iters;
         dss->max_factor = props->max_factor;
+        dss->min_remaining = props->min_remaining;
         dss->xlflags = props->flags;
     }
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -511,6 +511,7 @@ typedef struct {
     int flags; /* LIBXL_SUSPEND_* */
     int max_iters;
     int max_factor;
+    int min_remaining;
 } libxl_domain_suspend_properties;
 
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2251,6 +2251,7 @@ struct libxl__domain_suspend_state {
     int hvm;
     int max_iters;
     int max_factor;
+    int min_remaining;
     int xlflags;
     int xcflags;
     int guest_responded;
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl_save_callout.c
--- a/tools/libxl/libxl_save_callout.c
+++ b/tools/libxl/libxl_save_callout.c
@@ -108,7 +108,8 @@ void libxl__xc_domain_save(libxl__egc *e
     }
 
     const unsigned long argnums[] = {
-        dss->domid, dss->max_iters, dss->max_factor, dss->xcflags, dss->hvm,
+        dss->domid, dss->max_iters, dss->max_factor, dss->min_remaining,
+        dss->xcflags, dss->hvm,
         vm_generationid_addr, toolstack_data_fd, toolstack_data_len,
         cbflags,
     };
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/libxl_save_helper.c
--- a/tools/libxl/libxl_save_helper.c
+++ b/tools/libxl/libxl_save_helper.c
@@ -221,6 +221,7 @@ int main(int argc, char **argv)
         uint32_t dom =             strtoul(NEXTARG,0,10);
         uint32_t max_iters =       strtoul(NEXTARG,0,10);
         uint32_t max_factor =      strtoul(NEXTARG,0,10);
+        uint32_t min_remaining =   strtoul(NEXTARG,0,10);
         uint32_t flags =           strtoul(NEXTARG,0,10);
         int hvm =                  atoi(NEXTARG);
         unsigned long genidad =    strtoul(NEXTARG,0,10);
@@ -235,8 +236,8 @@ int main(int argc, char **argv)
         helper_setcallbacks_save(&helper_save_callbacks, cbflags);
 
         startup("save");
-        r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags,
-                           &helper_save_callbacks, hvm, genidad);
+        r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, 
min_remaining,
+                           flags, &helper_save_callbacks, hvm, genidad);
         complete(r);
 
     } else if (!strcmp(mode,"--restore-domain")) {
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -3361,7 +3361,8 @@ static void migrate_do_preamble(int send
 }
 
 static void migrate_domain(uint32_t domid, const char *rune, int debug,
-                           int max_iters, int max_factor, int abort_if_busy,
+                           int max_iters, int max_factor,
+                           int min_remaining, int abort_if_busy,
                            const char *override_config_file)
 {
     pid_t child = -1;
@@ -3375,6 +3376,7 @@ static void migrate_domain(uint32_t domi
         .flags = LIBXL_SUSPEND_LIVE,
         .max_iters = max_iters,
         .max_factor = max_factor,
+        .min_remaining = min_remaining,
     };
 
     save_domain_core_begin(domid, override_config_file,
@@ -3791,12 +3793,13 @@ int main_migrate(int argc, char **argv)
     char *rune = NULL;
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0;
-    int max_iters = 0, max_factor = 0, abort_if_busy = 0;
+    int max_iters = 0, max_factor = 0, min_remaining = 0, abort_if_busy = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
         {"max_iters", 1, 0, 0x101},
         {"max_factor", 1, 0, 0x102},
-        {"abort_if_busy", 0, 0, 0x103},
+        {"min_remaining", 1, 0, 0x103},
+        {"abort_if_busy", 0, 0, 0x104},
         COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
@@ -3825,6 +3828,9 @@ int main_migrate(int argc, char **argv)
         max_factor = atoi(optarg);
         break;
     case 0x103:
+        min_remaining = atoi(optarg);
+        break;
+    case 0x104:
         abort_if_busy = 1;
         break;
     }
@@ -3842,7 +3848,8 @@ int main_migrate(int argc, char **argv)
             return 1;
     }
 
-    migrate_domain(domid, rune, debug, max_iters, max_factor, abort_if_busy, 
config_filename);
+    migrate_domain(domid, rune, debug, max_iters, max_factor, min_remaining,
+                   abort_if_busy, config_filename);
     return 0;
 }
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -147,18 +147,19 @@ struct cmd_spec cmd_table[] = {
       &main_migrate, 0, 1,
       "Migrate a domain to another host",
       "[options] <Domain> <host>",
-      "-h                    Print this help.\n"
-      "-C <config>           Send <config> instead of config file from 
creation.\n"
-      "-s <sshcommand>       Use <sshcommand> instead of ssh.  String will be 
passed\n"
-      "                      to sh. If empty, run <host> instead of ssh <host> 
xl\n"
-      "                      migrate-receive [-d -e]\n"
-      "-e                    Do not wait in the background (on <host>) for the 
death\n"
-      "                      of the domain.\n"
-      "--debug               Print huge (!) amount of debug during the 
migration process.\n"
-      "--max_iters <number>  Number of iterations before final suspend 
(default: 30)\n"
-      "--max_factor <factor> Max amount of memory to transfer before final 
suspend (default: 3*RAM).\n"
-      "--abort_if_busy       Abort migration instead of doing final suspend, 
if number\n"
-      "                      of iterations or amount of transfered memory is 
exceeded."
+      "-h                      Print this help.\n"
+      "-C <config>             Send <config> instead of config file from 
creation.\n"
+      "-s <sshcommand>         Use <sshcommand> instead of ssh.  String will 
be passed\n"
+      "                        to sh. If empty, run <host> instead of ssh 
<host> xl\n"
+      "                        migrate-receive [-d -e]\n"
+      "-e                      Do not wait in the background (on <host>) for 
the death\n"
+      "                        of the domain.\n"
+      "--debug                 Print huge (!) amount of debug during the 
migration process.\n"
+      "--max_iters <number>    Number of iterations before final suspend 
(default: 30)\n"
+      "--max_factor <factor>   Max amount of memory to transfer before final 
suspend (default: 3*RAM).\n"
+      "--min_remaining <pages> Number of remaining dirty pages before final 
suspend (default: 50).\n"
+      "--abort_if_busy         Abort migration instead of doing final suspend, 
if number\n"
+      "                        of iterations or amount of transfered memory is 
exceeded."
     },
     { "dump-core",
       &main_dump_core, 0, 1,
diff -r 82ff5fb38a09 -r 4bf71e887b83 
tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
--- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
+++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
@@ -206,7 +206,7 @@ int checkpoint_start(checkpoint_state* s
 
     callbacks->switch_qemu_logdirty = noop_switch_logdirty;
 
-    rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm,
+    rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, 0, flags, callbacks, hvm,
                         vm_generationid_addr);
 
     if (hvm)
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py
+++ b/tools/python/xen/xend/XendCheckpoint.py
@@ -120,19 +120,22 @@ def save(fd, dominfo, network, live, dst
         # more information.
         max_iters = dominfo.info.get('max_iters', "0")
         max_factor = dominfo.info.get('max_factor', "0")
+        min_remaining = dominfo.info.get('min_remaining', "0")
         abort_if_busy = dominfo.info.get('abort_if_busy', "0")
         log_save_progress = dominfo.info.get('log_save_progress', "0")
         if max_iters == "None":
             max_iters = "0"
         if max_factor == "None":
             max_factor = "0"
+        if min_remaining == "None":
+            min_remaining = "0"
         if abort_if_busy == "None":
             abort_if_busy = "0"
         if log_save_progress == "None":
             log_save_progress = "0"
         cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
                str(dominfo.getDomid()),
-               max_iters, max_factor,
+               max_iters, max_factor, min_remaining,
                str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | 
(int(log_save_progress) << 6) ) ]
         log.debug("[xc_save]: %s", string.join(cmd))
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py
+++ b/tools/python/xen/xend/XendDomain.py
@@ -1832,18 +1832,19 @@ class XendDomain:
             log.exception(ex)
             raise XendError(str(ex))
 
-    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, 
abort_if_busy, log_save_progress):
+    def domain_migrate_constraints_set(self, domid, max_iters, max_factor, 
min_remaining, abort_if_busy, log_save_progress):
         """Set the Migrate Constraints of this domain.
         @param domid: Domain ID or Name
         @param max_iters: Number of iterations before final suspend
         @param max_factor: Max amount of memory to transfer before final 
suspend
+        @param min_remaining: Number of dirty pages before final suspend
         @param abort_if_busy: Abort migration instead of doing final suspend
         @param log_save_progress: Log progress of migrate to xend.log
         """
         dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
-        dominfo.setMigrateConstraints(max_iters, max_factor, abort_if_busy, 
log_save_progress)
+        dominfo.setMigrateConstraints(max_iters, max_factor, min_remaining, 
abort_if_busy, log_save_progress)
 
     def domain_maxmem_set(self, domid, mem):
         """Set the memory limit for a domain.
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -1459,17 +1459,19 @@ class XendDomainInfo:
         pci_conf = self.info['devices'][dev_uuid][1]
         return map(pci_dict_to_bdf_str, pci_conf['devs'])
 
-    def setMigrateConstraints(self, max_iters, max_factor, abort_if_busy, 
log_save_progress):
+    def setMigrateConstraints(self, max_iters, max_factor, min_remaining, 
abort_if_busy, log_save_progress):
         """Set the Migrate Constraints of this domain.
         @param max_iters: Number of iterations before final suspend
         @param max_factor: Max amount of memory to transfer before final 
suspend
+        @param min_remaining: Number of dirty pages before final suspend
         @param abort_if_busy: Abort migration instead of doing final suspend
         @param log_save_progress: Log progress of migrate to xend.log
         """
-        log.debug("Setting migration constraints of domain %s (%s) to '%s' 
'%s' '%s'.",
-                  self.info['name_label'], str(self.domid), max_iters, 
max_factor, abort_if_busy)
+        log.debug("Setting migration constraints of domain %s (%s) to '%s' 
'%s' '%s' '%s'.",
+                  self.info['name_label'], str(self.domid), max_iters, 
max_factor, min_remaining, abort_if_busy)
         self.info['max_iters'] = str(max_iters)
         self.info['max_factor'] = str(max_factor)
+        self.info['min_remaining'] = str(min_remaining)
         self.info['abort_if_busy'] = str(abort_if_busy)
         self.info['log_save_progress'] = str(log_save_progress)
 
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py
+++ b/tools/python/xen/xm/migrate.py
@@ -63,6 +63,10 @@ gopts.opt('max_factor', val='max_factor'
           fn=set_int, default=0,
           use="Max amount of memory to transfer before final suspend (default: 
3*RAM).")
 
+gopts.opt('min_remaining', val='min_remaining',
+          fn=set_int, default=0,
+          use="Number of dirty pages before final suspend (default: 50).")
+
 gopts.opt('abort_if_busy',
           fn=set_true, default=0,
           use="Abort migration instead of doing final suspend.")
@@ -99,6 +103,7 @@ def main(argv):
         server.xend.domain.migrate_constraints_set(dom,
                                                    opts.vals.max_iters,
                                                    opts.vals.max_factor,
+                                                   opts.vals.min_remaining,
                                                    opts.vals.abort_if_busy,
                                                    opts.vals.log_progress)
         server.xend.domain.migrate(dom, dst, opts.vals.live,
diff -r 82ff5fb38a09 -r 4bf71e887b83 tools/xcutils/xc_save.c
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -179,20 +179,21 @@ int
 main(int argc, char **argv)
 {
     xc_interface *xch;
-    unsigned int maxit, max_f, lflags;
+    unsigned int maxit, max_f, min_r, lflags;
     int io_fd, ret, port;
     struct save_callbacks callbacks;
     xentoollog_level lvl;
     xentoollog_logger *l;
 
-    if (argc != 6)
-        errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
+    if (argc != 7)
+        errx(1, "usage: %s iofd domid maxit maxf minr flags", argv[0]);
 
     io_fd = atoi(argv[1]);
     si.domid = atoi(argv[2]);
     maxit = atoi(argv[3]);
     max_f = atoi(argv[4]);
-    si.flags = atoi(argv[5]);
+    min_r = atoi(argv[5]);
+    si.flags = atoi(argv[6]);
 
     si.suspend_evtchn = -1;
 
@@ -226,7 +227,7 @@ main(int argc, char **argv)
     memset(&callbacks, 0, sizeof(callbacks));
     callbacks.suspend = suspend;
     callbacks.switch_qemu_logdirty = switch_qemu_logdirty;
-    ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags, 
+    ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, min_r, 
si.flags, 
                          &callbacks, !!(si.flags & XCFLAGS_HVM), 0);
 
     if (si.suspend_evtchn > 0)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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