All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v20210111 00/39] leftover from 2020
@ 2021-01-11 17:41 Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 01/39] stubdom: fix tpm_version Olaf Hering
                   ` (38 more replies)
  0 siblings, 39 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  Cc: Olaf Hering

Various unreviewed changes.

Olaf Hering (39):
  stubdom: fix tpm_version
  xl: use proper name for bash_completion file
  docs: remove stale create example from xl.1
  docs: substitute XEN_CONFIG_DIR in xl.conf.5
  tools: add with-xen-scriptdir configure option
  Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts
  xl: optionally print timestamps during xl migrate
  xl: fix description of migrate --debug
  tools: add readv_exact to libxenctrl
  tools: add xc_is_known_page_type to libxenctrl
  tools: use xc_is_known_page_type
  tools: unify type checking for data pfns in migration stream
  tools: show migration transfer rate in send_dirty_pages
  tools/guest: prepare to allocate arrays once
  tools/guest: save: move batch_pfns
  tools/guest: save: move mfns array
  tools/guest: save: move types array
  tools/guest: save: move errors array
  tools/guest: save: move iov array
  tools/guest: save: move rec_pfns array
  tools/guest: save: move guest_data array
  tools/guest: save: move local_pages array
  tools/guest: restore: move pfns array
  tools/guest: restore: move types array
  tools/guest: restore: move mfns array
  tools/guest: restore: move map_errs array
  tools/guest: restore: move mfns array in populate_pfns
  tools/guest: restore: move pfns array in populate_pfns
  tools/guest: restore: split record processing
  tools/guest: restore: split handle_page_data
  tools/guest: restore: write data directly into guest
  tools: remove tabs from code produced by libxl_save_msgs_gen.pl
  tools: recognize LIBXL_API_VERSION for 4.15
  tools: adjust libxl_domain_suspend to receive a struct props
  tools: change struct precopy_stats to precopy_stats_t
  tools: add callback to libxl for precopy_policy and precopy_stats_t
  tools: add --max_iters to libxl_domain_suspend
  tools: add --min_remaining to libxl_domain_suspend
  tools: add --abort_if_busy to libxl_domain_suspend

 .gitignore                                    |   3 +
 docs/configure.ac                             |   3 +
 ...n.5.pod => xl-disk-configuration.5.pod.in} |   2 +-
 ....pod => xl-network-configuration.5.pod.in} |   4 +-
 docs/man/xl.1.pod.in                          |  39 +-
 docs/man/{xl.conf.5.pod => xl.conf.5.pod.in}  |   8 +-
 docs/misc/block-scripts.txt                   |   2 +-
 m4/paths.m4                                   |   8 +-
 stubdom/vtpmmgr/vtpmmgr.h                     |   2 +-
 tools/include/libxl.h                         |  32 +-
 tools/include/xenguest.h                      |   7 +-
 tools/libs/ctrl/xc_private.c                  |  55 +-
 tools/libs/ctrl/xc_private.h                  |  34 ++
 tools/libs/guest/xg_sr_common.c               |  33 +-
 tools/libs/guest/xg_sr_common.h               |  88 ++-
 tools/libs/guest/xg_sr_restore.c              | 562 ++++++++++++------
 tools/libs/guest/xg_sr_save.c                 | 164 ++---
 tools/libs/guest/xg_sr_save_x86_hvm.c         |   5 +-
 tools/libs/guest/xg_sr_save_x86_pv.c          |  31 +-
 tools/libs/light/libxl_dom_save.c             |  24 +
 tools/libs/light/libxl_domain.c               |  10 +-
 tools/libs/light/libxl_internal.h             |   6 +
 tools/libs/light/libxl_save_msgs_gen.pl       |  23 +-
 tools/libs/light/libxl_stream_write.c         |   9 +-
 tools/libs/light/libxl_types.idl              |   1 +
 tools/ocaml/libs/xl/xenlight_stubs.c          |   3 +-
 tools/xl/Makefile                             |   4 +-
 tools/xl/bash-completion                      |   2 +-
 tools/xl/xl_cmdtable.c                        |  29 +-
 tools/xl/xl_migrate.c                         |  79 ++-
 tools/xl/xl_saverestore.c                     |   3 +-
 31 files changed, 901 insertions(+), 374 deletions(-)
 rename docs/man/{xl-disk-configuration.5.pod => xl-disk-configuration.5.pod.in} (99%)
 rename docs/man/{xl-network-configuration.5.pod => xl-network-configuration.5.pod.in} (98%)
 rename docs/man/{xl.conf.5.pod => xl.conf.5.pod.in} (96%)



^ permalink raw reply	[flat|nested] 62+ messages in thread

* [PATCH v20210111 01/39] stubdom: fix tpm_version
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 18:06   ` Samuel Thibault
  2021-01-11 17:41 ` [PATCH v20210111 02/39] xl: use proper name for bash_completion file Olaf Hering
                   ` (37 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Daniel De Graaf, Quan Xu, Samuel Thibault

It is just a declaration, not a variable.

ld: /home/abuild/rpmbuild/BUILD/xen-4.14.20200616T103126.3625b04991/non-dbg/stubdom/vtpmmgr/vtpmmgr.a(vtpm_cmd_handler.o):(.bss+0x0): multiple definition of `tpm_version'; /home/abuild/rpmbuild/BUILD/xen-4.14.20200616T103126.3625b04991/non-dbg/stubdom/vtpmmgr/vtpmmgr.a(vtpmmgr.o):(.bss+0x0): first defined here

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 stubdom/vtpmmgr/vtpmmgr.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/stubdom/vtpmmgr/vtpmmgr.h b/stubdom/vtpmmgr/vtpmmgr.h
index 2e6f8de9e4..f40ca9fd67 100644
--- a/stubdom/vtpmmgr/vtpmmgr.h
+++ b/stubdom/vtpmmgr/vtpmmgr.h
@@ -53,7 +53,7 @@
 enum {
     TPM1_HARDWARE = 1,
     TPM2_HARDWARE,
-} tpm_version;
+};
 
 struct tpm_hardware_version {
     int hw_version;


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 02/39] xl: use proper name for bash_completion file
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 01/39] stubdom: fix tpm_version Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 15:48   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 03/39] docs: remove stale create example from xl.1 Olaf Hering
                   ` (36 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Files in the bash-completion dirs should be named like the commands,
without suffix. Without this change 'xl' will not be recognized as a
command with completion support if BASH_COMPLETION_DIR is set to
/usr/share/bash-completion/completions.

Fixes commit 9136a919b19929ecb242ef327053d55d824397df

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/xl/Makefile        | 4 ++--
 tools/xl/bash-completion | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/xl/Makefile b/tools/xl/Makefile
index bdf67c8464..656b21c7da 100644
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -45,11 +45,11 @@ install: all
 	$(INSTALL_DIR) $(DESTDIR)$(sbindir)
 	$(INSTALL_DIR) $(DESTDIR)$(BASH_COMPLETION_DIR)
 	$(INSTALL_PROG) xl $(DESTDIR)$(sbindir)
-	$(INSTALL_DATA) bash-completion $(DESTDIR)$(BASH_COMPLETION_DIR)/xl.sh
+	$(INSTALL_DATA) bash-completion $(DESTDIR)$(BASH_COMPLETION_DIR)/xl
 
 .PHONY: uninstall
 uninstall:
-	rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/xl.sh
+	rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/xl
 	rm -f $(DESTDIR)$(sbindir)/xl
 
 .PHONY: clean
diff --git a/tools/xl/bash-completion b/tools/xl/bash-completion
index b7cd6b3992..7c6ed32f88 100644
--- a/tools/xl/bash-completion
+++ b/tools/xl/bash-completion
@@ -1,4 +1,4 @@
-# Copy this file to /etc/bash_completion.d/xl.sh
+# Copy this file to /etc/bash_completion.d/xl
 
 _xl()
 {


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 03/39] docs: remove stale create example from xl.1
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 01/39] stubdom: fix tpm_version Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 02/39] xl: use proper name for bash_completion file Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 15:41   ` Ian Jackson
  2021-02-08 15:42   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5 Olaf Hering
                   ` (35 subsequent siblings)
  38 siblings, 2 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu

Maybe xm create had a feature to create a domU based on a configuration
file. xl create requires the '-f' option to refer to a file.
There is no code to look into XEN_CONFIG_DIR, so remove the example.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 docs/man/xl.1.pod.in | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index af31d2b572..c7b2fcc927 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -171,13 +171,6 @@ B<EXAMPLES>
 
 =over 4
 
-=item I<with config file>
-
-  xl create DebianLenny
-
-This creates a domain with the file /etc/xen/DebianLenny, and returns as
-soon as it is run.
-
 =item I<with extra parameters>
 
   xl create hvm.cfg 'cpus="0-3"; pci=["01:05.1","01:05.2"]'


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (2 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 03/39] docs: remove stale create example from xl.1 Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 15:45   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option Olaf Hering
                   ` (34 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Anthony PERARD, Ian Jackson, Wei Liu

xl(1) opens xl.conf in XEN_CONFIG_DIR.
Substitute this variable also in the man page.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
---
 docs/man/xl.1.pod.in   | 2 +-
 docs/man/xl.conf.5.pod | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index c7b2fcc927..765c169ed2 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -50,7 +50,7 @@ setup the bridge.
 
 If you specify the amount of memory dom0 has, passing B<dom0_mem> to
 Xen, it is highly recommended to disable B<autoballoon>. Edit
-B</etc/xen/xl.conf> and set it to 0.
+B<@XEN_CONFIG_DIR@/xl.conf> and set it to 0.
 
 =item run xl as B<root>
 
diff --git a/docs/man/xl.conf.5.pod b/docs/man/xl.conf.5.pod
index 41ee428744..dfea9d64ba 100644
--- a/docs/man/xl.conf.5.pod
+++ b/docs/man/xl.conf.5.pod
@@ -1,6 +1,6 @@
 =head1 NAME
 
-/etc/xen/xl.conf - XL Global/Host Configuration 
+@XEN_CONFIG_DIR@/xl.conf - XL Global/Host Configuration
 
 =head1 DESCRIPTION
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (3 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5 Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 16:03   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts Olaf Hering
                   ` (33 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu

In the near future all fresh installations will have an empty /etc.
The content of this directory will not be controlled by the package
manager anymore. One of the reasons for this move is to make snapshots
more robust.

As a first step into this direction, add a knob to configure to allow
storing the hotplug scripts to libexec because they are not exactly
configuration. The current default is unchanged, which is
/etc/xen/scripts.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 m4/paths.m4 | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/m4/paths.m4 b/m4/paths.m4
index 89d3bb8312..0cec2bb190 100644
--- a/m4/paths.m4
+++ b/m4/paths.m4
@@ -70,6 +70,12 @@ AC_ARG_WITH([libexec-leaf-dir],
     [libexec_subdir=$withval],
     [libexec_subdir=$PACKAGE_TARNAME])
 
+AC_ARG_WITH([xen-scriptdir],
+    AS_HELP_STRING([--with-xen-scriptdir=DIR],
+    [Path to directory for dom0 hotplug scripts. [SYSCONFDIR/xen/scripts]]),
+    [xen_scriptdir_path=$withval],
+    [xen_scriptdir_path=$sysconfdir/xen/scripts])
+
 AC_ARG_WITH([xen-dumpdir],
     AS_HELP_STRING([--with-xen-dumpdir=DIR],
     [Path to directory for domU crash dumps. [LOCALSTATEDIR/lib/xen/dump]]),
@@ -137,7 +143,7 @@ AC_SUBST(INITD_DIR)
 XEN_CONFIG_DIR=$CONFIG_DIR/xen
 AC_SUBST(XEN_CONFIG_DIR)
 
-XEN_SCRIPT_DIR=$XEN_CONFIG_DIR/scripts
+XEN_SCRIPT_DIR=$xen_scriptdir_path
 AC_SUBST(XEN_SCRIPT_DIR)
 
 case "$host_os" in


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (4 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 16:04   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate Olaf Hering
                   ` (32 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel
  Cc: Olaf Hering, Andrew Cooper, George Dunlap, Ian Jackson,
	Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu,
	Anthony PERARD

Replace all hardcoded paths to use XEN_SCRIPT_DIR to expand the actual location.

Update .gitignore.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 .gitignore                                                  | 3 +++
 docs/configure.ac                                           | 3 +++
 ...k-configuration.5.pod => xl-disk-configuration.5.pod.in} | 2 +-
 ...onfiguration.5.pod => xl-network-configuration.5.pod.in} | 4 ++--
 docs/man/xl.1.pod.in                                        | 2 +-
 docs/man/{xl.conf.5.pod => xl.conf.5.pod.in}                | 6 +++---
 docs/misc/block-scripts.txt                                 | 2 +-
 tools/xl/xl_cmdtable.c                                      | 2 +-
 8 files changed, 15 insertions(+), 9 deletions(-)
 rename docs/man/{xl-disk-configuration.5.pod => xl-disk-configuration.5.pod.in} (99%)
 rename docs/man/{xl-network-configuration.5.pod => xl-network-configuration.5.pod.in} (98%)
 rename docs/man/{xl.conf.5.pod => xl.conf.5.pod.in} (97%)

diff --git a/.gitignore b/.gitignore
index b169d78ed7..76c13f3189 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,7 +48,10 @@ dist/*
 docs/tmp.*
 docs/html/
 docs/man/xl.cfg.5.pod
+docs/man/xl-disk-configuration.5.pod
+docs/man/xl-network-configuration.5.pod
 docs/man/xl.1.pod
+docs/man/xl.conf.5.pod
 docs/man1/
 docs/man5/
 docs/man7/
diff --git a/docs/configure.ac b/docs/configure.ac
index cb5a6eaa4c..c2e5edd3b3 100644
--- a/docs/configure.ac
+++ b/docs/configure.ac
@@ -9,6 +9,9 @@ AC_CONFIG_FILES([
 ../config/Docs.mk
 man/xl.cfg.5.pod
 man/xl.1.pod
+man/xl-disk-configuration.5.pod
+man/xl-network-configuration.5.pod
+man/xl.conf.5.pod
 ])
 AC_CONFIG_AUX_DIR([../])
 
diff --git a/docs/man/xl-disk-configuration.5.pod b/docs/man/xl-disk-configuration.5.pod.in
similarity index 99%
rename from docs/man/xl-disk-configuration.5.pod
rename to docs/man/xl-disk-configuration.5.pod.in
index 46feedb95e..71d0e86e3d 100644
--- a/docs/man/xl-disk-configuration.5.pod
+++ b/docs/man/xl-disk-configuration.5.pod.in
@@ -257,7 +257,7 @@ automatically determine the most suitable backend.
 
 Specifies that B<target> is not a normal host path, but rather
 information to be interpreted by the executable program I<SCRIPT>,
-(looked for in F</etc/xen/scripts>, if it doesn't contain a slash).
+(looked for in F<@XEN_SCRIPT_DIR@>, if it doesn't contain a slash).
 
 These scripts are normally called "block-I<SCRIPT>".
 
diff --git a/docs/man/xl-network-configuration.5.pod b/docs/man/xl-network-configuration.5.pod.in
similarity index 98%
rename from docs/man/xl-network-configuration.5.pod
rename to docs/man/xl-network-configuration.5.pod.in
index af058d4d3c..be8c7313aa 100644
--- a/docs/man/xl-network-configuration.5.pod
+++ b/docs/man/xl-network-configuration.5.pod.in
@@ -169,8 +169,8 @@ number. Likewise the default tap name is C<vifDOMID.DEVID-emu>.
 
 Specifies the hotplug script to run to configure this device (e.g. to
 add it to the relevant bridge). Defaults to
-C<XEN_SCRIPT_DIR/vif-bridge> but can be set to any script. Some example
-scripts are installed in C<XEN_SCRIPT_DIR>.
+C<@XEN_SCRIPT_DIR@/vif-bridge> but can be set to any script. Some example
+scripts are installed in C<@XEN_SCRIPT_DIR@>.
 
 
 =head2 ip
diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index 765c169ed2..df98adc9e4 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -571,7 +571,7 @@ See the corresponding option of the I<create> subcommand.
 =item B<-N> I<netbufscript>
 
 Use <netbufscript> to setup network buffering instead of the
-default script (/etc/xen/scripts/remus-netbuf-setup).
+default script (@XEN_SCRIPT_DIR@/remus-netbuf-setup).
 
 =item B<-F>
 
diff --git a/docs/man/xl.conf.5.pod b/docs/man/xl.conf.5.pod.in
similarity index 97%
rename from docs/man/xl.conf.5.pod
rename to docs/man/xl.conf.5.pod.in
index dfea9d64ba..b48e99131a 100644
--- a/docs/man/xl.conf.5.pod
+++ b/docs/man/xl.conf.5.pod.in
@@ -107,7 +107,7 @@ Configures the default hotplug script used by virtual network devices.
 
 The old B<vifscript> option is deprecated and should not be used.
 
-Default: C</etc/xen/scripts/vif-bridge>
+Default: C<@XEN_SCRIPT_DIR@/vif-bridge>
 
 =item B<vif.default.bridge="NAME">
 
@@ -133,13 +133,13 @@ Default: C<None>
 
 Configures the default script used by Remus to setup network buffering.
 
-Default: C</etc/xen/scripts/remus-netbuf-setup>
+Default: C<@XEN_SCRIPT_DIR@/remus-netbuf-setup>
 
 =item B<colo.default.proxyscript="PATH">
 
 Configures the default script used by COLO to setup colo-proxy.
 
-Default: C</etc/xen/scripts/colo-proxy-setup>
+Default: C<@XEN_SCRIPT_DIR@/colo-proxy-setup>
 
 =item B<output_format="json|sxp">
 
diff --git a/docs/misc/block-scripts.txt b/docs/misc/block-scripts.txt
index eabab100a8..8020787a52 100644
--- a/docs/misc/block-scripts.txt
+++ b/docs/misc/block-scripts.txt
@@ -18,7 +18,7 @@ Setup
 
 It is highly recommended that custom hotplug scripts as much as
 possible include and use the common Xen functionality.  If the script
-is run from the normal block script location (/etc/xen/scripts by
+is run from the normal block script location (/usr/lib/xen/scripts by
 default), then this can be done by adding the following to the top of
 the script:
 
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 6ab5e47da3..37710880d3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -521,7 +521,7 @@ struct cmd_spec cmd_table[] = {
       "-e                      Do not wait in the background (on <host>) for the death\n"
       "                        of the domain.\n"
       "-N <netbufscript>       Use netbufscript to setup network buffering instead of the\n"
-      "                        default script (/etc/xen/scripts/remus-netbuf-setup).\n"
+      "                        default script (" XEN_SCRIPT_DIR "/remus-netbuf-setup).\n"
       "-F                      Enable unsafe configurations [-b|-n|-d flags]. Use this option\n"
       "                        with caution as failover may not work as intended.\n"
       "-b                      Replicate memory checkpoints to /dev/null (blackhole).\n"


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (5 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 16:22   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 08/39] xl: fix description of migrate --debug Olaf Hering
                   ` (31 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

During 'xl -v.. migrate domU host' a large amount of debug is generated.
It is difficult to map each line to the sending and receiving side.
Also the time spent for migration is not reported.

With 'xl migrate -T domU host' both sides will print timestamps and
also the pid of the invoked xl process to make it more obvious which
side produced a given log line.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 docs/man/xl.1.pod.in   |  4 ++++
 tools/xl/xl_cmdtable.c |  1 +
 tools/xl/xl_migrate.c  | 25 +++++++++++++++++++++----
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index df98adc9e4..494a84ee13 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -475,6 +475,10 @@ domain. See the corresponding option of the I<create> subcommand.
 Send the specified <config> file instead of the file used on creation of the
 domain.
 
+=item B<-T>
+
+Include timestamps in output.
+
 =item B<--debug>
 
 Display huge (!) amount of debug information during the migration process.
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 37710880d3..da0473ddfb 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -167,6 +167,7 @@ struct cmd_spec cmd_table[] = {
       "                migrate-receive [-d -e]\n"
       "-e              Do not wait in the background (on <host>) for the death\n"
       "                of the domain.\n"
+      "-T              Show timestamps during the migration process.\n"
       "--debug         Print huge (!) amount of debug during the migration process.\n"
       "-p              Do not unpause domain after migrating it.\n"
       "-D              Preserve the domain id"
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 0813beb801..856a6e2be1 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -32,6 +32,8 @@
 
 #ifndef LIBXL_HAVE_NO_SUSPEND_RESUME
 
+static bool timestamps;
+
 static pid_t create_migration_child(const char *rune, int *send_fd,
                                         int *recv_fd)
 {
@@ -187,6 +189,7 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     char rc_buf;
     uint8_t *config_data;
     int config_len, flags = LIBXL_SUSPEND_LIVE;
+    unsigned xtl_flags = XTL_STDIOSTREAM_HIDE_PROGRESS;
 
     save_domain_core_begin(domid, preserve_domid, override_config_file,
                            &config_data, &config_len);
@@ -202,7 +205,9 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     migrate_do_preamble(send_fd, recv_fd, child, config_data, config_len,
                         rune);
 
-    xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0);
+    if (timestamps)
+        xtl_flags |= XTL_STDIOSTREAM_SHOW_DATE | XTL_STDIOSTREAM_SHOW_PID;
+    xtl_stdiostream_adjust_flags(logger, xtl_flags, 0);
 
     if (debug)
         flags |= LIBXL_SUSPEND_DEBUG;
@@ -328,6 +333,11 @@ static void migrate_receive(int debug, int daemonize, int monitor,
     char rc_buf;
     char *migration_domname;
     struct domain_create dom_info;
+    unsigned xtl_flags = 0;
+
+    if (timestamps)
+        xtl_flags |= XTL_STDIOSTREAM_SHOW_DATE | XTL_STDIOSTREAM_SHOW_PID;
+    xtl_stdiostream_adjust_flags(logger, xtl_flags, 0);
 
     signal(SIGPIPE, SIG_IGN);
     /* if we get SIGPIPE we'd rather just have it as an error */
@@ -491,7 +501,7 @@ int main_migrate_receive(int argc, char **argv)
         COMMON_LONG_OPTS
     };
 
-    SWITCH_FOREACH_OPT(opt, "Fedrp", opts, "migrate-receive", 0) {
+    SWITCH_FOREACH_OPT(opt, "FedrpT", opts, "migrate-receive", 0) {
     case 'F':
         daemonize = 0;
         break;
@@ -517,6 +527,9 @@ int main_migrate_receive(int argc, char **argv)
     case 'p':
         pause_after_migration = 1;
         break;
+    case 'T':
+        timestamps = 1;
+        break;
     }
 
     if (argc-optind != 0) {
@@ -545,7 +558,7 @@ int main_migrate(int argc, char **argv)
         COMMON_LONG_OPTS
     };
 
-    SWITCH_FOREACH_OPT(opt, "FC:s:epD", opts, "migrate", 2) {
+    SWITCH_FOREACH_OPT(opt, "FC:s:eTpD", opts, "migrate", 2) {
     case 'C':
         config_filename = optarg;
         break;
@@ -559,6 +572,9 @@ int main_migrate(int argc, char **argv)
         daemonize = 0;
         monitor = 0;
         break;
+    case 'T':
+        timestamps = 1;
+        break;
     case 'p':
         pause_after_migration = 1;
         break;
@@ -592,11 +608,12 @@ int main_migrate(int argc, char **argv)
         } else {
             verbose_len = (minmsglevel_default - minmsglevel) + 2;
         }
-        xasprintf(&rune, "exec %s %s xl%s%.*s migrate-receive%s%s%s",
+        xasprintf(&rune, "exec %s %s xl%s%.*s migrate-receive%s%s%s%s",
                   ssh_command, host,
                   pass_tty_arg ? " -t" : "",
                   verbose_len, verbose_buf,
                   daemonize ? "" : " -e",
+                  timestamps ? " -T" : "",
                   debug ? " -d" : "",
                   pause_after_migration ? " -p" : "");
     }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 08/39] xl: fix description of migrate --debug
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (6 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-02-08 16:25   ` Ian Jackson
  2021-01-11 17:41 ` [PATCH v20210111 09/39] tools: add readv_exact to libxenctrl Olaf Hering
                   ` (30 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

xl migrate --debug used to track every pfn in every batch of pages.
But these times are gone. Adjust the help text to tell what --debug
is supposed to do today.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 docs/man/xl.1.pod.in   | 4 +++-
 tools/xl/xl_cmdtable.c | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index 494a84ee13..e6e4e8e83a 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -481,7 +481,9 @@ Include timestamps in output.
 
 =item B<--debug>
 
-Display huge (!) amount of debug information during the migration process.
+Verify transferred domU page data. All memory will be transferred one more
+time to the destination host while the domU is paused, and compared with
+the result of the inital transfer while the domU was still running.
 
 =item B<-p>
 
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index da0473ddfb..a0567169bf 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -168,7 +168,7 @@ struct cmd_spec cmd_table[] = {
       "-e              Do not wait in the background (on <host>) for the death\n"
       "                of the domain.\n"
       "-T              Show timestamps during the migration process.\n"
-      "--debug         Print huge (!) amount of debug during the migration process.\n"
+      "--debug         Verify transferred domU page data.\n"
       "-p              Do not unpause domain after migrating it.\n"
       "-D              Preserve the domain id"
     },


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 09/39] tools: add readv_exact to libxenctrl
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (7 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 08/39] xl: fix description of migrate --debug Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 10/39] tools: add xc_is_known_page_type " Olaf Hering
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu

Read a batch of iovec's.

In the common case of short reads, finish individual iov's with read_exact.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/ctrl/xc_private.c | 55 +++++++++++++++++++++++++++++++++++-
 tools/libs/ctrl/xc_private.h |  1 +
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/tools/libs/ctrl/xc_private.c b/tools/libs/ctrl/xc_private.c
index d94f846686..ea420b9ba8 100644
--- a/tools/libs/ctrl/xc_private.c
+++ b/tools/libs/ctrl/xc_private.c
@@ -659,8 +659,23 @@ int write_exact(int fd, const void *data, size_t size)
 
 #if defined(__MINIOS__)
 /*
- * MiniOS's libc doesn't know about writev(). Implement it as multiple write()s.
+ * MiniOS's libc doesn't know about readv/writev().
+ * Implement it as multiple read/write()s.
  */
+int readv_exact(int fd, const struct iovec *iov, int iovcnt)
+{
+    int rc, i;
+
+    for ( i = 0; i < iovcnt; ++i )
+    {
+        rc = read_exact(fd, iov[i].iov_base, iov[i].iov_len);
+        if ( rc )
+            return rc;
+    }
+
+    return 0;
+}
+
 int writev_exact(int fd, const struct iovec *iov, int iovcnt)
 {
     int rc, i;
@@ -675,6 +690,44 @@ int writev_exact(int fd, const struct iovec *iov, int iovcnt)
     return 0;
 }
 #else
+int readv_exact(int fd, const struct iovec *iov, int iovcnt)
+{
+    int rc = 0, idx = 0;
+    ssize_t len;
+
+    while ( idx < iovcnt )
+    {
+        len = readv(fd, &iov[idx], min(iovcnt - idx, IOV_MAX));
+        if ( len == -1 && errno == EINTR )
+            continue;
+        if ( len <= 0 )
+        {
+            rc = -1;
+            goto out;
+        }
+        while ( len > 0 && idx < iovcnt )
+        {
+            if ( len >= iov[idx].iov_len )
+            {
+                len -= iov[idx].iov_len;
+            }
+            else
+            {
+                void *p = iov[idx].iov_base + len;
+                size_t l = iov[idx].iov_len - len;
+
+                rc = read_exact(fd, p, l);
+                if ( rc )
+                    goto out;
+                len = 0;
+            }
+            idx++;
+        }
+    }
+out:
+    return rc;
+}
+
 int writev_exact(int fd, const struct iovec *iov, int iovcnt)
 {
     struct iovec *local_iov = NULL;
diff --git a/tools/libs/ctrl/xc_private.h b/tools/libs/ctrl/xc_private.h
index f0b5f83ac8..5d2c7274fb 100644
--- a/tools/libs/ctrl/xc_private.h
+++ b/tools/libs/ctrl/xc_private.h
@@ -441,6 +441,7 @@ int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu);
 
 /* Return 0 on success; -1 on error setting errno. */
 int read_exact(int fd, void *data, size_t size); /* EOF => -1, errno=0 */
+int readv_exact(int fd, const struct iovec *iov, int iovcnt);
 int write_exact(int fd, const void *data, size_t size);
 int writev_exact(int fd, const struct iovec *iov, int iovcnt);
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 10/39] tools: add xc_is_known_page_type to libxenctrl
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (8 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 09/39] tools: add readv_exact to libxenctrl Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 11/39] tools: use xc_is_known_page_type Olaf Hering
                   ` (28 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu

Users of xc_get_pfn_type_batch may want to sanity check the data
returned by Xen. Add a simple helper for this purpose.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/ctrl/xc_private.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/tools/libs/ctrl/xc_private.h b/tools/libs/ctrl/xc_private.h
index 5d2c7274fb..afb08aafe1 100644
--- a/tools/libs/ctrl/xc_private.h
+++ b/tools/libs/ctrl/xc_private.h
@@ -421,6 +421,39 @@ void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
 int xc_get_pfn_type_batch(xc_interface *xch, uint32_t dom,
                           unsigned int num, xen_pfn_t *);
 
+/* Sanitiy check for types returned by Xen */
+static inline bool xc_is_known_page_type(xen_pfn_t type)
+{
+    bool ret;
+
+    switch (type)
+    {
+    case XEN_DOMCTL_PFINFO_NOTAB:
+
+    case XEN_DOMCTL_PFINFO_L1TAB:
+    case XEN_DOMCTL_PFINFO_L1TAB | XEN_DOMCTL_PFINFO_LPINTAB:
+
+    case XEN_DOMCTL_PFINFO_L2TAB:
+    case XEN_DOMCTL_PFINFO_L2TAB | XEN_DOMCTL_PFINFO_LPINTAB:
+
+    case XEN_DOMCTL_PFINFO_L3TAB:
+    case XEN_DOMCTL_PFINFO_L3TAB | XEN_DOMCTL_PFINFO_LPINTAB:
+
+    case XEN_DOMCTL_PFINFO_L4TAB:
+    case XEN_DOMCTL_PFINFO_L4TAB | XEN_DOMCTL_PFINFO_LPINTAB:
+
+    case XEN_DOMCTL_PFINFO_XTAB:
+    case XEN_DOMCTL_PFINFO_XALLOC:
+    case XEN_DOMCTL_PFINFO_BROKEN:
+        ret = true;
+        break;
+    default:
+        ret = false;
+        break;
+    }
+    return ret;
+}
+
 void bitmap_64_to_byte(uint8_t *bp, const uint64_t *lp, int nbits);
 void bitmap_byte_to_64(uint64_t *lp, const uint8_t *bp, int nbits);
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 11/39] tools: use xc_is_known_page_type
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (9 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 10/39] tools: add xc_is_known_page_type " Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 12/39] tools: unify type checking for data pfns in migration stream Olaf Hering
                   ` (27 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Verify pfn type on sending side, also verify incoming batch of pfns.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_restore.c | 3 +--
 tools/libs/guest/xg_sr_save.c    | 6 ++++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index b57a787519..f1c3169229 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -406,8 +406,7 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         }
 
         type = (pages->pfn[i] & PAGE_DATA_TYPE_MASK) >> 32;
-        if ( ((type >> XEN_DOMCTL_PFINFO_LTAB_SHIFT) >= 5) &&
-             ((type >> XEN_DOMCTL_PFINFO_LTAB_SHIFT) <= 8) )
+        if ( xc_is_known_page_type(type) == false )
         {
             ERROR("Invalid type %#"PRIx32" for pfn %#"PRIpfn" (index %u)",
                   type, pfn, i);
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 2ba7c3200c..044d0ae3aa 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -147,6 +147,12 @@ static int write_batch(struct xc_sr_context *ctx)
 
     for ( i = 0; i < nr_pfns; ++i )
     {
+        if ( xc_is_known_page_type(types[i]) == false )
+        {
+            ERROR("Wrong type %#"PRIpfn" for pfn %#"PRIpfn, types[i], mfns[i]);
+            goto err;
+        }
+
         switch ( types[i] )
         {
         case XEN_DOMCTL_PFINFO_BROKEN:


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 12/39] tools: unify type checking for data pfns in migration stream
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (10 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 11/39] tools: use xc_is_known_page_type Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 13/39] tools: show migration transfer rate in send_dirty_pages Olaf Hering
                   ` (26 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Introduce a helper which decides if a given pfn type has data
for the migration stream.

No change in behavior intended.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  | 17 ++++++++++++++++
 tools/libs/guest/xg_sr_restore.c | 34 +++++---------------------------
 tools/libs/guest/xg_sr_save.c    | 14 ++-----------
 3 files changed, 24 insertions(+), 41 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index cc3ad1c394..70e328e951 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -455,6 +455,23 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
 /* Handle a STATIC_DATA_END record. */
 int handle_static_data_end(struct xc_sr_context *ctx);
 
+static inline bool page_type_has_stream_data(uint32_t type)
+{
+    bool ret;
+
+    switch (type)
+    {
+    case XEN_DOMCTL_PFINFO_XTAB:
+    case XEN_DOMCTL_PFINFO_XALLOC:
+    case XEN_DOMCTL_PFINFO_BROKEN:
+        ret = false;
+        break;
+    default:
+        ret = true;
+        break;
+    }
+    return ret;
+}
 #endif
 /*
  * Local variables:
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index f1c3169229..0332ae9f32 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -152,9 +152,8 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
 
     for ( i = 0; i < count; ++i )
     {
-        if ( (!types || (types &&
-                         (types[i] != XEN_DOMCTL_PFINFO_XTAB &&
-                          types[i] != XEN_DOMCTL_PFINFO_BROKEN))) &&
+        if ( (!types ||
+              (types && page_type_has_stream_data(types[i]) == true)) &&
              !pfn_is_populated(ctx, original_pfns[i]) )
         {
             rc = pfn_set_populated(ctx, original_pfns[i]);
@@ -233,25 +232,8 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
     {
         ctx->restore.ops.set_page_type(ctx, pfns[i], types[i]);
 
-        switch ( types[i] )
-        {
-        case XEN_DOMCTL_PFINFO_NOTAB:
-
-        case XEN_DOMCTL_PFINFO_L1TAB:
-        case XEN_DOMCTL_PFINFO_L1TAB | XEN_DOMCTL_PFINFO_LPINTAB:
-
-        case XEN_DOMCTL_PFINFO_L2TAB:
-        case XEN_DOMCTL_PFINFO_L2TAB | XEN_DOMCTL_PFINFO_LPINTAB:
-
-        case XEN_DOMCTL_PFINFO_L3TAB:
-        case XEN_DOMCTL_PFINFO_L3TAB | XEN_DOMCTL_PFINFO_LPINTAB:
-
-        case XEN_DOMCTL_PFINFO_L4TAB:
-        case XEN_DOMCTL_PFINFO_L4TAB | XEN_DOMCTL_PFINFO_LPINTAB:
-
+        if ( page_type_has_stream_data(types[i]) == true )
             mfns[nr_pages++] = ctx->restore.ops.pfn_to_gfn(ctx, pfns[i]);
-            break;
-        }
     }
 
     /* Nothing to do? */
@@ -271,14 +253,8 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
 
     for ( i = 0, j = 0; i < count; ++i )
     {
-        switch ( types[i] )
-        {
-        case XEN_DOMCTL_PFINFO_XTAB:
-        case XEN_DOMCTL_PFINFO_BROKEN:
-        case XEN_DOMCTL_PFINFO_XALLOC:
-            /* No page data to deal with. */
+        if ( page_type_has_stream_data(types[i]) == false )
             continue;
-        }
 
         if ( map_errs[j] )
         {
@@ -413,7 +389,7 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
             goto err;
         }
 
-        if ( type < XEN_DOMCTL_PFINFO_BROKEN )
+        if ( page_type_has_stream_data(type) == true )
             /* NOTAB and all L1 through L4 tables (including pinned) should
              * have a page worth of data in the record. */
             pages_of_data++;
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 044d0ae3aa..0546d3d9e6 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -153,13 +153,8 @@ static int write_batch(struct xc_sr_context *ctx)
             goto err;
         }
 
-        switch ( types[i] )
-        {
-        case XEN_DOMCTL_PFINFO_BROKEN:
-        case XEN_DOMCTL_PFINFO_XALLOC:
-        case XEN_DOMCTL_PFINFO_XTAB:
+        if ( page_type_has_stream_data(types[i]) == false )
             continue;
-        }
 
         mfns[nr_pages++] = mfns[i];
     }
@@ -177,13 +172,8 @@ static int write_batch(struct xc_sr_context *ctx)
 
         for ( i = 0, p = 0; i < nr_pfns; ++i )
         {
-            switch ( types[i] )
-            {
-            case XEN_DOMCTL_PFINFO_BROKEN:
-            case XEN_DOMCTL_PFINFO_XALLOC:
-            case XEN_DOMCTL_PFINFO_XTAB:
+            if ( page_type_has_stream_data(types[i]) == false )
                 continue;
-            }
 
             if ( errors[p] )
             {


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 13/39] tools: show migration transfer rate in send_dirty_pages
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (11 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 12/39] tools: unify type checking for data pfns in migration stream Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 17:41 ` [PATCH v20210111 14/39] tools/guest: prepare to allocate arrays once Olaf Hering
                   ` (25 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Show how fast domU pages are transferred in each iteration.

The relevant data is how fast the pfns travel, not so much how much
protocol overhead exists. So the reported MiB/sec is just for pfns.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h |  2 ++
 tools/libs/guest/xg_sr_save.c   | 47 +++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 70e328e951..f3a7a29298 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -238,6 +238,8 @@ struct xc_sr_context
             bool debug;
 
             unsigned long p2m_size;
+            size_t pages_sent;
+            size_t overhead_sent;
 
             struct precopy_stats stats;
 
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 0546d3d9e6..da031fcfce 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <arpa/inet.h>
+#include <time.h>
 
 #include "xg_sr_common.h"
 
@@ -238,6 +239,8 @@ static int write_batch(struct xc_sr_context *ctx)
     iov[3].iov_len = nr_pfns * sizeof(*rec_pfns);
 
     iovcnt = 4;
+    ctx->save.pages_sent += nr_pages;
+    ctx->save.overhead_sent += sizeof(rec) + sizeof(hdr) + nr_pfns * sizeof(*rec_pfns);
 
     if ( nr_pages )
     {
@@ -357,6 +360,43 @@ static int suspend_domain(struct xc_sr_context *ctx)
     return 0;
 }
 
+static void show_transfer_rate(struct xc_sr_context *ctx, struct timespec *start)
+{
+    xc_interface *xch = ctx->xch;
+    struct timespec end = {}, diff = {};
+    size_t ms, MiB_sec = ctx->save.pages_sent * PAGE_SIZE;
+
+    if (!MiB_sec)
+        return;
+
+    if ( clock_gettime(CLOCK_MONOTONIC, &end) )
+        PERROR("clock_gettime");
+
+    if ( (end.tv_nsec - start->tv_nsec) < 0 )
+    {
+        diff.tv_sec = end.tv_sec - start->tv_sec - 1;
+        diff.tv_nsec = end.tv_nsec - start->tv_nsec + (1000U*1000U*1000U);
+    }
+    else
+    {
+        diff.tv_sec = end.tv_sec - start->tv_sec;
+        diff.tv_nsec = end.tv_nsec - start->tv_nsec;
+    }
+
+    ms = (diff.tv_nsec / (1000U*1000U));
+    if (!ms)
+        ms = 1;
+    ms += (diff.tv_sec * 1000U);
+
+    MiB_sec *= 1000U;
+    MiB_sec /= ms;
+    MiB_sec /= 1024U*1024U;
+
+    errno = 0;
+    IPRINTF("%s: %zu bytes + %zu pages in %ld.%09ld sec, %zu MiB/sec", __func__,
+            ctx->save.overhead_sent, ctx->save.pages_sent, diff.tv_sec, diff.tv_nsec, MiB_sec);
+}
+
 /*
  * Send a subset of pages in the guests p2m, according to the dirty bitmap.
  * Used for each subsequent iteration of the live migration loop.
@@ -370,9 +410,15 @@ static int send_dirty_pages(struct xc_sr_context *ctx,
     xen_pfn_t p;
     unsigned long written;
     int rc;
+    struct timespec start = {};
     DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
                                     &ctx->save.dirty_bitmap_hbuf);
 
+    ctx->save.pages_sent = 0;
+    ctx->save.overhead_sent = 0;
+    if ( clock_gettime(CLOCK_MONOTONIC, &start) )
+        PERROR("clock_gettime");
+
     for ( p = 0, written = 0; p < ctx->save.p2m_size; ++p )
     {
         if ( !test_bit(p, dirty_bitmap) )
@@ -396,6 +442,7 @@ static int send_dirty_pages(struct xc_sr_context *ctx,
     if ( written > entries )
         DPRINTF("Bitmap contained more entries than expected...");
 
+    show_transfer_rate(ctx, &start);
     xc_report_progress_step(xch, entries, entries);
 
     return ctx->save.ops.check_vm_state(ctx);


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 14/39] tools/guest: prepare to allocate arrays once
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (12 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 13/39] tools: show migration transfer rate in send_dirty_pages Olaf Hering
@ 2021-01-11 17:41 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 15/39] tools/guest: save: move batch_pfns Olaf Hering
                   ` (24 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

The hotpath 'send_dirty_pages' is supposed to do just one thing: sending.
The other end 'handle_page_data' is supposed to do just receiving.

But instead both do other costly work like memory allocations and data moving.
Do the allocations once, the array sizes are a compiletime constant.
Avoid unneeded copying of data by receiving data directly into mapped guest memory.

This patch is just prepartion, subsequent changes will populate the arrays.

Once all changes are applied, migration of a busy HVM domU changes like that:

Without this series, from sr650 to sr950 (xen-4.15.20201027T173911.16a20963b3 xen_testing):
2020-10-29 10:23:10.711+0000: xc: show_transfer_rate: 23663128 bytes + 2879563 pages in 55.324905335 sec, 203 MiB/sec: Internal error
2020-10-29 10:23:35.115+0000: xc: show_transfer_rate: 16829632 bytes + 2097552 pages in 24.401179720 sec, 335 MiB/sec: Internal error
2020-10-29 10:23:59.436+0000: xc: show_transfer_rate: 16829032 bytes + 2097478 pages in 24.319025928 sec, 336 MiB/sec: Internal error
2020-10-29 10:24:23.844+0000: xc: show_transfer_rate: 16829024 bytes + 2097477 pages in 24.406992500 sec, 335 MiB/sec: Internal error
2020-10-29 10:24:48.292+0000: xc: show_transfer_rate: 16828912 bytes + 2097463 pages in 24.446489027 sec, 335 MiB/sec: Internal error
2020-10-29 10:25:01.816+0000: xc: show_transfer_rate: 16836080 bytes + 2098356 pages in 13.447091818 sec, 609 MiB/sec: Internal error

With this series, from sr650 to sr950 (xen-4.15.20201027T173911.16a20963b3 xen_unstable):
2020-10-28 21:26:05.074+0000: xc: show_transfer_rate: 23663128 bytes + 2879563 pages in 52.564054368 sec, 213 MiB/sec: Internal error
2020-10-28 21:26:23.527+0000: xc: show_transfer_rate: 16830040 bytes + 2097603 pages in 18.450592015 sec, 444 MiB/sec: Internal error
2020-10-28 21:26:41.926+0000: xc: show_transfer_rate: 16830944 bytes + 2097717 pages in 18.397862306 sec, 445 MiB/sec: Internal error
2020-10-28 21:27:00.339+0000: xc: show_transfer_rate: 16829176 bytes + 2097498 pages in 18.411973339 sec, 445 MiB/sec: Internal error
2020-10-28 21:27:18.643+0000: xc: show_transfer_rate: 16828592 bytes + 2097425 pages in 18.303326695 sec, 447 MiB/sec: Internal error
2020-10-28 21:27:26.289+0000: xc: show_transfer_rate: 16835952 bytes + 2098342 pages in 7.579846749 sec, 1081 MiB/sec: Internal error

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  | 8 ++++++++
 tools/libs/guest/xg_sr_restore.c | 8 ++++++++
 tools/libs/guest/xg_sr_save.c    | 4 +++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index f3a7a29298..62bc87b5f4 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -211,6 +211,12 @@ static inline int update_blob(struct xc_sr_blob *blob,
     return 0;
 }
 
+struct xc_sr_save_arrays {
+};
+
+struct xc_sr_restore_arrays {
+};
+
 struct xc_sr_context
 {
     xc_interface *xch;
@@ -248,6 +254,7 @@ struct xc_sr_context
             unsigned long *deferred_pages;
             unsigned long nr_deferred_pages;
             xc_hypercall_buffer_t dirty_bitmap_hbuf;
+            struct xc_sr_save_arrays *m;
         } save;
 
         struct /* Restore data. */
@@ -299,6 +306,7 @@ struct xc_sr_context
 
             /* Sender has invoked verify mode on the stream. */
             bool verify;
+            struct xc_sr_restore_arrays *m;
         } restore;
     };
 
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 0332ae9f32..4a9ece9681 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -739,6 +739,13 @@ static int setup(struct xc_sr_context *ctx)
     }
     ctx->restore.allocated_rec_num = DEFAULT_BUF_RECORDS;
 
+    ctx->restore.m = malloc(sizeof(*ctx->restore.m));
+    if ( !ctx->restore.m ) {
+        ERROR("Unable to allocate memory for arrays");
+        rc = -1;
+        goto err;
+    }
+
  err:
     return rc;
 }
@@ -757,6 +764,7 @@ static void cleanup(struct xc_sr_context *ctx)
         xc_hypercall_buffer_free_pages(
             xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->restore.p2m_size)));
 
+    free(ctx->restore.m);
     free(ctx->restore.buffered_records);
     free(ctx->restore.populated_pfns);
 
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index da031fcfce..baaeb12762 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -853,8 +853,9 @@ static int setup(struct xc_sr_context *ctx)
     ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE *
                                   sizeof(*ctx->save.batch_pfns));
     ctx->save.deferred_pages = bitmap_alloc(ctx->save.p2m_size);
+    ctx->save.m = malloc(sizeof(*ctx->save.m));
 
-    if ( !ctx->save.batch_pfns || !dirty_bitmap || !ctx->save.deferred_pages )
+    if ( !ctx->save.m || !ctx->save.batch_pfns || !dirty_bitmap || !ctx->save.deferred_pages )
     {
         ERROR("Unable to allocate memory for dirty bitmaps, batch pfns and"
               " deferred pages");
@@ -886,6 +887,7 @@ static void cleanup(struct xc_sr_context *ctx)
                                    NRPAGES(bitmap_size(ctx->save.p2m_size)));
     free(ctx->save.deferred_pages);
     free(ctx->save.batch_pfns);
+    free(ctx->save.m);
 }
 
 /*


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 15/39] tools/guest: save: move batch_pfns
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (13 preceding siblings ...)
  2021-01-11 17:41 ` [PATCH v20210111 14/39] tools/guest: prepare to allocate arrays once Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-02-08 17:46   ` Ian Jackson
  2021-01-11 17:42 ` [PATCH v20210111 16/39] tools/guest: save: move mfns array Olaf Hering
                   ` (23 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

The batch_pfns array is already allocated in advance.
Move it into the preallocated area.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h |  2 +-
 tools/libs/guest/xg_sr_save.c   | 25 +++++++++++--------------
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 62bc87b5f4..c78a07b8f8 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -212,6 +212,7 @@ static inline int update_blob(struct xc_sr_blob *blob,
 }
 
 struct xc_sr_save_arrays {
+    xen_pfn_t batch_pfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_restore_arrays {
@@ -249,7 +250,6 @@ struct xc_sr_context
 
             struct precopy_stats stats;
 
-            xen_pfn_t *batch_pfns;
             unsigned int nr_batch_pfns;
             unsigned long *deferred_pages;
             unsigned long nr_deferred_pages;
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index baaeb12762..700344b6b6 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -77,7 +77,7 @@ static int write_checkpoint_record(struct xc_sr_context *ctx)
 
 /*
  * Writes a batch of memory as a PAGE_DATA record into the stream.  The batch
- * is constructed in ctx->save.batch_pfns.
+ * is constructed in ctx->save.m->batch_pfns.
  *
  * This function:
  * - gets the types for each pfn in the batch.
@@ -128,12 +128,12 @@ static int write_batch(struct xc_sr_context *ctx)
     for ( i = 0; i < nr_pfns; ++i )
     {
         types[i] = mfns[i] = ctx->save.ops.pfn_to_gfn(ctx,
-                                                      ctx->save.batch_pfns[i]);
+                                                      ctx->save.m->batch_pfns[i]);
 
         /* Likely a ballooned page. */
         if ( mfns[i] == INVALID_MFN )
         {
-            set_bit(ctx->save.batch_pfns[i], ctx->save.deferred_pages);
+            set_bit(ctx->save.m->batch_pfns[i], ctx->save.deferred_pages);
             ++ctx->save.nr_deferred_pages;
         }
     }
@@ -179,7 +179,7 @@ static int write_batch(struct xc_sr_context *ctx)
             if ( errors[p] )
             {
                 ERROR("Mapping of pfn %#"PRIpfn" (mfn %#"PRIpfn") failed %d",
-                      ctx->save.batch_pfns[i], mfns[p], errors[p]);
+                      ctx->save.m->batch_pfns[i], mfns[p], errors[p]);
                 goto err;
             }
 
@@ -193,7 +193,7 @@ static int write_batch(struct xc_sr_context *ctx)
             {
                 if ( rc == -1 && errno == EAGAIN )
                 {
-                    set_bit(ctx->save.batch_pfns[i], ctx->save.deferred_pages);
+                    set_bit(ctx->save.m->batch_pfns[i], ctx->save.deferred_pages);
                     ++ctx->save.nr_deferred_pages;
                     types[i] = XEN_DOMCTL_PFINFO_XTAB;
                     --nr_pages;
@@ -224,7 +224,7 @@ static int write_batch(struct xc_sr_context *ctx)
     rec.length += nr_pages * PAGE_SIZE;
 
     for ( i = 0; i < nr_pfns; ++i )
-        rec_pfns[i] = ((uint64_t)(types[i]) << 32) | ctx->save.batch_pfns[i];
+        rec_pfns[i] = ((uint64_t)(types[i]) << 32) | ctx->save.m->batch_pfns[i];
 
     iov[0].iov_base = &rec.type;
     iov[0].iov_len = sizeof(rec.type);
@@ -296,9 +296,9 @@ static int flush_batch(struct xc_sr_context *ctx)
 
     if ( !rc )
     {
-        VALGRIND_MAKE_MEM_UNDEFINED(ctx->save.batch_pfns,
+        VALGRIND_MAKE_MEM_UNDEFINED(ctx->save.m->batch_pfns,
                                     MAX_BATCH_SIZE *
-                                    sizeof(*ctx->save.batch_pfns));
+                                    sizeof(*ctx->save.m->batch_pfns));
     }
 
     return rc;
@@ -315,7 +315,7 @@ static int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
         rc = flush_batch(ctx);
 
     if ( rc == 0 )
-        ctx->save.batch_pfns[ctx->save.nr_batch_pfns++] = pfn;
+        ctx->save.m->batch_pfns[ctx->save.nr_batch_pfns++] = pfn;
 
     return rc;
 }
@@ -850,14 +850,12 @@ static int setup(struct xc_sr_context *ctx)
 
     dirty_bitmap = xc_hypercall_buffer_alloc_pages(
         xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size)));
-    ctx->save.batch_pfns = malloc(MAX_BATCH_SIZE *
-                                  sizeof(*ctx->save.batch_pfns));
     ctx->save.deferred_pages = bitmap_alloc(ctx->save.p2m_size);
     ctx->save.m = malloc(sizeof(*ctx->save.m));
 
-    if ( !ctx->save.m || !ctx->save.batch_pfns || !dirty_bitmap || !ctx->save.deferred_pages )
+    if ( !ctx->save.m || !dirty_bitmap || !ctx->save.deferred_pages )
     {
-        ERROR("Unable to allocate memory for dirty bitmaps, batch pfns and"
+        ERROR("Unable to allocate memory for dirty bitmaps and"
               " deferred pages");
         rc = -1;
         errno = ENOMEM;
@@ -886,7 +884,6 @@ static void cleanup(struct xc_sr_context *ctx)
     xc_hypercall_buffer_free_pages(xch, dirty_bitmap,
                                    NRPAGES(bitmap_size(ctx->save.p2m_size)));
     free(ctx->save.deferred_pages);
-    free(ctx->save.batch_pfns);
     free(ctx->save.m);
 }
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 16/39] tools/guest: save: move mfns array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (14 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 15/39] tools/guest: save: move batch_pfns Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 17/39] tools/guest: save: move types array Olaf Hering
                   ` (22 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move mfns array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h | 2 ++
 tools/libs/guest/xg_sr_save.c   | 7 ++-----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index c78a07b8f8..0c2bef8f78 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -213,6 +213,8 @@ static inline int update_blob(struct xc_sr_blob *blob,
 
 struct xc_sr_save_arrays {
     xen_pfn_t batch_pfns[MAX_BATCH_SIZE];
+    /* write_batch: Mfns of the batch pfns. */
+    xen_pfn_t mfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_restore_arrays {
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 700344b6b6..fd6437afc0 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -88,7 +88,7 @@ static int write_checkpoint_record(struct xc_sr_context *ctx)
 static int write_batch(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
-    xen_pfn_t *mfns = NULL, *types = NULL;
+    xen_pfn_t *mfns = ctx->save.m->mfns, *types = NULL;
     void *guest_mapping = NULL;
     void **guest_data = NULL;
     void **local_pages = NULL;
@@ -105,8 +105,6 @@ static int write_batch(struct xc_sr_context *ctx)
 
     assert(nr_pfns != 0);
 
-    /* Mfns of the batch pfns. */
-    mfns = malloc(nr_pfns * sizeof(*mfns));
     /* Types of the batch pfns. */
     types = malloc(nr_pfns * sizeof(*types));
     /* Errors from attempting to map the gfns. */
@@ -118,7 +116,7 @@ static int write_batch(struct xc_sr_context *ctx)
     /* iovec[] for writev(). */
     iov = malloc((nr_pfns + 4) * sizeof(*iov));
 
-    if ( !mfns || !types || !errors || !guest_data || !local_pages || !iov )
+    if ( !types || !errors || !guest_data || !local_pages || !iov )
     {
         ERROR("Unable to allocate arrays for a batch of %u pages",
               nr_pfns);
@@ -277,7 +275,6 @@ static int write_batch(struct xc_sr_context *ctx)
     free(guest_data);
     free(errors);
     free(types);
-    free(mfns);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 17/39] tools/guest: save: move types array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (15 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 16/39] tools/guest: save: move mfns array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 18/39] tools/guest: save: move errors array Olaf Hering
                   ` (21 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move types array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h | 2 ++
 tools/libs/guest/xg_sr_save.c   | 7 ++-----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 0c2bef8f78..3cbadb607b 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -215,6 +215,8 @@ struct xc_sr_save_arrays {
     xen_pfn_t batch_pfns[MAX_BATCH_SIZE];
     /* write_batch: Mfns of the batch pfns. */
     xen_pfn_t mfns[MAX_BATCH_SIZE];
+    /* write_batch: Types of the batch pfns. */
+    xen_pfn_t types[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_restore_arrays {
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index fd6437afc0..ff70f62b1e 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -88,7 +88,7 @@ static int write_checkpoint_record(struct xc_sr_context *ctx)
 static int write_batch(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
-    xen_pfn_t *mfns = ctx->save.m->mfns, *types = NULL;
+    xen_pfn_t *mfns = ctx->save.m->mfns, *types = ctx->save.m->types;
     void *guest_mapping = NULL;
     void **guest_data = NULL;
     void **local_pages = NULL;
@@ -105,8 +105,6 @@ static int write_batch(struct xc_sr_context *ctx)
 
     assert(nr_pfns != 0);
 
-    /* Types of the batch pfns. */
-    types = malloc(nr_pfns * sizeof(*types));
     /* Errors from attempting to map the gfns. */
     errors = malloc(nr_pfns * sizeof(*errors));
     /* Pointers to page data to send.  Mapped gfns or local allocations. */
@@ -116,7 +114,7 @@ static int write_batch(struct xc_sr_context *ctx)
     /* iovec[] for writev(). */
     iov = malloc((nr_pfns + 4) * sizeof(*iov));
 
-    if ( !types || !errors || !guest_data || !local_pages || !iov )
+    if ( !errors || !guest_data || !local_pages || !iov )
     {
         ERROR("Unable to allocate arrays for a batch of %u pages",
               nr_pfns);
@@ -274,7 +272,6 @@ static int write_batch(struct xc_sr_context *ctx)
     free(local_pages);
     free(guest_data);
     free(errors);
-    free(types);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 18/39] tools/guest: save: move errors array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (16 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 17/39] tools/guest: save: move types array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 19/39] tools/guest: save: move iov array Olaf Hering
                   ` (20 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move errors array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h | 2 ++
 tools/libs/guest/xg_sr_save.c   | 7 ++-----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 3cbadb607b..71b676c0e0 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -217,6 +217,8 @@ struct xc_sr_save_arrays {
     xen_pfn_t mfns[MAX_BATCH_SIZE];
     /* write_batch: Types of the batch pfns. */
     xen_pfn_t types[MAX_BATCH_SIZE];
+    /* write_batch: Errors from attempting to map the gfns. */
+    int errors[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_restore_arrays {
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index ff70f62b1e..a1bddd5dcb 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -92,7 +92,7 @@ static int write_batch(struct xc_sr_context *ctx)
     void *guest_mapping = NULL;
     void **guest_data = NULL;
     void **local_pages = NULL;
-    int *errors = NULL, rc = -1;
+    int *errors = ctx->save.m->errors, rc = -1;
     unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0;
     unsigned int nr_pfns = ctx->save.nr_batch_pfns;
     void *page, *orig_page;
@@ -105,8 +105,6 @@ static int write_batch(struct xc_sr_context *ctx)
 
     assert(nr_pfns != 0);
 
-    /* Errors from attempting to map the gfns. */
-    errors = malloc(nr_pfns * sizeof(*errors));
     /* Pointers to page data to send.  Mapped gfns or local allocations. */
     guest_data = calloc(nr_pfns, sizeof(*guest_data));
     /* Pointers to locally allocated pages.  Need freeing. */
@@ -114,7 +112,7 @@ static int write_batch(struct xc_sr_context *ctx)
     /* iovec[] for writev(). */
     iov = malloc((nr_pfns + 4) * sizeof(*iov));
 
-    if ( !errors || !guest_data || !local_pages || !iov )
+    if ( !guest_data || !local_pages || !iov )
     {
         ERROR("Unable to allocate arrays for a batch of %u pages",
               nr_pfns);
@@ -271,7 +269,6 @@ static int write_batch(struct xc_sr_context *ctx)
     free(iov);
     free(local_pages);
     free(guest_data);
-    free(errors);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 19/39] tools/guest: save: move iov array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (17 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 18/39] tools/guest: save: move errors array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 20/39] tools/guest: save: move rec_pfns array Olaf Hering
                   ` (19 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move iov array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h | 2 ++
 tools/libs/guest/xg_sr_save.c   | 7 ++-----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 71b676c0e0..f315b4f526 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -219,6 +219,8 @@ struct xc_sr_save_arrays {
     xen_pfn_t types[MAX_BATCH_SIZE];
     /* write_batch: Errors from attempting to map the gfns. */
     int errors[MAX_BATCH_SIZE];
+    /* write_batch: iovec[] for writev(). */
+    struct iovec iov[MAX_BATCH_SIZE + 4];
 };
 
 struct xc_sr_restore_arrays {
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index a1bddd5dcb..1d04bd0a44 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -97,7 +97,7 @@ static int write_batch(struct xc_sr_context *ctx)
     unsigned int nr_pfns = ctx->save.nr_batch_pfns;
     void *page, *orig_page;
     uint64_t *rec_pfns = NULL;
-    struct iovec *iov = NULL; int iovcnt = 0;
+    struct iovec *iov = ctx->save.m->iov; int iovcnt = 0;
     struct xc_sr_rec_page_data_header hdr = { 0 };
     struct xc_sr_record rec = {
         .type = REC_TYPE_PAGE_DATA,
@@ -109,10 +109,8 @@ static int write_batch(struct xc_sr_context *ctx)
     guest_data = calloc(nr_pfns, sizeof(*guest_data));
     /* Pointers to locally allocated pages.  Need freeing. */
     local_pages = calloc(nr_pfns, sizeof(*local_pages));
-    /* iovec[] for writev(). */
-    iov = malloc((nr_pfns + 4) * sizeof(*iov));
 
-    if ( !guest_data || !local_pages || !iov )
+    if ( !guest_data || !local_pages )
     {
         ERROR("Unable to allocate arrays for a batch of %u pages",
               nr_pfns);
@@ -266,7 +264,6 @@ static int write_batch(struct xc_sr_context *ctx)
         xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped);
     for ( i = 0; local_pages && i < nr_pfns; ++i )
         free(local_pages[i]);
-    free(iov);
     free(local_pages);
     free(guest_data);
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 20/39] tools/guest: save: move rec_pfns array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (18 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 19/39] tools/guest: save: move iov array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 21/39] tools/guest: save: move guest_data array Olaf Hering
                   ` (18 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move rec_pfns array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h |  2 ++
 tools/libs/guest/xg_sr_save.c   | 11 +----------
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index f315b4f526..81158a4f4d 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -221,6 +221,8 @@ struct xc_sr_save_arrays {
     int errors[MAX_BATCH_SIZE];
     /* write_batch: iovec[] for writev(). */
     struct iovec iov[MAX_BATCH_SIZE + 4];
+    /* write_batch */
+    uint64_t rec_pfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_restore_arrays {
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 1d04bd0a44..0e34c4b051 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -96,7 +96,7 @@ static int write_batch(struct xc_sr_context *ctx)
     unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0;
     unsigned int nr_pfns = ctx->save.nr_batch_pfns;
     void *page, *orig_page;
-    uint64_t *rec_pfns = NULL;
+    uint64_t *rec_pfns = ctx->save.m->rec_pfns;
     struct iovec *iov = ctx->save.m->iov; int iovcnt = 0;
     struct xc_sr_rec_page_data_header hdr = { 0 };
     struct xc_sr_record rec = {
@@ -201,14 +201,6 @@ static int write_batch(struct xc_sr_context *ctx)
         }
     }
 
-    rec_pfns = malloc(nr_pfns * sizeof(*rec_pfns));
-    if ( !rec_pfns )
-    {
-        ERROR("Unable to allocate %zu bytes of memory for page data pfn list",
-              nr_pfns * sizeof(*rec_pfns));
-        goto err;
-    }
-
     hdr.count = nr_pfns;
 
     rec.length = sizeof(hdr);
@@ -259,7 +251,6 @@ static int write_batch(struct xc_sr_context *ctx)
     rc = ctx->save.nr_batch_pfns = 0;
 
  err:
-    free(rec_pfns);
     if ( guest_mapping )
         xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped);
     for ( i = 0; local_pages && i < nr_pfns; ++i )


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 21/39] tools/guest: save: move guest_data array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (19 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 20/39] tools/guest: save: move rec_pfns array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 22/39] tools/guest: save: move local_pages array Olaf Hering
                   ` (17 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move guest_data array into preallocated space.

Because this was allocated with calloc:
Adjust the loop to clear unused entries as needed.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h |  2 ++
 tools/libs/guest/xg_sr_save.c   | 11 ++++++-----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 81158a4f4d..33e66678c6 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -223,6 +223,8 @@ struct xc_sr_save_arrays {
     struct iovec iov[MAX_BATCH_SIZE + 4];
     /* write_batch */
     uint64_t rec_pfns[MAX_BATCH_SIZE];
+    /* write_batch: Pointers to page data to send. Mapped gfns or local allocations. */
+    void *guest_data[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_restore_arrays {
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index 0e34c4b051..a571246894 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -90,7 +90,7 @@ static int write_batch(struct xc_sr_context *ctx)
     xc_interface *xch = ctx->xch;
     xen_pfn_t *mfns = ctx->save.m->mfns, *types = ctx->save.m->types;
     void *guest_mapping = NULL;
-    void **guest_data = NULL;
+    void **guest_data = ctx->save.m->guest_data;
     void **local_pages = NULL;
     int *errors = ctx->save.m->errors, rc = -1;
     unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0;
@@ -105,12 +105,10 @@ static int write_batch(struct xc_sr_context *ctx)
 
     assert(nr_pfns != 0);
 
-    /* Pointers to page data to send.  Mapped gfns or local allocations. */
-    guest_data = calloc(nr_pfns, sizeof(*guest_data));
     /* Pointers to locally allocated pages.  Need freeing. */
     local_pages = calloc(nr_pfns, sizeof(*local_pages));
 
-    if ( !guest_data || !local_pages )
+    if ( !local_pages )
     {
         ERROR("Unable to allocate arrays for a batch of %u pages",
               nr_pfns);
@@ -166,7 +164,10 @@ static int write_batch(struct xc_sr_context *ctx)
         for ( i = 0, p = 0; i < nr_pfns; ++i )
         {
             if ( page_type_has_stream_data(types[i]) == false )
+            {
+                guest_data[i] = NULL;
                 continue;
+            }
 
             if ( errors[p] )
             {
@@ -183,6 +184,7 @@ static int write_batch(struct xc_sr_context *ctx)
 
             if ( rc )
             {
+                guest_data[i] = NULL;
                 if ( rc == -1 && errno == EAGAIN )
                 {
                     set_bit(ctx->save.m->batch_pfns[i], ctx->save.deferred_pages);
@@ -256,7 +258,6 @@ static int write_batch(struct xc_sr_context *ctx)
     for ( i = 0; local_pages && i < nr_pfns; ++i )
         free(local_pages[i]);
     free(local_pages);
-    free(guest_data);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 22/39] tools/guest: save: move local_pages array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (20 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 21/39] tools/guest: save: move guest_data array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 23/39] tools/guest: restore: move pfns array Olaf Hering
                   ` (16 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move local_pages array into preallocated space.

Adjust the code to use the src page as is in case of HVM.
In case of PV the page may need to be normalised, use an private memory
area for this purpose.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h       | 22 ++++++++++---------
 tools/libs/guest/xg_sr_save.c         | 25 +++------------------
 tools/libs/guest/xg_sr_save_x86_hvm.c |  5 +++--
 tools/libs/guest/xg_sr_save_x86_pv.c  | 31 ++++++++++++++++++---------
 4 files changed, 39 insertions(+), 44 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 33e66678c6..2a020fef5c 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -33,16 +33,12 @@ struct xc_sr_save_ops
      * Optionally transform the contents of a page from being specific to the
      * sending environment, to being generic for the stream.
      *
-     * The page of data at the end of 'page' may be a read-only mapping of a
-     * running guest; it must not be modified.  If no transformation is
-     * required, the callee should leave '*pages' untouched.
+     * The page of data '*src' may be a read-only mapping of a running guest;
+     * it must not be modified. If no transformation is required, the callee
+     * should leave '*src' untouched, and return it via '**ptr'.
      *
-     * If a transformation is required, the callee should allocate themselves
-     * a local page using malloc() and return it via '*page'.
-     *
-     * The caller shall free() '*page' in all cases.  In the case that the
-     * callee encounters an error, it should *NOT* free() the memory it
-     * allocated for '*page'.
+     * If a transformation is required, the callee should provide the
+     * transformed page in a private buffer and return it via '**ptr'.
      *
      * It is valid to fail with EAGAIN if the transformation is not able to be
      * completed at this point.  The page shall be retried later.
@@ -50,7 +46,7 @@ struct xc_sr_save_ops
      * @returns 0 for success, -1 for failure, with errno appropriately set.
      */
     int (*normalise_page)(struct xc_sr_context *ctx, xen_pfn_t type,
-                          void **page);
+                          void *src, unsigned int idx, void **ptr);
 
     /**
      * Set up local environment to save a domain. (Typically querying
@@ -371,6 +367,12 @@ struct xc_sr_context
 
                 union
                 {
+                    struct
+                    {
+                        /* Used by write_batch for modified pages. */
+                        void *normalised_pages;
+                    } save;
+
                     struct
                     {
                         /* State machine for the order of received records. */
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index a571246894..e724ba9cb8 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -91,11 +91,10 @@ static int write_batch(struct xc_sr_context *ctx)
     xen_pfn_t *mfns = ctx->save.m->mfns, *types = ctx->save.m->types;
     void *guest_mapping = NULL;
     void **guest_data = ctx->save.m->guest_data;
-    void **local_pages = NULL;
     int *errors = ctx->save.m->errors, rc = -1;
     unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0;
     unsigned int nr_pfns = ctx->save.nr_batch_pfns;
-    void *page, *orig_page;
+    void *src;
     uint64_t *rec_pfns = ctx->save.m->rec_pfns;
     struct iovec *iov = ctx->save.m->iov; int iovcnt = 0;
     struct xc_sr_rec_page_data_header hdr = { 0 };
@@ -105,16 +104,6 @@ static int write_batch(struct xc_sr_context *ctx)
 
     assert(nr_pfns != 0);
 
-    /* Pointers to locally allocated pages.  Need freeing. */
-    local_pages = calloc(nr_pfns, sizeof(*local_pages));
-
-    if ( !local_pages )
-    {
-        ERROR("Unable to allocate arrays for a batch of %u pages",
-              nr_pfns);
-        goto err;
-    }
-
     for ( i = 0; i < nr_pfns; ++i )
     {
         types[i] = mfns[i] = ctx->save.ops.pfn_to_gfn(ctx,
@@ -176,11 +165,8 @@ static int write_batch(struct xc_sr_context *ctx)
                 goto err;
             }
 
-            orig_page = page = guest_mapping + (p * PAGE_SIZE);
-            rc = ctx->save.ops.normalise_page(ctx, types[i], &page);
-
-            if ( orig_page != page )
-                local_pages[i] = page;
+            src = guest_mapping + (p * PAGE_SIZE);
+            rc = ctx->save.ops.normalise_page(ctx, types[i], src, i, &guest_data[i]);
 
             if ( rc )
             {
@@ -195,8 +181,6 @@ static int write_batch(struct xc_sr_context *ctx)
                 else
                     goto err;
             }
-            else
-                guest_data[i] = page;
 
             rc = -1;
             ++p;
@@ -255,9 +239,6 @@ static int write_batch(struct xc_sr_context *ctx)
  err:
     if ( guest_mapping )
         xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped);
-    for ( i = 0; local_pages && i < nr_pfns; ++i )
-        free(local_pages[i]);
-    free(local_pages);
 
     return rc;
 }
diff --git a/tools/libs/guest/xg_sr_save_x86_hvm.c b/tools/libs/guest/xg_sr_save_x86_hvm.c
index 1634a7bc43..11232b9f1d 100644
--- a/tools/libs/guest/xg_sr_save_x86_hvm.c
+++ b/tools/libs/guest/xg_sr_save_x86_hvm.c
@@ -129,9 +129,10 @@ static xen_pfn_t x86_hvm_pfn_to_gfn(const struct xc_sr_context *ctx,
     return pfn;
 }
 
-static int x86_hvm_normalise_page(struct xc_sr_context *ctx,
-                                  xen_pfn_t type, void **page)
+static int x86_hvm_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type,
+                                  void *src, unsigned int idx, void **ptr)
 {
+    *ptr = src;
     return 0;
 }
 
diff --git a/tools/libs/guest/xg_sr_save_x86_pv.c b/tools/libs/guest/xg_sr_save_x86_pv.c
index 4964f1f7b8..8165306354 100644
--- a/tools/libs/guest/xg_sr_save_x86_pv.c
+++ b/tools/libs/guest/xg_sr_save_x86_pv.c
@@ -999,29 +999,31 @@ static xen_pfn_t x86_pv_pfn_to_gfn(const struct xc_sr_context *ctx,
  * save_ops function.  Performs pagetable normalisation on appropriate pages.
  */
 static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type,
-                                 void **page)
+                                  void *src, unsigned int idx, void **ptr)
 {
     xc_interface *xch = ctx->xch;
-    void *local_page;
     int rc;
+    void *dst;
 
     type &= XEN_DOMCTL_PFINFO_LTABTYPE_MASK;
 
     if ( type < XEN_DOMCTL_PFINFO_L1TAB || type > XEN_DOMCTL_PFINFO_L4TAB )
+    {
+        *ptr = src;
         return 0;
+    }
 
-    local_page = malloc(PAGE_SIZE);
-    if ( !local_page )
+    if ( idx >= MAX_BATCH_SIZE )
     {
-        ERROR("Unable to allocate scratch page");
-        rc = -1;
-        goto out;
+        ERROR("idx %u out of range", idx);
+        errno = ERANGE;
+        return -1;
     }
 
-    rc = normalise_pagetable(ctx, *page, local_page, type);
-    *page = local_page;
+    dst = ctx->x86.pv.save.normalised_pages + idx * PAGE_SIZE;
+    rc = normalise_pagetable(ctx, src, dst, type);
+    *ptr = dst;
 
- out:
     return rc;
 }
 
@@ -1031,8 +1033,16 @@ static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type,
  */
 static int x86_pv_setup(struct xc_sr_context *ctx)
 {
+    xc_interface *xch = ctx->xch;
     int rc;
 
+    ctx->x86.pv.save.normalised_pages = malloc(MAX_BATCH_SIZE * PAGE_SIZE);
+    if ( !ctx->x86.pv.save.normalised_pages )
+    {
+        PERROR("Failed to allocate normalised_pages");
+        return -1;
+    }
+
     rc = x86_pv_domain_info(ctx);
     if ( rc )
         return rc;
@@ -1118,6 +1128,7 @@ static int x86_pv_check_vm_state(struct xc_sr_context *ctx)
 
 static int x86_pv_cleanup(struct xc_sr_context *ctx)
 {
+    free(ctx->x86.pv.save.normalised_pages);
     free(ctx->x86.pv.p2m_pfns);
 
     if ( ctx->x86.pv.p2m )


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 23/39] tools/guest: restore: move pfns array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (21 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 22/39] tools/guest: save: move local_pages array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 24/39] tools/guest: restore: move types array Olaf Hering
                   ` (15 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move pfns array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  | 2 ++
 tools/libs/guest/xg_sr_restore.c | 6 ++----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 2a020fef5c..516d9b9fb5 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -224,6 +224,8 @@ struct xc_sr_save_arrays {
 };
 
 struct xc_sr_restore_arrays {
+    /* handle_page_data */
+    xen_pfn_t pfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_context
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 4a9ece9681..7d1447e86c 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -315,7 +315,7 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     unsigned int i, pages_of_data = 0;
     int rc = -1;
 
-    xen_pfn_t *pfns = NULL, pfn;
+    xen_pfn_t *pfns = ctx->restore.m->pfns, pfn;
     uint32_t *types = NULL, type;
 
     /*
@@ -363,9 +363,8 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         goto err;
     }
 
-    pfns = malloc(pages->count * sizeof(*pfns));
     types = malloc(pages->count * sizeof(*types));
-    if ( !pfns || !types )
+    if ( !types )
     {
         ERROR("Unable to allocate enough memory for %u pfns",
               pages->count);
@@ -412,7 +411,6 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
                            &pages->pfn[pages->count]);
  err:
     free(types);
-    free(pfns);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 24/39] tools/guest: restore: move types array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (22 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 23/39] tools/guest: restore: move pfns array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 25/39] tools/guest: restore: move mfns array Olaf Hering
                   ` (14 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move types array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  |  1 +
 tools/libs/guest/xg_sr_restore.c | 12 +-----------
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 516d9b9fb5..0ceecb289d 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -226,6 +226,7 @@ struct xc_sr_save_arrays {
 struct xc_sr_restore_arrays {
     /* handle_page_data */
     xen_pfn_t pfns[MAX_BATCH_SIZE];
+    uint32_t types[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_context
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 7d1447e86c..7729071e41 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -316,7 +316,7 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     int rc = -1;
 
     xen_pfn_t *pfns = ctx->restore.m->pfns, pfn;
-    uint32_t *types = NULL, type;
+    uint32_t *types = ctx->restore.m->types, type;
 
     /*
      * v2 compatibility only exists for x86 streams.  This is a bit of a
@@ -363,14 +363,6 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         goto err;
     }
 
-    types = malloc(pages->count * sizeof(*types));
-    if ( !types )
-    {
-        ERROR("Unable to allocate enough memory for %u pfns",
-              pages->count);
-        goto err;
-    }
-
     for ( i = 0; i < pages->count; ++i )
     {
         pfn = pages->pfn[i] & PAGE_DATA_PFN_MASK;
@@ -410,8 +402,6 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     rc = process_page_data(ctx, pages->count, pfns, types,
                            &pages->pfn[pages->count]);
  err:
-    free(types);
-
     return rc;
 }
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 25/39] tools/guest: restore: move mfns array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (23 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 24/39] tools/guest: restore: move types array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 26/39] tools/guest: restore: move map_errs array Olaf Hering
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move mfns array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  | 2 ++
 tools/libs/guest/xg_sr_restore.c | 5 ++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 0ceecb289d..5731a5c186 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -227,6 +227,8 @@ struct xc_sr_restore_arrays {
     /* handle_page_data */
     xen_pfn_t pfns[MAX_BATCH_SIZE];
     uint32_t types[MAX_BATCH_SIZE];
+    /* process_page_data */
+    xen_pfn_t mfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_context
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 7729071e41..3ba089f862 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -205,7 +205,7 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
                              xen_pfn_t *pfns, uint32_t *types, void *page_data)
 {
     xc_interface *xch = ctx->xch;
-    xen_pfn_t *mfns = malloc(count * sizeof(*mfns));
+    xen_pfn_t *mfns = ctx->restore.m->mfns;
     int *map_errs = malloc(count * sizeof(*map_errs));
     int rc;
     void *mapping = NULL, *guest_page = NULL;
@@ -213,7 +213,7 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
         j,          /* j indexes the subset of pfns we decide to map. */
         nr_pages = 0;
 
-    if ( !mfns || !map_errs )
+    if ( !map_errs )
     {
         rc = -1;
         ERROR("Failed to allocate %zu bytes to process page data",
@@ -299,7 +299,6 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
         xenforeignmemory_unmap(xch->fmem, mapping, nr_pages);
 
     free(map_errs);
-    free(mfns);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 26/39] tools/guest: restore: move map_errs array
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (24 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 25/39] tools/guest: restore: move mfns array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 27/39] tools/guest: restore: move mfns array in populate_pfns Olaf Hering
                   ` (12 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move map_errs array into preallocated space.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  |  1 +
 tools/libs/guest/xg_sr_restore.c | 12 +-----------
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 5731a5c186..eba3a49877 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -229,6 +229,7 @@ struct xc_sr_restore_arrays {
     uint32_t types[MAX_BATCH_SIZE];
     /* process_page_data */
     xen_pfn_t mfns[MAX_BATCH_SIZE];
+    int map_errs[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_context
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 3ba089f862..94c329032f 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -206,21 +206,13 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
 {
     xc_interface *xch = ctx->xch;
     xen_pfn_t *mfns = ctx->restore.m->mfns;
-    int *map_errs = malloc(count * sizeof(*map_errs));
+    int *map_errs = ctx->restore.m->map_errs;
     int rc;
     void *mapping = NULL, *guest_page = NULL;
     unsigned int i, /* i indexes the pfns from the record. */
         j,          /* j indexes the subset of pfns we decide to map. */
         nr_pages = 0;
 
-    if ( !map_errs )
-    {
-        rc = -1;
-        ERROR("Failed to allocate %zu bytes to process page data",
-              count * (sizeof(*mfns) + sizeof(*map_errs)));
-        goto err;
-    }
-
     rc = populate_pfns(ctx, count, pfns, types);
     if ( rc )
     {
@@ -298,8 +290,6 @@ static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
     if ( mapping )
         xenforeignmemory_unmap(xch->fmem, mapping, nr_pages);
 
-    free(map_errs);
-
     return rc;
 }
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 27/39] tools/guest: restore: move mfns array in populate_pfns
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (25 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 26/39] tools/guest: restore: move map_errs array Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 28/39] tools/guest: restore: move pfns " Olaf Hering
                   ` (11 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move populate_pfns mfns array into preallocated space.
Use some prefix to avoid conflict with an array used in handle_page_data.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  | 2 ++
 tools/libs/guest/xg_sr_restore.c | 5 ++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index eba3a49877..96a77b5969 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -230,6 +230,8 @@ struct xc_sr_restore_arrays {
     /* process_page_data */
     xen_pfn_t mfns[MAX_BATCH_SIZE];
     int map_errs[MAX_BATCH_SIZE];
+    /* populate_pfns */
+    xen_pfn_t pp_mfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_context
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 94c329032f..85a32aaed2 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -138,12 +138,12 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
                   const xen_pfn_t *original_pfns, const uint32_t *types)
 {
     xc_interface *xch = ctx->xch;
-    xen_pfn_t *mfns = malloc(count * sizeof(*mfns)),
+    xen_pfn_t *mfns = ctx->restore.m->pp_mfns,
         *pfns = malloc(count * sizeof(*pfns));
     unsigned int i, nr_pfns = 0;
     int rc = -1;
 
-    if ( !mfns || !pfns )
+    if ( !pfns )
     {
         ERROR("Failed to allocate %zu bytes for populating the physmap",
               2 * count * sizeof(*mfns));
@@ -191,7 +191,6 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
 
  err:
     free(pfns);
-    free(mfns);
 
     return rc;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 28/39] tools/guest: restore: move pfns array in populate_pfns
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (26 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 27/39] tools/guest: restore: move mfns array in populate_pfns Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 29/39] tools/guest: restore: split record processing Olaf Hering
                   ` (10 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Remove allocation from hotpath, move populate_pfns' pfns array into preallocated space.
Use some prefix to avoid conflict with an array used in handle_page_data.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  |  1 +
 tools/libs/guest/xg_sr_restore.c | 11 +----------
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 96a77b5969..3fe665b91d 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -232,6 +232,7 @@ struct xc_sr_restore_arrays {
     int map_errs[MAX_BATCH_SIZE];
     /* populate_pfns */
     xen_pfn_t pp_mfns[MAX_BATCH_SIZE];
+    xen_pfn_t pp_pfns[MAX_BATCH_SIZE];
 };
 
 struct xc_sr_context
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 85a32aaed2..71b39612ee 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -139,17 +139,10 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
 {
     xc_interface *xch = ctx->xch;
     xen_pfn_t *mfns = ctx->restore.m->pp_mfns,
-        *pfns = malloc(count * sizeof(*pfns));
+        *pfns = ctx->restore.m->pp_pfns;
     unsigned int i, nr_pfns = 0;
     int rc = -1;
 
-    if ( !pfns )
-    {
-        ERROR("Failed to allocate %zu bytes for populating the physmap",
-              2 * count * sizeof(*mfns));
-        goto err;
-    }
-
     for ( i = 0; i < count; ++i )
     {
         if ( (!types ||
@@ -190,8 +183,6 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
     rc = 0;
 
  err:
-    free(pfns);
-
     return rc;
 }
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 29/39] tools/guest: restore: split record processing
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (27 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 28/39] tools/guest: restore: move pfns " Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 30/39] tools/guest: restore: split handle_page_data Olaf Hering
                   ` (9 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

handle_page_data must be able to read directly into mapped guest memory.
This will avoid unneccesary memcpy calls for data which can be consumed verbatim.

Rearrange the code to allow decisions based on the incoming record.

This change is preparation for future changes in handle_page_data,
no change in behavior is intended.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.c  | 33 ++++++++++++---------
 tools/libs/guest/xg_sr_common.h  |  4 ++-
 tools/libs/guest/xg_sr_restore.c | 49 ++++++++++++++++++++++----------
 tools/libs/guest/xg_sr_save.c    |  7 ++++-
 4 files changed, 63 insertions(+), 30 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_common.c
index 17567ab133..cabde4ef74 100644
--- a/tools/libs/guest/xg_sr_common.c
+++ b/tools/libs/guest/xg_sr_common.c
@@ -91,26 +91,33 @@ int write_split_record(struct xc_sr_context *ctx, struct xc_sr_record *rec,
     return -1;
 }
 
-int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
+int read_record_header(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rhdr rhdr;
-    size_t datasz;
 
-    if ( read_exact(fd, &rhdr, sizeof(rhdr)) )
+    if ( read_exact(fd, rhdr, sizeof(*rhdr)) )
     {
         PERROR("Failed to read Record Header from stream");
         return -1;
     }
 
-    if ( rhdr.length > REC_LENGTH_MAX )
+    if ( rhdr->length > REC_LENGTH_MAX )
     {
-        ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr.type,
-              rec_type_to_str(rhdr.type), rhdr.length, REC_LENGTH_MAX);
+        ERROR("Record (0x%08x, %s) length %#x exceeds max (%#x)", rhdr->type,
+              rec_type_to_str(rhdr->type), rhdr->length, REC_LENGTH_MAX);
         return -1;
     }
 
-    datasz = ROUNDUP(rhdr.length, REC_ALIGN_ORDER);
+    return 0;
+}
+
+int read_record_data(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr,
+                     struct xc_sr_record *rec)
+{
+    xc_interface *xch = ctx->xch;
+    size_t datasz;
+
+    datasz = ROUNDUP(rhdr->length, REC_ALIGN_ORDER);
 
     if ( datasz )
     {
@@ -119,7 +126,7 @@ int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
         if ( !rec->data )
         {
             ERROR("Unable to allocate %zu bytes for record data (0x%08x, %s)",
-                  datasz, rhdr.type, rec_type_to_str(rhdr.type));
+                  datasz, rhdr->type, rec_type_to_str(rhdr->type));
             return -1;
         }
 
@@ -128,18 +135,18 @@ int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec)
             free(rec->data);
             rec->data = NULL;
             PERROR("Failed to read %zu bytes of data for record (0x%08x, %s)",
-                   datasz, rhdr.type, rec_type_to_str(rhdr.type));
+                   datasz, rhdr->type, rec_type_to_str(rhdr->type));
             return -1;
         }
     }
     else
         rec->data = NULL;
 
-    rec->type   = rhdr.type;
-    rec->length = rhdr.length;
+    rec->type   = rhdr->type;
+    rec->length = rhdr->length;
 
     return 0;
-};
+}
 
 static void __attribute__((unused)) build_assertions(void)
 {
diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 3fe665b91d..66d1b0dfe6 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -475,7 +475,9 @@ static inline int write_record(struct xc_sr_context *ctx,
  *
  * On failure, the contents of the record structure are undefined.
  */
-int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec);
+int read_record_header(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr);
+int read_record_data(struct xc_sr_context *ctx, int fd, struct xc_sr_rhdr *rhdr,
+                     struct xc_sr_record *rec);
 
 /*
  * This would ideally be private in restore.c, but is needed by
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 71b39612ee..93f69b9ba8 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -471,7 +471,7 @@ static int send_checkpoint_dirty_pfn_list(struct xc_sr_context *ctx)
     return rc;
 }
 
-static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
+static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
 static int handle_checkpoint(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
@@ -510,7 +510,7 @@ static int handle_checkpoint(struct xc_sr_context *ctx)
 
         for ( i = 0; i < ctx->restore.buffered_rec_num; i++ )
         {
-            rc = process_record(ctx, &ctx->restore.buffered_records[i]);
+            rc = process_buffered_record(ctx, &ctx->restore.buffered_records[i]);
             if ( rc )
                 goto err;
         }
@@ -571,10 +571,11 @@ static int handle_checkpoint(struct xc_sr_context *ctx)
     return rc;
 }
 
-static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
+static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_rhdr *rhdr)
 {
     xc_interface *xch = ctx->xch;
     unsigned int new_alloc_num;
+    struct xc_sr_record rec;
     struct xc_sr_record *p;
 
     if ( ctx->restore.buffered_rec_num >= ctx->restore.allocated_rec_num )
@@ -592,8 +593,13 @@ static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         ctx->restore.allocated_rec_num = new_alloc_num;
     }
 
+    if ( read_record_data(ctx, ctx->fd, rhdr, &rec) )
+    {
+        return -1;
+    }
+
     memcpy(&ctx->restore.buffered_records[ctx->restore.buffered_rec_num++],
-           rec, sizeof(*rec));
+           &rec, sizeof(rec));
 
     return 0;
 }
@@ -624,7 +630,7 @@ int handle_static_data_end(struct xc_sr_context *ctx)
     return rc;
 }
 
-static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
+static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
     int rc = 0;
@@ -662,6 +668,19 @@ static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     return rc;
 }
 
+static int process_incoming_record_header(struct xc_sr_context *ctx, struct xc_sr_rhdr *rhdr)
+{
+    struct xc_sr_record rec;
+    int rc;
+
+    rc = read_record_data(ctx, ctx->fd, rhdr, &rec);
+    if ( rc )
+        return rc;
+
+    return process_buffered_record(ctx, &rec);
+}
+
+
 static int setup(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
@@ -745,7 +764,7 @@ static void cleanup(struct xc_sr_context *ctx)
 static int restore(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
-    struct xc_sr_record rec;
+    struct xc_sr_rhdr rhdr;
     int rc, saved_rc = 0, saved_errno = 0;
 
     IPRINTF("Restoring domain");
@@ -756,7 +775,7 @@ static int restore(struct xc_sr_context *ctx)
 
     do
     {
-        rc = read_record(ctx, ctx->fd, &rec);
+        rc = read_record_header(ctx, ctx->fd, &rhdr);
         if ( rc )
         {
             if ( ctx->restore.buffer_all_records )
@@ -766,25 +785,25 @@ static int restore(struct xc_sr_context *ctx)
         }
 
         if ( ctx->restore.buffer_all_records &&
-             rec.type != REC_TYPE_END &&
-             rec.type != REC_TYPE_CHECKPOINT )
+             rhdr.type != REC_TYPE_END &&
+             rhdr.type != REC_TYPE_CHECKPOINT )
         {
-            rc = buffer_record(ctx, &rec);
+            rc = buffer_record(ctx, &rhdr);
             if ( rc )
                 goto err;
         }
         else
         {
-            rc = process_record(ctx, &rec);
+            rc = process_incoming_record_header(ctx, &rhdr);
             if ( rc == RECORD_NOT_PROCESSED )
             {
-                if ( rec.type & REC_TYPE_OPTIONAL )
+                if ( rhdr.type & REC_TYPE_OPTIONAL )
                     DPRINTF("Ignoring optional record %#x (%s)",
-                            rec.type, rec_type_to_str(rec.type));
+                            rhdr.type, rec_type_to_str(rhdr.type));
                 else
                 {
                     ERROR("Mandatory record %#x (%s) not handled",
-                          rec.type, rec_type_to_str(rec.type));
+                          rhdr.type, rec_type_to_str(rhdr.type));
                     rc = -1;
                     goto err;
                 }
@@ -795,7 +814,7 @@ static int restore(struct xc_sr_context *ctx)
                 goto err;
         }
 
-    } while ( rec.type != REC_TYPE_END );
+    } while ( rhdr.type != REC_TYPE_END );
 
  remus_failover:
     if ( ctx->stream_type == XC_STREAM_COLO )
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index e724ba9cb8..d766384ed6 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -590,6 +590,7 @@ static int send_memory_live(struct xc_sr_context *ctx)
 static int colo_merge_secondary_dirty_bitmap(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
+    struct xc_sr_rhdr rhdr;
     struct xc_sr_record rec;
     uint64_t *pfns = NULL;
     uint64_t pfn;
@@ -598,7 +599,11 @@ static int colo_merge_secondary_dirty_bitmap(struct xc_sr_context *ctx)
     DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
                                     &ctx->save.dirty_bitmap_hbuf);
 
-    rc = read_record(ctx, ctx->save.recv_fd, &rec);
+    rc = read_record_header(ctx, ctx->save.recv_fd, &rhdr);
+    if ( rc )
+        goto err;
+
+    rc = read_record_data(ctx, ctx->save.recv_fd, &rhdr, &rec);
     if ( rc )
         goto err;
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 30/39] tools/guest: restore: split handle_page_data
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (28 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 29/39] tools/guest: restore: split record processing Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 31/39] tools/guest: restore: write data directly into guest Olaf Hering
                   ` (8 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

handle_page_data must be able to read directly into mapped guest memory.
This will avoid unneccesary memcpy calls for data that can be consumed verbatim.

Split the various steps of record processing:
- move processing to handle_buffered_page_data
- adjust xenforeignmemory_map to set errno in case of failure
- adjust verify mode to set errno in case of failure

This change is preparation for future changes in handle_page_data,
no change in behavior is intended.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  |   9 +
 tools/libs/guest/xg_sr_restore.c | 343 ++++++++++++++++++++-----------
 2 files changed, 231 insertions(+), 121 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 66d1b0dfe6..7ec8867b88 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -230,9 +230,14 @@ struct xc_sr_restore_arrays {
     /* process_page_data */
     xen_pfn_t mfns[MAX_BATCH_SIZE];
     int map_errs[MAX_BATCH_SIZE];
+    void *guest_data[MAX_BATCH_SIZE];
+
     /* populate_pfns */
     xen_pfn_t pp_mfns[MAX_BATCH_SIZE];
     xen_pfn_t pp_pfns[MAX_BATCH_SIZE];
+
+    /* Must be the last member */
+    struct xc_sr_rec_page_data_header pages;
 };
 
 struct xc_sr_context
@@ -323,7 +328,11 @@ struct xc_sr_context
 
             /* Sender has invoked verify mode on the stream. */
             bool verify;
+            void *verify_buf;
+
             struct xc_sr_restore_arrays *m;
+            void *guest_mapping;
+            uint32_t nr_mapped_pages;
         } restore;
     };
 
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 93f69b9ba8..060f3d1f4e 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -186,123 +186,18 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned int count,
     return rc;
 }
 
-/*
- * Given a list of pfns, their types, and a block of page data from the
- * stream, populate and record their types, map the relevant subset and copy
- * the data into the guest.
- */
-static int process_page_data(struct xc_sr_context *ctx, unsigned int count,
-                             xen_pfn_t *pfns, uint32_t *types, void *page_data)
+static int handle_static_data_end_v2(struct xc_sr_context *ctx)
 {
-    xc_interface *xch = ctx->xch;
-    xen_pfn_t *mfns = ctx->restore.m->mfns;
-    int *map_errs = ctx->restore.m->map_errs;
-    int rc;
-    void *mapping = NULL, *guest_page = NULL;
-    unsigned int i, /* i indexes the pfns from the record. */
-        j,          /* j indexes the subset of pfns we decide to map. */
-        nr_pages = 0;
-
-    rc = populate_pfns(ctx, count, pfns, types);
-    if ( rc )
-    {
-        ERROR("Failed to populate pfns for batch of %u pages", count);
-        goto err;
-    }
-
-    for ( i = 0; i < count; ++i )
-    {
-        ctx->restore.ops.set_page_type(ctx, pfns[i], types[i]);
-
-        if ( page_type_has_stream_data(types[i]) == true )
-            mfns[nr_pages++] = ctx->restore.ops.pfn_to_gfn(ctx, pfns[i]);
-    }
-
-    /* Nothing to do? */
-    if ( nr_pages == 0 )
-        goto done;
-
-    mapping = guest_page = xenforeignmemory_map(
-        xch->fmem, ctx->domid, PROT_READ | PROT_WRITE,
-        nr_pages, mfns, map_errs);
-    if ( !mapping )
-    {
-        rc = -1;
-        PERROR("Unable to map %u mfns for %u pages of data",
-               nr_pages, count);
-        goto err;
-    }
-
-    for ( i = 0, j = 0; i < count; ++i )
-    {
-        if ( page_type_has_stream_data(types[i]) == false )
-            continue;
-
-        if ( map_errs[j] )
-        {
-            rc = -1;
-            ERROR("Mapping pfn %#"PRIpfn" (mfn %#"PRIpfn", type %#"PRIx32") failed with %d",
-                  pfns[i], mfns[j], types[i], map_errs[j]);
-            goto err;
-        }
-
-        /* Undo page normalisation done by the saver. */
-        rc = ctx->restore.ops.localise_page(ctx, types[i], page_data);
-        if ( rc )
-        {
-            ERROR("Failed to localise pfn %#"PRIpfn" (type %#"PRIx32")",
-                  pfns[i], types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
-            goto err;
-        }
-
-        if ( ctx->restore.verify )
-        {
-            /* Verify mode - compare incoming data to what we already have. */
-            if ( memcmp(guest_page, page_data, PAGE_SIZE) )
-                ERROR("verify pfn %#"PRIpfn" failed (type %#"PRIx32")",
-                      pfns[i], types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
-        }
-        else
-        {
-            /* Regular mode - copy incoming data into place. */
-            memcpy(guest_page, page_data, PAGE_SIZE);
-        }
-
-        ++j;
-        guest_page += PAGE_SIZE;
-        page_data += PAGE_SIZE;
-    }
-
- done:
-    rc = 0;
-
- err:
-    if ( mapping )
-        xenforeignmemory_unmap(xch->fmem, mapping, nr_pages);
-
-    return rc;
-}
+    int rc = 0;
 
-/*
- * Validate a PAGE_DATA record from the stream, and pass the results to
- * process_page_data() to actually perform the legwork.
- */
-static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
-{
+#if defined(__i386__) || defined(__x86_64__)
     xc_interface *xch = ctx->xch;
-    struct xc_sr_rec_page_data_header *pages = rec->data;
-    unsigned int i, pages_of_data = 0;
-    int rc = -1;
-
-    xen_pfn_t *pfns = ctx->restore.m->pfns, pfn;
-    uint32_t *types = ctx->restore.m->types, type;
-
     /*
      * v2 compatibility only exists for x86 streams.  This is a bit of a
      * bodge, but it is less bad than duplicating handle_page_data() between
      * different architectures.
      */
-#if defined(__i386__) || defined(__x86_64__)
+
     /* v2 compat.  Infer the position of STATIC_DATA_END. */
     if ( ctx->restore.format_version < 3 && !ctx->restore.seen_static_data_end )
     {
@@ -320,12 +215,26 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         ERROR("No STATIC_DATA_END seen");
         goto err;
     }
+
+    rc = 0;
+err:
 #endif
 
-    if ( rec->length < sizeof(*pages) )
+    return rc;
+}
+
+static bool verify_rec_page_hdr(struct xc_sr_context *ctx, uint32_t rec_length,
+                                 struct xc_sr_rec_page_data_header *pages)
+{
+    xc_interface *xch = ctx->xch;
+    bool ret = false;
+
+    errno = EINVAL;
+
+    if ( rec_length < sizeof(*pages) )
     {
         ERROR("PAGE_DATA record truncated: length %u, min %zu",
-              rec->length, sizeof(*pages));
+              rec_length, sizeof(*pages));
         goto err;
     }
 
@@ -335,13 +244,35 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         goto err;
     }
 
-    if ( rec->length < sizeof(*pages) + (pages->count * sizeof(uint64_t)) )
+    if ( pages->count > MAX_BATCH_SIZE )
+    {
+        ERROR("pfn count %u in PAGE_DATA record too large", pages->count);
+        errno = E2BIG;
+        goto err;
+    }
+
+    if ( rec_length < sizeof(*pages) + (pages->count * sizeof(uint64_t)) )
     {
         ERROR("PAGE_DATA record (length %u) too short to contain %u"
-              " pfns worth of information", rec->length, pages->count);
+              " pfns worth of information", rec_length, pages->count);
         goto err;
     }
 
+    ret = true;
+
+err:
+    return ret;
+}
+
+static bool verify_rec_page_pfns(struct xc_sr_context *ctx, uint32_t rec_length,
+                                 struct xc_sr_rec_page_data_header *pages)
+{
+    xc_interface *xch = ctx->xch;
+    uint32_t i, pages_of_data = 0;
+    xen_pfn_t pfn;
+    uint32_t type;
+    bool ret = false;
+
     for ( i = 0; i < pages->count; ++i )
     {
         pfn = pages->pfn[i] & PAGE_DATA_PFN_MASK;
@@ -364,23 +295,183 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
              * have a page worth of data in the record. */
             pages_of_data++;
 
-        pfns[i] = pfn;
-        types[i] = type;
+        ctx->restore.m->pfns[i] = pfn;
+        ctx->restore.m->types[i] = type;
     }
 
-    if ( rec->length != (sizeof(*pages) +
+    if ( rec_length != (sizeof(*pages) +
                          (sizeof(uint64_t) * pages->count) +
                          (PAGE_SIZE * pages_of_data)) )
     {
         ERROR("PAGE_DATA record wrong size: length %u, expected "
-              "%zu + %zu + %lu", rec->length, sizeof(*pages),
+              "%zu + %zu + %lu", rec_length, sizeof(*pages),
               (sizeof(uint64_t) * pages->count), (PAGE_SIZE * pages_of_data));
         goto err;
     }
 
-    rc = process_page_data(ctx, pages->count, pfns, types,
-                           &pages->pfn[pages->count]);
+    ret = true;
+
+err:
+    return ret;
+}
+
+/*
+ * Populate pfns, if required
+ * Fill m->guest_data with either mapped address or NULL
+ * The caller must unmap guest_mapping
+ */
+static int map_guest_pages(struct xc_sr_context *ctx,
+                           struct xc_sr_rec_page_data_header *pages)
+{
+    xc_interface *xch = ctx->xch;
+    struct xc_sr_restore_arrays *m = ctx->restore.m;
+    uint32_t i, p;
+    int rc;
+
+    rc = populate_pfns(ctx, pages->count, m->pfns, m->types);
+    if ( rc )
+    {
+        ERROR("Failed to populate pfns for batch of %u pages", pages->count);
+        goto err;
+    }
+
+    ctx->restore.nr_mapped_pages = 0;
+
+    for ( i = 0; i < pages->count; i++ )
+    {
+        ctx->restore.ops.set_page_type(ctx, m->pfns[i], m->types[i]);
+
+        if ( page_type_has_stream_data(m->types[i]) == false )
+        {
+            m->guest_data[i] = NULL;
+            continue;
+        }
+
+        m->mfns[ctx->restore.nr_mapped_pages++] = ctx->restore.ops.pfn_to_gfn(ctx, m->pfns[i]);
+    }
+
+    /* Nothing to do? */
+    if ( ctx->restore.nr_mapped_pages == 0 )
+        goto done;
+
+    ctx->restore.guest_mapping = xenforeignmemory_map(xch->fmem, ctx->domid,
+            PROT_READ | PROT_WRITE, ctx->restore.nr_mapped_pages,
+            m->mfns, m->map_errs);
+    if ( !ctx->restore.guest_mapping )
+    {
+        rc = -1;
+        PERROR("Unable to map %u mfns for %u pages of data",
+               ctx->restore.nr_mapped_pages, pages->count);
+        goto err;
+    }
+
+    /* Verify mapping, and assign address to pfn data */
+    for ( i = 0, p = 0; i < pages->count; i++ )
+    {
+        if ( page_type_has_stream_data(m->types[i]) == false )
+            continue;
+
+        if ( m->map_errs[p] == 0 )
+        {
+            m->guest_data[i] = ctx->restore.guest_mapping + (p * PAGE_SIZE);
+            p++;
+            continue;
+        }
+
+        errno = m->map_errs[p];
+        rc = -1;
+        PERROR("Mapping pfn %#"PRIpfn" (mfn %#"PRIpfn", type %#"PRIx32") failed",
+              m->pfns[i], m->mfns[p], m->types[i]);
+        goto err;
+    }
+
+done:
+    rc = 0;
+
+err:
+    return rc;
+}
+
+/*
+ * Handle PAGE_DATA record from an existing buffer
+ * Given a list of pfns, their types, and a block of page data from the
+ * stream, populate and record their types, map the relevant subset and copy
+ * the data into the guest.
+ */
+static int handle_buffered_page_data(struct xc_sr_context *ctx,
+                                     struct xc_sr_record *rec)
+{
+    xc_interface *xch = ctx->xch;
+    struct xc_sr_rec_page_data_header *pages = rec->data;
+    struct xc_sr_restore_arrays *m = ctx->restore.m;
+    void *p;
+    uint32_t i;
+    int rc = -1, idx;
+
+    rc = handle_static_data_end_v2(ctx);
+    if ( rc )
+        goto err;
+
+    /* First read and verify the header */
+    if ( verify_rec_page_hdr(ctx, rec->length, pages) == false )
+    {
+        rc = -1;
+        goto err;
+    }
+
+    /* Then read and verify the pfn numbers */
+    if ( verify_rec_page_pfns(ctx, rec->length, pages) == false )
+    {
+        rc = -1;
+        goto err;
+    }
+
+    /* Map the target pfn */
+    rc = map_guest_pages(ctx, pages);
+    if ( rc )
+        goto err;
+
+    for ( i = 0, idx = 0; i < pages->count; i++ )
+    {
+        if ( !m->guest_data[i] )
+            continue;
+
+        p = &pages->pfn[pages->count] + (idx * PAGE_SIZE);
+        rc = ctx->restore.ops.localise_page(ctx, m->types[i], p);
+        if ( rc )
+        {
+            ERROR("Failed to localise pfn %#"PRIpfn" (type %#"PRIx32")",
+                  m->pfns[i], m->types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+            goto err;
+
+        }
+
+        if ( ctx->restore.verify )
+        {
+            if ( memcmp(m->guest_data[i], p, PAGE_SIZE) )
+            {
+                errno = EIO;
+                ERROR("verify pfn %#"PRIpfn" failed (type %#"PRIx32")",
+                      m->pfns[i], m->types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+                goto err;
+            }
+        }
+        else
+        {
+            memcpy(m->guest_data[i], p, PAGE_SIZE);
+        }
+
+        idx++;
+    }
+
+    rc = 0;
+
  err:
+    if ( ctx->restore.guest_mapping )
+    {
+        xenforeignmemory_unmap(xch->fmem, ctx->restore.guest_mapping, ctx->restore.nr_mapped_pages);
+        ctx->restore.guest_mapping = NULL;
+    }
     return rc;
 }
 
@@ -641,12 +732,21 @@ static int process_buffered_record(struct xc_sr_context *ctx, struct xc_sr_recor
         break;
 
     case REC_TYPE_PAGE_DATA:
-        rc = handle_page_data(ctx, rec);
+        rc = handle_buffered_page_data(ctx, rec);
         break;
 
     case REC_TYPE_VERIFY:
         DPRINTF("Verify mode enabled");
         ctx->restore.verify = true;
+        if ( !ctx->restore.verify_buf )
+        {
+            ctx->restore.verify_buf = malloc(MAX_BATCH_SIZE * PAGE_SIZE);
+            if ( !ctx->restore.verify_buf )
+            {
+                rc = -1;
+                PERROR("Unable to allocate verify_buf");
+            }
+        }
         break;
 
     case REC_TYPE_CHECKPOINT:
@@ -725,7 +825,8 @@ static int setup(struct xc_sr_context *ctx)
     }
     ctx->restore.allocated_rec_num = DEFAULT_BUF_RECORDS;
 
-    ctx->restore.m = malloc(sizeof(*ctx->restore.m));
+    ctx->restore.m = malloc(sizeof(*ctx->restore.m) +
+            (sizeof(*ctx->restore.m->pages.pfn) * MAX_BATCH_SIZE));
     if ( !ctx->restore.m ) {
         ERROR("Unable to allocate memory for arrays");
         rc = -1;


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 31/39] tools/guest: restore: write data directly into guest
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (29 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 30/39] tools/guest: restore: split handle_page_data Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl Olaf Hering
                   ` (7 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Read incoming migration stream directly into the guest memory.
This avoids the memory allocation and copying, and the resulting
performance penalty.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/guest/xg_sr_common.h  |   1 +
 tools/libs/guest/xg_sr_restore.c | 132 ++++++++++++++++++++++++++++++-
 2 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 7ec8867b88..f76af23bcc 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -231,6 +231,7 @@ struct xc_sr_restore_arrays {
     xen_pfn_t mfns[MAX_BATCH_SIZE];
     int map_errs[MAX_BATCH_SIZE];
     void *guest_data[MAX_BATCH_SIZE];
+    struct iovec iov[MAX_BATCH_SIZE];
 
     /* populate_pfns */
     xen_pfn_t pp_mfns[MAX_BATCH_SIZE];
diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_restore.c
index 060f3d1f4e..2f575d7dd9 100644
--- a/tools/libs/guest/xg_sr_restore.c
+++ b/tools/libs/guest/xg_sr_restore.c
@@ -392,6 +392,122 @@ err:
     return rc;
 }
 
+/*
+ * Handle PAGE_DATA record from the stream.
+ * Given a list of pfns, their types, and a block of page data from the
+ * stream, populate and record their types, map the relevant subset and copy
+ * the data into the guest.
+ */
+static int handle_incoming_page_data(struct xc_sr_context *ctx,
+                                     struct xc_sr_rhdr *rhdr)
+{
+    xc_interface *xch = ctx->xch;
+    struct xc_sr_restore_arrays *m = ctx->restore.m;
+    struct xc_sr_rec_page_data_header *pages = &m->pages;
+    uint64_t *pfn_nums = m->pages.pfn;
+    uint32_t i;
+    int rc, iov_idx;
+
+    rc = handle_static_data_end_v2(ctx);
+    if ( rc )
+        goto err;
+
+    /* First read and verify the header */
+    rc = read_exact(ctx->fd, pages, sizeof(*pages));
+    if ( rc )
+    {
+        PERROR("Could not read rec_pfn header");
+        goto err;
+    }
+
+    if ( verify_rec_page_hdr(ctx, rhdr->length, pages) == false )
+    {
+        rc = -1;
+        goto err;
+    }
+
+    /* Then read and verify the incoming pfn numbers */
+    rc = read_exact(ctx->fd, pfn_nums, sizeof(*pfn_nums) * pages->count);
+    if ( rc )
+    {
+        PERROR("Could not read rec_pfn data");
+        goto err;
+    }
+
+    if ( verify_rec_page_pfns(ctx, rhdr->length, pages) == false )
+    {
+        rc = -1;
+        goto err;
+    }
+
+    /* Finally read and verify the incoming pfn data */
+    rc = map_guest_pages(ctx, pages);
+    if ( rc )
+        goto err;
+
+    /* Prepare read buffers, either guest or throw away memory */
+    for ( i = 0, iov_idx = 0; i < pages->count; i++ )
+    {
+        if ( !m->guest_data[i] )
+            continue;
+
+        m->iov[iov_idx].iov_len = PAGE_SIZE;
+        if ( ctx->restore.verify )
+            m->iov[iov_idx].iov_base = ctx->restore.verify_buf + i * PAGE_SIZE;
+        else
+            m->iov[iov_idx].iov_base = m->guest_data[i];
+        iov_idx++;
+    }
+
+    if ( !iov_idx )
+        goto done;
+
+    rc = readv_exact(ctx->fd, m->iov, iov_idx);
+    if ( rc )
+    {
+        PERROR("read of %d pages failed", iov_idx);
+        goto err;
+    }
+
+    /* Post-processing of pfn data */
+    for ( i = 0, iov_idx = 0; i < pages->count; i++ )
+    {
+        if ( !m->guest_data[i] )
+            continue;
+
+        rc = ctx->restore.ops.localise_page(ctx, m->types[i], m->iov[iov_idx].iov_base);
+        if ( rc )
+        {
+            ERROR("Failed to localise pfn %#"PRIpfn" (type %#"PRIx32")",
+                  m->pfns[i], m->types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+            goto err;
+
+        }
+
+        if ( ctx->restore.verify )
+        {
+            if ( memcmp(m->guest_data[i], m->iov[iov_idx].iov_base, PAGE_SIZE) )
+            {
+                ERROR("verify pfn %#"PRIpfn" failed (type %#"PRIx32")",
+                      m->pfns[i], m->types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT);
+            }
+        }
+
+        iov_idx++;
+    }
+
+done:
+    rc = 0;
+
+err:
+    if ( ctx->restore.guest_mapping )
+    {
+        xenforeignmemory_unmap(xch->fmem, ctx->restore.guest_mapping, ctx->restore.nr_mapped_pages);
+        ctx->restore.guest_mapping = NULL;
+    }
+    return rc;
+}
+
 /*
  * Handle PAGE_DATA record from an existing buffer
  * Given a list of pfns, their types, and a block of page data from the
@@ -773,11 +889,19 @@ static int process_incoming_record_header(struct xc_sr_context *ctx, struct xc_s
     struct xc_sr_record rec;
     int rc;
 
-    rc = read_record_data(ctx, ctx->fd, rhdr, &rec);
-    if ( rc )
-        return rc;
+    switch ( rhdr->type )
+    {
+    case REC_TYPE_PAGE_DATA:
+        rc = handle_incoming_page_data(ctx, rhdr);
+        break;
+    default:
+        rc = read_record_data(ctx, ctx->fd, rhdr, &rec);
+        if ( rc == 0 )
+            rc = process_buffered_record(ctx, &rec);;
+        break;
+    }
 
-    return process_buffered_record(ctx, &rec);
+    return rc;
 }
 
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (30 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 31/39] tools/guest: restore: write data directly into guest Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-02-08 16:28   ` Ian Jackson
  2021-01-11 17:42 ` [PATCH v20210111 33/39] tools: recognize LIBXL_API_VERSION for 4.15 Olaf Hering
                   ` (6 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libs/light/libxl_save_msgs_gen.pl | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/tools/libs/light/libxl_save_msgs_gen.pl b/tools/libs/light/libxl_save_msgs_gen.pl
index 5bfbd4fd10..9d425b1dee 100755
--- a/tools/libs/light/libxl_save_msgs_gen.pl
+++ b/tools/libs/light/libxl_save_msgs_gen.pl
@@ -120,8 +120,8 @@ sub typeid ($) { my ($t) = @_; $t =~ s/\W/_/; return $t; };
 
 $out_body{'callout'} .= <<END;
 static int bytes_get(const unsigned char **msg,
-		     const unsigned char *const endmsg,
-		     void *result, int rlen)
+                     const unsigned char *const endmsg,
+                     void *result, int rlen)
 {
     if (endmsg - *msg < rlen) return 0;
     memcpy(result, *msg, rlen);
@@ -132,11 +132,11 @@ static int bytes_get(const unsigned char **msg,
 END
 $out_body{'helper'} .= <<END;
 static void bytes_put(unsigned char *const buf, int *len,
-		      const void *value, int vlen)
+                      const void *value, int vlen)
 {
     assert(vlen < INT_MAX/2 - *len);
     if (buf)
-	memcpy(buf + *len, value, vlen);
+        memcpy(buf + *len, value, vlen);
     *len += vlen;
 }
 
@@ -155,7 +155,7 @@ static int ${typeid}_get(const unsigned char **msg,
 END
     $out_body{'helper'} .= <<END;
 static void ${typeid}_put(unsigned char *const buf, int *len,
-			 const $simpletype value)
+                          const $simpletype value)
 {
     bytes_put(buf, len, &value, sizeof(value));
 }
@@ -192,15 +192,15 @@ END
 $out_body{'helper'} .= <<END;
 static void BLOCK_put(unsigned char *const buf,
                       int *len,
-		      const uint8_t *bytes, uint32_t size)
+                      const uint8_t *bytes, uint32_t size)
 {
     uint32_t_put(buf, len, size);
     bytes_put(buf, len, bytes, size);
 }
 
 static void STRING_put(unsigned char *const buf,
-		       int *len,
-		       const char *string)
+                       int *len,
+                       const char *string)
 {
     size_t slen = strlen(string);
     assert(slen < INT_MAX / 4);
@@ -216,7 +216,7 @@ foreach my $sr (qw(save restore)) {
            "(void *data)");
 
     f_decl("${receiveds}_${sr}", 'callout', 'int',
-	   "(const unsigned char *msg, uint32_t len, void *user)");
+           "(const unsigned char *msg, uint32_t len, void *user)");
 
     f_decl("${enumcallbacks}_${sr}", 'callout', 'unsigned',
            "(const ".cbtype($sr)." *cbs)");
@@ -301,7 +301,7 @@ END_ALWAYS
 	$c_callback_args .= "$c_args, ";
 	$c_recv.=
             "        if (!${typeid}_get(&msg, endmsg, $c_get_args)) return 0;\n";
-        f_more("${encode}_$name", "	${typeid}_put(buf, &len, $c_args);\n");
+        f_more("${encode}_$name", "        ${typeid}_put(buf, &len, $c_args);\n");
     }
     $f_more_sr->($c_recv);
     $c_decl .= "void *user)";


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 33/39] tools: recognize LIBXL_API_VERSION for 4.15
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (31 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props Olaf Hering
                   ` (5 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu

This is required by upcoming API changes.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/include/libxl.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 3433c950f9..6546dcd819 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -690,7 +690,8 @@ typedef struct libxl__ctx libxl_ctx;
 #if LIBXL_API_VERSION != 0x040200 && LIBXL_API_VERSION != 0x040300 && \
     LIBXL_API_VERSION != 0x040400 && LIBXL_API_VERSION != 0x040500 && \
     LIBXL_API_VERSION != 0x040700 && LIBXL_API_VERSION != 0x040800 && \
-    LIBXL_API_VERSION != 0x041300 && LIBXL_API_VERSION != 0x041400
+    LIBXL_API_VERSION != 0x041300 && LIBXL_API_VERSION != 0x041400 && \
+    LIBXL_API_VERSION != 0x041500
 #error Unknown LIBXL_API_VERSION
 #endif
 #endif


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (32 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 33/39] tools: recognize LIBXL_API_VERSION for 4.15 Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-12  9:17   ` Christian Lindig
  2021-01-11 17:42 ` [PATCH v20210111 35/39] tools: change struct precopy_stats to precopy_stats_t Olaf Hering
                   ` (4 subsequent siblings)
  38 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD,
	Christian Lindig, David Scott

Upcoming changes will pass more knobs down to xc_domain_save.
Adjust the libxl_domain_suspend API to allow easy adding of additional knobs.

No change in behavior intented.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/include/libxl.h                | 26 +++++++++++++++++++++++---
 tools/libs/light/libxl_domain.c      |  7 ++++---
 tools/ocaml/libs/xl/xenlight_stubs.c |  3 ++-
 tools/xl/xl_migrate.c                |  9 ++++++---
 tools/xl/xl_saverestore.c            |  3 ++-
 5 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 6546dcd819..94b8f1095f 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -1667,12 +1667,32 @@ static inline int libxl_retrieve_domain_configuration_0x041200(
     libxl_retrieve_domain_configuration_0x041200
 #endif
 
+/*
+ * LIBXL_HAVE_DOMAIN_SUSPEND_PROPS indicates that the
+ * libxl_domain_suspend_props() function takes a props struct.
+ */
+#define LIBXL_HAVE_DOMAIN_SUSPEND_PROPS 1
+
+typedef struct {
+    uint32_t flags; /* LIBXL_SUSPEND_* */
+} libxl_domain_suspend_props;
+#define LIBXL_SUSPEND_DEBUG 1
+#define LIBXL_SUSPEND_LIVE 2
+
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
-                         int flags, /* LIBXL_SUSPEND_* */
+                         libxl_domain_suspend_props *props,
                          const libxl_asyncop_how *ao_how)
                          LIBXL_EXTERNAL_CALLERS_ONLY;
-#define LIBXL_SUSPEND_DEBUG 1
-#define LIBXL_SUSPEND_LIVE 2
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041500
+static inline int libxl_domain_suspend_0x041400(libxl_ctx *ctx, uint32_t domid,
+                         int fd, int flags, /* LIBXL_SUSPEND_* */
+                         const libxl_asyncop_how *ao_how)
+{
+    libxl_domain_suspend_props props = { .flags = flags, };
+    return libxl_domain_suspend(ctx, domid, fd, &props, ao_how);
+}
+#define libxl_domain_suspend libxl_domain_suspend_0x041400
+#endif
 
 /*
  * Only suspend domain, do not save its state to file, do not destroy it.
diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domain.c
index 5d4ec90711..45e0c57c3a 100644
--- a/tools/libs/light/libxl_domain.c
+++ b/tools/libs/light/libxl_domain.c
@@ -505,7 +505,8 @@ static void domain_suspend_cb(libxl__egc *egc,
 
 }
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+                         libxl_domain_suspend_props *props,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -526,8 +527,8 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
     dss->domid = domid;
     dss->fd = fd;
     dss->type = type;
-    dss->live = flags & LIBXL_SUSPEND_LIVE;
-    dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+    dss->live = props->flags & LIBXL_SUSPEND_LIVE;
+    dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
     dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
 
     rc = libxl__fd_flags_modify_save(gc, dss->fd,
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c
index 352a00134d..eaf7bce35a 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -614,10 +614,11 @@ value stub_libxl_domain_suspend(value ctx, value domid, value fd, value async, v
 	int ret;
 	uint32_t c_domid = Int_val(domid);
 	int c_fd = Int_val(fd);
+    libxl_domain_suspend_props props = {};
 	libxl_asyncop_how *ao_how = aohow_val(async);
 
 	caml_enter_blocking_section();
-	ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, ao_how);
+	ret = libxl_domain_suspend(CTX, c_domid, c_fd, &props, ao_how);
 	caml_leave_blocking_section();
 
 	free(ao_how);
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 856a6e2be1..fc9f69bf06 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -188,7 +188,10 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     char *away_domname;
     char rc_buf;
     uint8_t *config_data;
-    int config_len, flags = LIBXL_SUSPEND_LIVE;
+    int config_len;
+    libxl_domain_suspend_props props = {
+        .flags = LIBXL_SUSPEND_LIVE,
+        };
     unsigned xtl_flags = XTL_STDIOSTREAM_HIDE_PROGRESS;
 
     save_domain_core_begin(domid, preserve_domid, override_config_file,
@@ -210,8 +213,8 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     xtl_stdiostream_adjust_flags(logger, xtl_flags, 0);
 
     if (debug)
-        flags |= LIBXL_SUSPEND_DEBUG;
-    rc = libxl_domain_suspend(ctx, domid, send_fd, flags, NULL);
+        props.flags |= LIBXL_SUSPEND_DEBUG;
+    rc = libxl_domain_suspend(ctx, domid, send_fd, &props, NULL);
     if (rc) {
         fprintf(stderr, "migration sender: libxl_domain_suspend failed"
                 " (rc=%d)\n", rc);
diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c
index 953d791d1a..476d4d9a6a 100644
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -130,6 +130,7 @@ static int save_domain(uint32_t domid, int preserve_domid,
     int fd;
     uint8_t *config_data;
     int config_len;
+    libxl_domain_suspend_props props = {};
 
     save_domain_core_begin(domid, preserve_domid, override_config_file,
                            &config_data, &config_len);
@@ -146,7 +147,7 @@ static int save_domain(uint32_t domid, int preserve_domid,
 
     save_domain_core_writeconfig(fd, filename, config_data, config_len);
 
-    int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL);
+    int rc = libxl_domain_suspend(ctx, domid, fd, &props, NULL);
     close(fd);
 
     if (rc < 0) {


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 35/39] tools: change struct precopy_stats to precopy_stats_t
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (33 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 36/39] tools: add callback to libxl for precopy_policy and precopy_stats_t Olaf Hering
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

This will help libxl_save_msgs_gen.pl to copy the struct as a region of memory.

No change in behavior intented.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/include/xenguest.h        | 7 +++----
 tools/libs/guest/xg_sr_common.h | 2 +-
 tools/libs/guest/xg_sr_save.c   | 6 +++---
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h
index 775cf34c04..b567d7e0ec 100644
--- a/tools/include/xenguest.h
+++ b/tools/include/xenguest.h
@@ -435,18 +435,17 @@ static inline xen_pfn_t xc_dom_p2m(struct xc_dom_image *dom, xen_pfn_t pfn)
 struct xenevtchn_handle;
 
 /* For save's precopy_policy(). */
-struct precopy_stats
-{
+typedef struct {
     unsigned int iteration;
     unsigned long total_written;
     long dirty_count; /* -1 if unknown */
-};
+} precopy_stats_t;
 
 /*
  * A precopy_policy callback may not be running in the same address
  * space as libxc an so precopy_stats is passed by value.
  */
-typedef int (*precopy_policy_t)(struct precopy_stats, void *);
+typedef int (*precopy_policy_t)(precopy_stats_t, void *);
 
 /* callbacks provided by xc_domain_save */
 struct save_callbacks {
diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index f76af23bcc..ba2f7e72b1 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -271,7 +271,7 @@ struct xc_sr_context
             size_t pages_sent;
             size_t overhead_sent;
 
-            struct precopy_stats stats;
+            precopy_stats_t stats;
 
             unsigned int nr_batch_pfns;
             unsigned long *deferred_pages;
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index d766384ed6..c86180730f 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -489,7 +489,7 @@ static int update_progress_string(struct xc_sr_context *ctx, char **str)
 #define SPP_MAX_ITERATIONS      5
 #define SPP_TARGET_DIRTY_COUNT 50
 
-static int simple_precopy_policy(struct precopy_stats stats, void *user)
+static int simple_precopy_policy(precopy_stats_t stats, void *user)
 {
     return ((stats.dirty_count >= 0 &&
              stats.dirty_count < SPP_TARGET_DIRTY_COUNT) ||
@@ -516,13 +516,13 @@ static int send_memory_live(struct xc_sr_context *ctx)
     precopy_policy_t precopy_policy = ctx->save.callbacks->precopy_policy;
     void *data = ctx->save.callbacks->data;
 
-    struct precopy_stats *policy_stats;
+    precopy_stats_t *policy_stats;
 
     rc = update_progress_string(ctx, &progress_str);
     if ( rc )
         goto out;
 
-    ctx->save.stats = (struct precopy_stats){
+    ctx->save.stats = (precopy_stats_t){
         .dirty_count = ctx->save.p2m_size,
     };
     policy_stats = &ctx->save.stats;


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 36/39] tools: add callback to libxl for precopy_policy and precopy_stats_t
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (34 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 35/39] tools: change struct precopy_stats to precopy_stats_t Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 37/39] tools: add --max_iters to libxl_domain_suspend Olaf Hering
                   ` (2 subsequent siblings)
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

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>
---
 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(-)

diff --git a/tools/libs/light/libxl_dom_save.c b/tools/libs/light/libxl_dom_save.c
index 32e3cb5a13..3f3cff0342 100644
--- a/tools/libs/light/libxl_dom_save.c
+++ b/tools/libs/light/libxl_dom_save.c
@@ -373,6 +373,24 @@ int libxl__save_emulator_xenstore_data(libxl__domain_save_state *dss,
     return rc;
 }
 
+static int libxl__domain_save_precopy_policy(precopy_stats_t 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)
@@ -430,6 +448,7 @@ void libxl__domain_save(libxl__egc *egc, libxl__domain_save_state *dss)
         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;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index c79523ba92..d4cc694c01 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -124,6 +124,8 @@
 #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
 
 /* Size macros. */
 #define __AC(X,Y)   (X##Y)
diff --git a/tools/libs/light/libxl_save_msgs_gen.pl b/tools/libs/light/libxl_save_msgs_gen.pl
index 9d425b1dee..7481818361 100755
--- a/tools/libs/light/libxl_save_msgs_gen.pl
+++ b/tools/libs/light/libxl_save_msgs_gen.pl
@@ -23,6 +23,7 @@ our @msgs = (
                                              STRING doing_what),
                                             'unsigned long', 'done',
                                             'unsigned long', 'total'] ],
+    [ 'scxW',   "precopy_policy", ['precopy_stats_t', 'stats'] ],
     [ 'srcxA',  "suspend", [] ],
     [ 'srcxA',  "postcopy", [] ],
     [ 'srcxA',  "checkpoint", [] ],
@@ -142,7 +143,7 @@ static void bytes_put(unsigned char *const buf, int *len,
 
 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 precopy_stats_t xen_pfn_t), 'unsigned long') {
     my $typeid = typeid($simpletype);
     $out_body{'callout'} .= <<END;
 static int ${typeid}_get(const unsigned char **msg,


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 37/39] tools: add --max_iters to libxl_domain_suspend
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (35 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 36/39] tools: add callback to libxl for precopy_policy and precopy_stats_t Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 38/39] tools: add --min_remaining " Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 39/39] tools: add --abort_if_busy " Olaf Hering
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Migrating a large, and potentially busy, domU will take more
time than neccessary due to excessive number of copying iterations.

Allow to host admin to control the number of iterations which
copy cumulated domU dirty pages to the target host.

The default remains 5, which means one initial iteration to copy the
entire domU memory, and up to 4 additional iterations to copy dirty
memory from the still running domU. After the given number of iterations
the domU is suspended, remaining dirty memory is copied and the domU is
finally moved to the target host.

This patch adjusts xl(1) and the libxl API.
External users check LIBXL_HAVE_DOMAIN_SUSPEND_PROPS for the availibility
of the new .max_iters property.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 docs/man/xl.1.pod.in              |  4 ++++
 tools/include/libxl.h             |  1 +
 tools/libs/light/libxl_dom_save.c |  2 +-
 tools/libs/light/libxl_domain.c   |  1 +
 tools/libs/light/libxl_internal.h |  1 +
 tools/xl/xl_cmdtable.c            |  3 ++-
 tools/xl/xl_migrate.c             | 10 +++++++++-
 7 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index e6e4e8e83a..8339bd8e6f 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -496,6 +496,10 @@ such that it will be identical on the destination host, unless that
 configuration is overridden using the B<-C> option. Note that it is not
 possible to use this option for a 'localhost' migration.
 
+=item B<--max_iters> I<iterations>
+
+Number of copy iterations before final suspend+move (default: 5)
+
 =back
 
 =item B<remus> [I<OPTIONS>] I<domain-id> I<host>
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 94b8f1095f..646cef28aa 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -1675,6 +1675,7 @@ static inline int libxl_retrieve_domain_configuration_0x041200(
 
 typedef struct {
     uint32_t flags; /* LIBXL_SUSPEND_* */
+    uint32_t max_iters;
 } libxl_domain_suspend_props;
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
diff --git a/tools/libs/light/libxl_dom_save.c b/tools/libs/light/libxl_dom_save.c
index 3f3cff0342..938c0127f3 100644
--- a/tools/libs/light/libxl_dom_save.c
+++ b/tools/libs/light/libxl_dom_save.c
@@ -383,7 +383,7 @@ static int libxl__domain_save_precopy_policy(precopy_stats_t stats, void *user)
          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)
+    if (stats.iteration >= dss->max_iters)
         goto stop_copy;
     return XGS_POLICY_CONTINUE_PRECOPY;
 
diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domain.c
index 45e0c57c3a..612d3dc4ea 100644
--- a/tools/libs/light/libxl_domain.c
+++ b/tools/libs/light/libxl_domain.c
@@ -527,6 +527,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
     dss->domid = domid;
     dss->fd = fd;
     dss->type = type;
+    dss->max_iters = props->max_iters ?: LIBXL_XGS_POLICY_MAX_ITERATIONS;
     dss->live = props->flags & LIBXL_SUSPEND_LIVE;
     dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
     dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index d4cc694c01..80a31c3a88 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -3640,6 +3640,7 @@ struct libxl__domain_save_state {
     int live;
     int debug;
     int checkpointed_stream;
+    uint32_t max_iters;
     const libxl_domain_remus_info *remus;
     /* private */
     int rc;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index a0567169bf..75e2e4d54b 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -170,7 +170,8 @@ struct cmd_spec cmd_table[] = {
       "-T              Show timestamps during the migration process.\n"
       "--debug         Verify transferred domU page data.\n"
       "-p              Do not unpause domain after migrating it.\n"
-      "-D              Preserve the domain id"
+      "-D              Preserve the domain id\n"
+      "--max_iters N   Number of copy iterations before final stop+move"
     },
     { "restore",
       &main_restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index fc9f69bf06..a724bc21ea 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -180,6 +180,7 @@ static void migrate_do_preamble(int send_fd, int recv_fd, pid_t child,
 
 static void migrate_domain(uint32_t domid, int preserve_domid,
                            const char *rune, int debug,
+                           uint32_t max_iters,
                            const char *override_config_file)
 {
     pid_t child = -1;
@@ -191,6 +192,7 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     int config_len;
     libxl_domain_suspend_props props = {
         .flags = LIBXL_SUSPEND_LIVE,
+        .max_iters = max_iters,
         };
     unsigned xtl_flags = XTL_STDIOSTREAM_HIDE_PROGRESS;
 
@@ -555,8 +557,10 @@ int main_migrate(int argc, char **argv)
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0, pause_after_migration = 0;
     int preserve_domid = 0;
+    uint32_t max_iters = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
+        {"max_iters", 1, 0, 0x101},
         {"live", 0, 0, 0x200},
         COMMON_LONG_OPTS
     };
@@ -587,6 +591,9 @@ int main_migrate(int argc, char **argv)
     case 0x100: /* --debug */
         debug = 1;
         break;
+    case 0x101: /* --max_iters */
+        max_iters = atoi(optarg);
+        break;
     case 0x200: /* --live */
         /* ignored for compatibility with xm */
         break;
@@ -621,7 +628,8 @@ int main_migrate(int argc, char **argv)
                   pause_after_migration ? " -p" : "");
     }
 
-    migrate_domain(domid, preserve_domid, rune, debug, config_filename);
+    migrate_domain(domid, preserve_domid, rune, debug,
+                   max_iters, config_filename);
     return EXIT_SUCCESS;
 }
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 38/39] tools: add --min_remaining to libxl_domain_suspend
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (36 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 37/39] tools: add --max_iters to libxl_domain_suspend Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  2021-01-11 17:42 ` [PATCH v20210111 39/39] tools: add --abort_if_busy " Olaf Hering
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

The decision to stop+move a domU to the new host must be based on two factors:
- the available network bandwidth for the migration stream
- the maximum time a workload within a domU can be savely suspended

Both values define how many dirty pages a workload may produce prior the
final stop+move.

The default value of 50 pages is much too low with todays network bandwidths.
On an idle 1GiB link these 200K will be transferred within ~2ms.

Give the admin a knob to adjust the point when the final stop+move will
be done, so he can base this decision on his own needs.

This patch adjusts xl(1) and the libxl API.
External users check LIBXL_HAVE_DOMAIN_SUSPEND_PROPS for the availibility
of the new .min_remaining property.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 docs/man/xl.1.pod.in              |  8 ++++++++
 tools/include/libxl.h             |  1 +
 tools/libs/light/libxl_dom_save.c |  2 +-
 tools/libs/light/libxl_domain.c   |  1 +
 tools/libs/light/libxl_internal.h |  1 +
 tools/xl/xl_cmdtable.c            | 25 +++++++++++++------------
 tools/xl/xl_migrate.c             |  9 ++++++++-
 7 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index 8339bd8e6f..930270fe23 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -500,6 +500,14 @@ possible to use this option for a 'localhost' migration.
 
 Number of copy iterations before final suspend+move (default: 5)
 
+=item B<--min_remaing> I<pages>
+
+Number of remaining dirty pages. If the number of dirty pages drops that
+low, the guest is suspended and the domU will finally be moved to I<host>.
+
+This allows the host admin to control for how long the domU will likely
+be suspended during transit.
+
 =back
 
 =item B<remus> [I<OPTIONS>] I<domain-id> I<host>
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 646cef28aa..d45d3a4460 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -1676,6 +1676,7 @@ static inline int libxl_retrieve_domain_configuration_0x041200(
 typedef struct {
     uint32_t flags; /* LIBXL_SUSPEND_* */
     uint32_t max_iters;
+    uint32_t min_remaining;
 } libxl_domain_suspend_props;
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
diff --git a/tools/libs/light/libxl_dom_save.c b/tools/libs/light/libxl_dom_save.c
index 938c0127f3..ad5df89b2c 100644
--- a/tools/libs/light/libxl_dom_save.c
+++ b/tools/libs/light/libxl_dom_save.c
@@ -381,7 +381,7 @@ static int libxl__domain_save_precopy_policy(precopy_stats_t stats, void *user)
 
     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)
+    if (stats.dirty_count >= 0 && stats.dirty_count < dss->min_remaining)
         goto stop_copy;
     if (stats.iteration >= dss->max_iters)
         goto stop_copy;
diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domain.c
index 612d3dc4ea..ae4dc9ad01 100644
--- a/tools/libs/light/libxl_domain.c
+++ b/tools/libs/light/libxl_domain.c
@@ -528,6 +528,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
     dss->fd = fd;
     dss->type = type;
     dss->max_iters = props->max_iters ?: LIBXL_XGS_POLICY_MAX_ITERATIONS;
+    dss->min_remaining = props->min_remaining ?: LIBXL_XGS_POLICY_TARGET_DIRTY_COUNT;
     dss->live = props->flags & LIBXL_SUSPEND_LIVE;
     dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
     dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index 80a31c3a88..d7631022a0 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -3641,6 +3641,7 @@ struct libxl__domain_save_state {
     int debug;
     int checkpointed_stream;
     uint32_t max_iters;
+    uint32_t min_remaining;
     const libxl_domain_remus_info *remus;
     /* private */
     int rc;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 75e2e4d54b..2c1acaf536 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -160,18 +160,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"
-      "-T              Show timestamps during the migration process.\n"
-      "--debug         Verify transferred domU page data.\n"
-      "-p              Do not unpause domain after migrating it.\n"
-      "-D              Preserve the domain id\n"
-      "--max_iters N   Number of copy iterations before final stop+move"
+      "-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"
+      "-T                Show timestamps during the migration process.\n"
+      "--debug           Verify transferred domU page data.\n"
+      "-p                Do not unpause domain after migrating it.\n"
+      "-D                Preserve the domain id\n"
+      "--max_iters N     Number of copy iterations before final stop+move\n"
+      "--min_remaining N Number of remaining dirty pages before final stop+move"
     },
     { "restore",
       &main_restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index a724bc21ea..fd826f671b 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -181,6 +181,7 @@ static void migrate_do_preamble(int send_fd, int recv_fd, pid_t child,
 static void migrate_domain(uint32_t domid, int preserve_domid,
                            const char *rune, int debug,
                            uint32_t max_iters,
+                           uint32_t min_remaining,
                            const char *override_config_file)
 {
     pid_t child = -1;
@@ -193,6 +194,7 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     libxl_domain_suspend_props props = {
         .flags = LIBXL_SUSPEND_LIVE,
         .max_iters = max_iters,
+        .min_remaining = min_remaining,
         };
     unsigned xtl_flags = XTL_STDIOSTREAM_HIDE_PROGRESS;
 
@@ -558,9 +560,11 @@ int main_migrate(int argc, char **argv)
     int opt, daemonize = 1, monitor = 1, debug = 0, pause_after_migration = 0;
     int preserve_domid = 0;
     uint32_t max_iters = 0;
+    uint32_t min_remaining = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
         {"max_iters", 1, 0, 0x101},
+        {"min_remaining", 1, 0, 0x102},
         {"live", 0, 0, 0x200},
         COMMON_LONG_OPTS
     };
@@ -594,6 +598,9 @@ int main_migrate(int argc, char **argv)
     case 0x101: /* --max_iters */
         max_iters = atoi(optarg);
         break;
+    case 0x102: /* --min_remaining */
+        min_remaining = atoi(optarg);
+        break;
     case 0x200: /* --live */
         /* ignored for compatibility with xm */
         break;
@@ -629,7 +636,7 @@ int main_migrate(int argc, char **argv)
     }
 
     migrate_domain(domid, preserve_domid, rune, debug,
-                   max_iters, config_filename);
+                   max_iters, min_remaining, config_filename);
     return EXIT_SUCCESS;
 }
 


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [PATCH v20210111 39/39] tools: add --abort_if_busy to libxl_domain_suspend
  2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
                   ` (37 preceding siblings ...)
  2021-01-11 17:42 ` [PATCH v20210111 38/39] tools: add --min_remaining " Olaf Hering
@ 2021-01-11 17:42 ` Olaf Hering
  38 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-01-11 17:42 UTC (permalink / raw)
  To: xen-devel; +Cc: Olaf Hering, Ian Jackson, Wei Liu, Anthony PERARD

Provide a knob to the host admin to abort the live migration of a
running domU if the downtime during final transit will be too long
for the workload within domU.

Adjust error reporting. Add ERROR_MIGRATION_ABORTED to allow callers of
libxl_domain_suspend to distinguish between errors and the requested
constraint.

Adjust precopy_policy to simplify reporting of remaining dirty pages.
The loop in send_memory_live populates ->dirty_count in a different
place than ->iteration. Let it proceeed one more time to provide the
desired information before leaving the loop.

This patch adjusts xl(1) and the libxl API.
External users check LIBXL_HAVE_DOMAIN_SUSPEND_PROPS for the availibility
of the new .abort_if_busy property.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 docs/man/xl.1.pod.in                  |  8 +++++++
 tools/include/libxl.h                 |  1 +
 tools/libs/light/libxl_dom_save.c     |  7 ++++++-
 tools/libs/light/libxl_domain.c       |  1 +
 tools/libs/light/libxl_internal.h     |  2 ++
 tools/libs/light/libxl_stream_write.c |  9 +++++++-
 tools/libs/light/libxl_types.idl      |  1 +
 tools/xl/xl_cmdtable.c                |  6 +++++-
 tools/xl/xl_migrate.c                 | 30 ++++++++++++++++++++-------
 9 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index 930270fe23..8064acb226 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -508,6 +508,14 @@ low, the guest is suspended and the domU will finally be moved to I<host>.
 This allows the host admin to control for how long the domU will likely
 be suspended during transit.
 
+=item B<--abort_if_busy>
+
+Abort migration instead of doing final suspend/move/resume if the
+guest produced more than I<min_remaining> dirty pages during th number
+of I<max_iters> iterations.
+This avoids long periods of time where the guest is suspended, which
+may confuse the workload within domU.
+
 =back
 
 =item B<remus> [I<OPTIONS>] I<domain-id> I<host>
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index d45d3a4460..ad660e9c9f 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -1680,6 +1680,7 @@ typedef struct {
 } libxl_domain_suspend_props;
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_ABORT_IF_BUSY 4
 
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
                          libxl_domain_suspend_props *props,
diff --git a/tools/libs/light/libxl_dom_save.c b/tools/libs/light/libxl_dom_save.c
index ad5df89b2c..1999a8997f 100644
--- a/tools/libs/light/libxl_dom_save.c
+++ b/tools/libs/light/libxl_dom_save.c
@@ -383,11 +383,16 @@ static int libxl__domain_save_precopy_policy(precopy_stats_t stats, void *user)
          stats.iteration, stats.dirty_count, stats.total_written);
     if (stats.dirty_count >= 0 && stats.dirty_count < dss->min_remaining)
         goto stop_copy;
-    if (stats.iteration >= dss->max_iters)
+    if (stats.dirty_count >= 0 && stats.iteration >= dss->max_iters)
         goto stop_copy;
     return XGS_POLICY_CONTINUE_PRECOPY;
 
 stop_copy:
+    if (dss->abort_if_busy)
+    {
+        dss->remaining_dirty_pages = stats.dirty_count;
+        return XGS_POLICY_ABORT;
+    }
     return XGS_POLICY_STOP_AND_COPY;
 }
 
diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domain.c
index ae4dc9ad01..913653bd76 100644
--- a/tools/libs/light/libxl_domain.c
+++ b/tools/libs/light/libxl_domain.c
@@ -529,6 +529,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
     dss->type = type;
     dss->max_iters = props->max_iters ?: LIBXL_XGS_POLICY_MAX_ITERATIONS;
     dss->min_remaining = props->min_remaining ?: LIBXL_XGS_POLICY_TARGET_DIRTY_COUNT;
+    dss->abort_if_busy = props->flags & LIBXL_SUSPEND_ABORT_IF_BUSY;
     dss->live = props->flags & LIBXL_SUSPEND_LIVE;
     dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
     dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index d7631022a0..c08918b37b 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -3639,9 +3639,11 @@ struct libxl__domain_save_state {
     libxl_domain_type type;
     int live;
     int debug;
+    int abort_if_busy;
     int checkpointed_stream;
     uint32_t max_iters;
     uint32_t min_remaining;
+    long remaining_dirty_pages;
     const libxl_domain_remus_info *remus;
     /* private */
     int rc;
diff --git a/tools/libs/light/libxl_stream_write.c b/tools/libs/light/libxl_stream_write.c
index 634f3240d1..1ab3943f3e 100644
--- a/tools/libs/light/libxl_stream_write.c
+++ b/tools/libs/light/libxl_stream_write.c
@@ -344,11 +344,18 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void *dss_void,
         goto err;
 
     if (retval) {
+        if (dss->remaining_dirty_pages) {
+            LOGD(NOTICE, dss->domid, "saving domain: aborted,"
+                 " %ld remaining dirty pages.", dss->remaining_dirty_pages);
+        } else {
         LOGEVD(ERROR, errnoval, dss->domid, "saving domain: %s",
               dss->dsps.guest_responded ?
               "domain responded to suspend request" :
               "domain did not respond to suspend request");
-        if (!dss->dsps.guest_responded)
+        }
+        if (dss->remaining_dirty_pages)
+           rc = ERROR_MIGRATION_ABORTED;
+        else if(!dss->dsps.guest_responded)
             rc = ERROR_GUEST_TIMEDOUT;
         else if (dss->rc)
             rc = dss->rc;
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 05324736b7..1901122b6d 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -76,6 +76,7 @@ libxl_error = Enumeration("error", [
     (-30, "QMP_DEVICE_NOT_ACTIVE"), # a device has failed to be become active
     (-31, "QMP_DEVICE_NOT_FOUND"), # the requested device has not been found
     (-32, "QEMU_API"), # QEMU's replies don't contains expected members
+    (-33, "MIGRATION_ABORTED"),
     ], value_namespace = "")
 
 libxl_domain_type = Enumeration("domain_type", [
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 2c1acaf536..41292f3b5a 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -172,7 +172,11 @@ struct cmd_spec cmd_table[] = {
       "-p                Do not unpause domain after migrating it.\n"
       "-D                Preserve the domain id\n"
       "--max_iters N     Number of copy iterations before final stop+move\n"
-      "--min_remaining N Number of remaining dirty pages before final stop+move"
+      "--min_remaining N Number of remaining dirty pages before final stop+move\n"
+      "--abort_if_busy   Abort migration instead of doing final stop+move,\n"
+      "                  if the number of dirty pages is higher than <min_remaining>\n"
+      "                  after <max_iters> iterations. Otherwise the amount of memory\n"
+      "                  to be transfered would exceed maximum allowed domU downtime."
     },
     { "restore",
       &main_restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index fd826f671b..68fdc8630a 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -179,7 +179,7 @@ static void migrate_do_preamble(int send_fd, int recv_fd, pid_t child,
 }
 
 static void migrate_domain(uint32_t domid, int preserve_domid,
-                           const char *rune, int debug,
+                           const char *rune, int debug, int abort_if_busy,
                            uint32_t max_iters,
                            uint32_t min_remaining,
                            const char *override_config_file)
@@ -218,14 +218,20 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
 
     if (debug)
         props.flags |= LIBXL_SUSPEND_DEBUG;
+    if (abort_if_busy)
+        props.flags |= LIBXL_SUSPEND_ABORT_IF_BUSY;
     rc = libxl_domain_suspend(ctx, domid, send_fd, &props, NULL);
     if (rc) {
         fprintf(stderr, "migration sender: libxl_domain_suspend failed"
                 " (rc=%d)\n", rc);
-        if (rc == ERROR_GUEST_TIMEDOUT)
-            goto failed_suspend;
-        else
-            goto failed_resume;
+        switch (rc) {
+            case ERROR_GUEST_TIMEDOUT:
+                goto failed_suspend;
+            case ERROR_MIGRATION_ABORTED:
+                goto failed_busy;
+            default:
+                goto failed_resume;
+        }
     }
 
     //fprintf(stderr, "migration sender: Transfer complete.\n");
@@ -307,6 +313,12 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     fprintf(stderr, "Migration failed, failed to suspend at sender.\n");
     exit(EXIT_FAILURE);
 
+ failed_busy:
+    close(send_fd);
+    migration_child_report(recv_fd);
+    fprintf(stderr, "Migration aborted as requested, domain is too busy.\n");
+    exit(EXIT_FAILURE);
+
  failed_resume:
     close(send_fd);
     migration_child_report(recv_fd);
@@ -558,13 +570,14 @@ int main_migrate(int argc, char **argv)
     char *rune = NULL;
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0, pause_after_migration = 0;
-    int preserve_domid = 0;
+    int preserve_domid = 0, abort_if_busy = 0;
     uint32_t max_iters = 0;
     uint32_t min_remaining = 0;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
         {"max_iters", 1, 0, 0x101},
         {"min_remaining", 1, 0, 0x102},
+        {"abort_if_busy", 0, 0, 0x103},
         {"live", 0, 0, 0x200},
         COMMON_LONG_OPTS
     };
@@ -601,6 +614,9 @@ int main_migrate(int argc, char **argv)
     case 0x102: /* --min_remaining */
         min_remaining = atoi(optarg);
         break;
+    case 0x103: /* --abort_if_busy */
+        abort_if_busy = 1;
+        break;
     case 0x200: /* --live */
         /* ignored for compatibility with xm */
         break;
@@ -635,7 +651,7 @@ int main_migrate(int argc, char **argv)
                   pause_after_migration ? " -p" : "");
     }
 
-    migrate_domain(domid, preserve_domid, rune, debug,
+    migrate_domain(domid, preserve_domid, rune, debug, abort_if_busy,
                    max_iters, min_remaining, config_filename);
     return EXIT_SUCCESS;
 }


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 01/39] stubdom: fix tpm_version
  2021-01-11 17:41 ` [PATCH v20210111 01/39] stubdom: fix tpm_version Olaf Hering
@ 2021-01-11 18:06   ` Samuel Thibault
  0 siblings, 0 replies; 62+ messages in thread
From: Samuel Thibault @ 2021-01-11 18:06 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Daniel De Graaf, Quan Xu

Olaf Hering, le lun. 11 janv. 2021 18:41:46 +0100, a ecrit:
> It is just a declaration, not a variable.
> 
> ld: /home/abuild/rpmbuild/BUILD/xen-4.14.20200616T103126.3625b04991/non-dbg/stubdom/vtpmmgr/vtpmmgr.a(vtpm_cmd_handler.o):(.bss+0x0): multiple definition of `tpm_version'; /home/abuild/rpmbuild/BUILD/xen-4.14.20200616T103126.3625b04991/non-dbg/stubdom/vtpmmgr/vtpmmgr.a(vtpmmgr.o):(.bss+0x0): first defined here
> 
> Signed-off-by: Olaf Hering <olaf@aepfle.de>

Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

> ---
>  stubdom/vtpmmgr/vtpmmgr.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/stubdom/vtpmmgr/vtpmmgr.h b/stubdom/vtpmmgr/vtpmmgr.h
> index 2e6f8de9e4..f40ca9fd67 100644
> --- a/stubdom/vtpmmgr/vtpmmgr.h
> +++ b/stubdom/vtpmmgr/vtpmmgr.h
> @@ -53,7 +53,7 @@
>  enum {
>      TPM1_HARDWARE = 1,
>      TPM2_HARDWARE,
> -} tpm_version;
> +};
>  
>  struct tpm_hardware_version {
>      int hw_version;
> 



^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props
  2021-01-11 17:42 ` [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props Olaf Hering
@ 2021-01-12  9:17   ` Christian Lindig
  0 siblings, 0 replies; 62+ messages in thread
From: Christian Lindig @ 2021-01-12  9:17 UTC (permalink / raw)
  To: Olaf Hering, xen-devel; +Cc: Ian Jackson, Wei Liu, Anthony Perard, David Scott

> Upcoming changes will pass more knobs down to xc_domain_save.
> Adjust the libxl_domain_suspend API to allow easy adding of additional knobs.

Acked-by: Christian Lindig <christian.lindig@citrix.com>

________________________________________
From: Olaf Hering <olaf@aepfle.de>
Sent: 11 January 2021 17:42
To: xen-devel@lists.xenproject.org
Cc: Olaf Hering; Ian Jackson; Wei Liu; Anthony Perard; Christian Lindig; David Scott
Subject: [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props

Upcoming changes will pass more knobs down to xc_domain_save.
Adjust the libxl_domain_suspend API to allow easy adding of additional knobs.

No change in behavior intented.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/include/libxl.h                | 26 +++++++++++++++++++++++---
 tools/libs/light/libxl_domain.c      |  7 ++++---
 tools/ocaml/libs/xl/xenlight_stubs.c |  3 ++-
 tools/xl/xl_migrate.c                |  9 ++++++---
 tools/xl/xl_saverestore.c            |  3 ++-
 5 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 6546dcd819..94b8f1095f 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -1667,12 +1667,32 @@ static inline int libxl_retrieve_domain_configuration_0x041200(
     libxl_retrieve_domain_configuration_0x041200
 #endif

+/*
+ * LIBXL_HAVE_DOMAIN_SUSPEND_PROPS indicates that the
+ * libxl_domain_suspend_props() function takes a props struct.
+ */
+#define LIBXL_HAVE_DOMAIN_SUSPEND_PROPS 1
+
+typedef struct {
+    uint32_t flags; /* LIBXL_SUSPEND_* */
+} libxl_domain_suspend_props;
+#define LIBXL_SUSPEND_DEBUG 1
+#define LIBXL_SUSPEND_LIVE 2
+
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
-                         int flags, /* LIBXL_SUSPEND_* */
+                         libxl_domain_suspend_props *props,
                          const libxl_asyncop_how *ao_how)
                          LIBXL_EXTERNAL_CALLERS_ONLY;
-#define LIBXL_SUSPEND_DEBUG 1
-#define LIBXL_SUSPEND_LIVE 2
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041500
+static inline int libxl_domain_suspend_0x041400(libxl_ctx *ctx, uint32_t domid,
+                         int fd, int flags, /* LIBXL_SUSPEND_* */
+                         const libxl_asyncop_how *ao_how)
+{
+    libxl_domain_suspend_props props = { .flags = flags, };
+    return libxl_domain_suspend(ctx, domid, fd, &props, ao_how);
+}
+#define libxl_domain_suspend libxl_domain_suspend_0x041400
+#endif

 /*
  * Only suspend domain, do not save its state to file, do not destroy it.
diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domain.c
index 5d4ec90711..45e0c57c3a 100644
--- a/tools/libs/light/libxl_domain.c
+++ b/tools/libs/light/libxl_domain.c
@@ -505,7 +505,8 @@ static void domain_suspend_cb(libxl__egc *egc,

 }

-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+                         libxl_domain_suspend_props *props,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -526,8 +527,8 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
     dss->domid = domid;
     dss->fd = fd;
     dss->type = type;
-    dss->live = flags & LIBXL_SUSPEND_LIVE;
-    dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+    dss->live = props->flags & LIBXL_SUSPEND_LIVE;
+    dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
     dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;

     rc = libxl__fd_flags_modify_save(gc, dss->fd,
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c
index 352a00134d..eaf7bce35a 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -614,10 +614,11 @@ value stub_libxl_domain_suspend(value ctx, value domid, value fd, value async, v
        int ret;
        uint32_t c_domid = Int_val(domid);
        int c_fd = Int_val(fd);
+    libxl_domain_suspend_props props = {};
        libxl_asyncop_how *ao_how = aohow_val(async);

        caml_enter_blocking_section();
-       ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, ao_how);
+       ret = libxl_domain_suspend(CTX, c_domid, c_fd, &props, ao_how);
        caml_leave_blocking_section();

        free(ao_how);
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 856a6e2be1..fc9f69bf06 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -188,7 +188,10 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     char *away_domname;
     char rc_buf;
     uint8_t *config_data;
-    int config_len, flags = LIBXL_SUSPEND_LIVE;
+    int config_len;
+    libxl_domain_suspend_props props = {
+        .flags = LIBXL_SUSPEND_LIVE,
+        };
     unsigned xtl_flags = XTL_STDIOSTREAM_HIDE_PROGRESS;

     save_domain_core_begin(domid, preserve_domid, override_config_file,
@@ -210,8 +213,8 @@ static void migrate_domain(uint32_t domid, int preserve_domid,
     xtl_stdiostream_adjust_flags(logger, xtl_flags, 0);

     if (debug)
-        flags |= LIBXL_SUSPEND_DEBUG;
-    rc = libxl_domain_suspend(ctx, domid, send_fd, flags, NULL);
+        props.flags |= LIBXL_SUSPEND_DEBUG;
+    rc = libxl_domain_suspend(ctx, domid, send_fd, &props, NULL);
     if (rc) {
         fprintf(stderr, "migration sender: libxl_domain_suspend failed"
                 " (rc=%d)\n", rc);
diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c
index 953d791d1a..476d4d9a6a 100644
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -130,6 +130,7 @@ static int save_domain(uint32_t domid, int preserve_domid,
     int fd;
     uint8_t *config_data;
     int config_len;
+    libxl_domain_suspend_props props = {};

     save_domain_core_begin(domid, preserve_domid, override_config_file,
                            &config_data, &config_len);
@@ -146,7 +147,7 @@ static int save_domain(uint32_t domid, int preserve_domid,

     save_domain_core_writeconfig(fd, filename, config_data, config_len);

-    int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL);
+    int rc = libxl_domain_suspend(ctx, domid, fd, &props, NULL);
     close(fd);

     if (rc < 0) {


^ permalink raw reply related	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 03/39] docs: remove stale create example from xl.1
  2021-01-11 17:41 ` [PATCH v20210111 03/39] docs: remove stale create example from xl.1 Olaf Hering
@ 2021-02-08 15:41   ` Ian Jackson
  2021-02-08 15:42   ` Ian Jackson
  1 sibling, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 15:41 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu

Olaf Hering writes ("[PATCH v20210111 03/39] docs: remove stale create example from xl.1"):
> Maybe xm create had a feature to create a domU based on a configuration
> file. xl create requires the '-f' option to refer to a file.
> There is no code to look into XEN_CONFIG_DIR, so remove the example.

This series seems to contain a number of patches which seem to have
slipped through the net before the freeze, despite some having reviews
even :-/.

I'm going to go through them and look at the status of each and hope
to commit and/or review and/or release-ack as many of them as
possible.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 03/39] docs: remove stale create example from xl.1
  2021-01-11 17:41 ` [PATCH v20210111 03/39] docs: remove stale create example from xl.1 Olaf Hering
  2021-02-08 15:41   ` Ian Jackson
@ 2021-02-08 15:42   ` Ian Jackson
  1 sibling, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 15:42 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu

Olaf Hering writes ("[PATCH v20210111 03/39] docs: remove stale create example from xl.1"):
> Maybe xm create had a feature to create a domU based on a configuration
> file. xl create requires the '-f' option to refer to a file.
> There is no code to look into XEN_CONFIG_DIR, so remove the example.

Reviewed-by: Ian Jackson <iwj@xenproject.org>

This is docs so

Release-Acked-by: Ian Jackson <iwj@xenproject.org>

I'm queueing it now.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5
  2021-01-11 17:41 ` [PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5 Olaf Hering
@ 2021-02-08 15:45   ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 15:45 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Anthony PERARD, Wei Liu

Olaf Hering writes ("[PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5"):
> xl(1) opens xl.conf in XEN_CONFIG_DIR.
> Substitute this variable also in the man page.
> 
> Signed-off-by: Olaf Hering <olaf@aepfle.de>
> Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>

Release-Acked-by: Ian Jackson <iwj@xenproject.org>

This is docs.  Worst risk is slight chance of breaking the build.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 02/39] xl: use proper name for bash_completion file
  2021-01-11 17:41 ` [PATCH v20210111 02/39] xl: use proper name for bash_completion file Olaf Hering
@ 2021-02-08 15:48   ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 15:48 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu, Anthony PERARD

Olaf Hering writes ("[PATCH v20210111 02/39] xl: use proper name for bash_completion file"):
> Files in the bash-completion dirs should be named like the commands,
> without suffix. Without this change 'xl' will not be recognized as a
> command with completion support if BASH_COMPLETION_DIR is set to
> /usr/share/bash-completion/completions.
> 
> Fixes commit 9136a919b19929ecb242ef327053d55d824397df

This was committed already.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option
  2021-01-11 17:41 ` [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option Olaf Hering
@ 2021-02-08 16:03   ` Ian Jackson
  2021-02-08 17:23     ` Olaf Hering
  0 siblings, 1 reply; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 16:03 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu

Olaf Hering writes ("[PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option"):
> In the near future all fresh installations will have an empty /etc.
> The content of this directory will not be controlled by the package
> manager anymore. One of the reasons for this move is to make snapshots
> more robust.

As I wrote in September 2019 I don't agree with it, if it's intended
as a claim about all systems that Xen will run on.

However, this seems to be an accidental retention in the commit
message, since the content of the commit is now what I asked for,
which is to make this directory configurable.

So I approve of the contents of this patch in principle.

> As a first step into this direction, add a knob to configure to allow
> storing the hotplug scripts to libexec because they are not exactly
> configuration. The current default is unchanged, which is
> /etc/xen/scripts.

I suggest this commit message as a compromise:

  Some distros plan for fresh installations will have an empty /etc,
  whose content will not be controlled by the package manager
  anymore.

  To make this possible, add a knob to configure to allow storing the
  hotplug scripts to libexec instead of /etc/xen/scripts.

Olaf, would that be OK with you ?


As for detailed review:

> diff --git a/m4/paths.m4 b/m4/paths.m4
> index 89d3bb8312..0cec2bb190 100644
> --- a/m4/paths.m4
> +++ b/m4/paths.m4
...
> +AC_ARG_WITH([xen-scriptdir],
> +    AS_HELP_STRING([--with-xen-scriptdir=DIR],
> +    [Path to directory for dom0 hotplug scripts. [SYSCONFDIR/xen/scripts]]),
> +    [xen_scriptdir_path=$withval],
> +    [xen_scriptdir_path=$sysconfdir/xen/scripts])
...
> -XEN_SCRIPT_DIR=$XEN_CONFIG_DIR/scripts
> +XEN_SCRIPT_DIR=$xen_scriptdir_path
>  AC_SUBST(XEN_SCRIPT_DIR)

It is not clear to me why the deefault is changed from
"$XEN_CONFIG_DIR/scripts" to "$sysconfdir/xen/scripts" and there isn't
any explanation for this in the commit message.  I think this may make
no difference but an explanation is called for.


As for the release ack question: there is a risk that this patch would
break the build, by causing the scripts to go somewhere wrong.  This
risk seems fairly low and osstest would catch it.

However, I find it difficult to analyse the consequence of the changed
way the default is calculated.

So, a conditional release ack:

Release-Acked-by: Ian Jackson <iwj@xenproject.org>

subject to changing this patch to make the actual implemented default
to still be $XEN_CONFIG_DIR/scripts.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts
  2021-01-11 17:41 ` [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts Olaf Hering
@ 2021-02-08 16:04   ` Ian Jackson
  2021-02-08 16:23     ` Ian Jackson
  0 siblings, 1 reply; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 16:04 UTC (permalink / raw)
  To: Olaf Hering
  Cc: xen-devel, Andrew Cooper, George Dunlap, Ian Jackson,
	Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu,
	Anthony PERARD

Olaf Hering writes ("[PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts"):
> Replace all hardcoded paths to use XEN_SCRIPT_DIR to expand the actual location.
> 
> Update .gitignore.

Reviewed-by: Ian Jackson <iwj@xenproject.org>
Release-Acked-by: Ian Jackson <iwj@xenproject.org>

Although I would have preferred these to be separate patches.

I see no reason not to commit this now so I will queue it.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate
  2021-01-11 17:41 ` [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate Olaf Hering
@ 2021-02-08 16:22   ` Ian Jackson
  2021-02-08 17:30     ` Olaf Hering
  2021-02-08 18:53     ` Olaf Hering
  0 siblings, 2 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 16:22 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu, Anthony PERARD

Olaf Hering writes ("[PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate"):
> During 'xl -v.. migrate domU host' a large amount of debug is generated.
> It is difficult to map each line to the sending and receiving side.
> Also the time spent for migration is not reported.
> 
> With 'xl migrate -T domU host' both sides will print timestamps and
> also the pid of the invoked xl process to make it more obvious which
> side produced a given log line.
> 
> Signed-off-by: Olaf Hering <olaf@aepfle.de>

This is from October and ought to have been reviewed much sooner.
Sorry.

With my maintainer hat on: this is a useful development but I am not
sure about the choice of -T, and the choice to make this a
migrate-specific option.  Most unix things that have an option to
print timestamps use `-t`.  But we have already stolen `-t` as a
global option for "prinht CR as well as LF".  Hrmf.

Under the circumstances -T for migrate seems a plausible and
conservative choice.  I think maybe we should maybe add a global -T
later.

Reviewed-by: Ian Jackson <iwj@xenproject.org>



Now I have to decide what to do about it for 4.15.

The downside risks I see from reading the patch are:

* The CLI API choice is being made in a hurry.

* We might break something.  This actually seems quite unlikely since
  I have reviewed the code changes in detail.


I wonder if I can get a quick second option from someone on the API
question.  Using up a single letter option is something I don't want
to just rush into.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts
  2021-02-08 16:04   ` Ian Jackson
@ 2021-02-08 16:23     ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 16:23 UTC (permalink / raw)
  To: Olaf Hering, xen-devel, Andrew Cooper, George Dunlap,
	Jan Beulich, Julien Grall, Stefano Stabellini, Wei Liu,
	Anthony PERARD

Ian Jackson writes ("Re: [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts"):
> Olaf Hering writes ("[PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts"):
> > Replace all hardcoded paths to use XEN_SCRIPT_DIR to expand the actual location.
> > 
> > Update .gitignore.
> 
> Reviewed-by: Ian Jackson <iwj@xenproject.org>
> Release-Acked-by: Ian Jackson <iwj@xenproject.org>
> 
> Although I would have preferred these to be separate patches.
> 
> I see no reason not to commit this now so I will queue it.

I split the patch up.

I also dropped the hunk for docs/misc/block-scripts.txt which seems to
have been left over from v1.  Thanks to Andy for spotting that.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 08/39] xl: fix description of migrate --debug
  2021-01-11 17:41 ` [PATCH v20210111 08/39] xl: fix description of migrate --debug Olaf Hering
@ 2021-02-08 16:25   ` Ian Jackson
  2021-02-08 16:39     ` Andrew Cooper
  0 siblings, 1 reply; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 16:25 UTC (permalink / raw)
  To: Olaf Hering, Andrew Cooper; +Cc: xen-devel, Wei Liu, Anthony PERARD

Olaf Hering writes ("[PATCH v20210111 08/39] xl: fix description of migrate --debug"):
> xl migrate --debug used to track every pfn in every batch of pages.
> But these times are gone. Adjust the help text to tell what --debug
> is supposed to do today.
...
> -Display huge (!) amount of debug information during the migration process.
> +Verify transferred domU page data. All memory will be transferred one more
> +time to the destination host while the domU is paused, and compared with
> +the result of the inital transfer while the domU was still running.

Andy, as our expert on migration, can you confirm whether this is
accurate ?

Docs (including usage message) so

Release-Acked-by: Ian Jackson <iwj@xenproject.org>


Thanks,
Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl
  2021-01-11 17:42 ` [PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl Olaf Hering
@ 2021-02-08 16:28   ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 16:28 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu, Anthony PERARD

Olaf Hering writes ("[PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl"):
> Signed-off-by: Olaf Hering <olaf@aepfle.de>

Personally I think this is busywork but I am happy to take the patch.

Release-Acked-by: Ian Jackson <iwj@xenproject.org>
Acked-by: Ian Jackson <iwj@xenproject.org>

Release risk is clearly negligible since it's a whitespace change.



^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 08/39] xl: fix description of migrate --debug
  2021-02-08 16:25   ` Ian Jackson
@ 2021-02-08 16:39     ` Andrew Cooper
  2021-02-09 12:42       ` Olaf Hering
  0 siblings, 1 reply; 62+ messages in thread
From: Andrew Cooper @ 2021-02-08 16:39 UTC (permalink / raw)
  To: Ian Jackson, Olaf Hering; +Cc: xen-devel, Wei Liu, Anthony PERARD

On 08/02/2021 16:25, Ian Jackson wrote:
> Olaf Hering writes ("[PATCH v20210111 08/39] xl: fix description of migrate --debug"):
>> xl migrate --debug used to track every pfn in every batch of pages.
>> But these times are gone. Adjust the help text to tell what --debug
>> is supposed to do today.
> ...
>> -Display huge (!) amount of debug information during the migration process.
>> +Verify transferred domU page data. All memory will be transferred one more
>> +time to the destination host while the domU is paused, and compared with
>> +the result of the inital transfer while the domU was still running.
> Andy, as our expert on migration, can you confirm whether this is
> accurate ?
>
> Docs (including usage message) so
>
> Release-Acked-by: Ian Jackson <iwj@xenproject.org>

Yeah - I totally changed what --debug did in migration v2, and this is
stale.  The legacy behaviour was unhelpful on any non-trivial guest.

It is possibly worth noting that you typically do see changed data when
using --debug, because of how the front/back pairs work.  This was a bit
of a curveball during development.

~Andrew


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option
  2021-02-08 16:03   ` Ian Jackson
@ 2021-02-08 17:23     ` Olaf Hering
  2021-02-08 17:48       ` Ian Jackson
  0 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-02-08 17:23 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Wei Liu

[-- Attachment #1: Type: text/plain, Size: 1787 bytes --]

Am Mon, 8 Feb 2021 16:03:29 +0000
schrieb Ian Jackson <iwj@xenproject.org>:

> I suggest this commit message as a compromise:
> 
>   Some distros plan for fresh installations will have an empty /etc,
>   whose content will not be controlled by the package manager
>   anymore.
> 
>   To make this possible, add a knob to configure to allow storing the
>   hotplug scripts to libexec instead of /etc/xen/scripts.
> 
> Olaf, would that be OK with you ?

Yes, this is fine. Thanks.


> As for detailed review:
> 
> > diff --git a/m4/paths.m4 b/m4/paths.m4
> > index 89d3bb8312..0cec2bb190 100644
> > --- a/m4/paths.m4
> > +++ b/m4/paths.m4  
> ...
> > +AC_ARG_WITH([xen-scriptdir],
> > +    AS_HELP_STRING([--with-xen-scriptdir=DIR],
> > +    [Path to directory for dom0 hotplug scripts. [SYSCONFDIR/xen/scripts]]),
> > +    [xen_scriptdir_path=$withval],
> > +    [xen_scriptdir_path=$sysconfdir/xen/scripts])  
> ...
> > -XEN_SCRIPT_DIR=$XEN_CONFIG_DIR/scripts
> > +XEN_SCRIPT_DIR=$xen_scriptdir_path
> >  AC_SUBST(XEN_SCRIPT_DIR)  
> 
> It is not clear to me why the deefault is changed from
> "$XEN_CONFIG_DIR/scripts" to "$sysconfdir/xen/scripts" and there isn't
> any explanation for this in the commit message.  I think this may make
> no difference but an explanation is called for.

The reason is the ordering of assignments in the file:
AC_ARG_WITH comes early in the file, XEN_CONFIG_DIR= is assigned much later.

It seems the assignments for CONFIG_DIR and XEN_CONFIG_DIR can be moved up, because $sysconfdir is expected to be set already. As a result the new AC_ARG_WITH= can continue to use "$XEN_CONFIG_DIR/scripts" for the default case. I assume the current ordering is to have a separate AC_ARG_WITH and AC_SUBST section.

Olaf

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate
  2021-02-08 16:22   ` Ian Jackson
@ 2021-02-08 17:30     ` Olaf Hering
  2021-02-08 17:47       ` Ian Jackson
  2021-02-08 18:53     ` Olaf Hering
  1 sibling, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-02-08 17:30 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Wei Liu, Anthony PERARD

[-- Attachment #1: Type: text/plain, Size: 468 bytes --]

Am Mon, 8 Feb 2021 16:22:54 +0000
schrieb Ian Jackson <iwj@xenproject.org>:

> I wonder if I can get a quick second option from someone on the API
> question.  Using up a single letter option is something I don't want
> to just rush into.

Maybe put "-T" or "-t" into xl.c:main() instead, so that every command prints timestamp+pid?

For everything beside "migrate" it will only be useful along with a couple of "-v" to enable global debug output.


Olaf

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 15/39] tools/guest: save: move batch_pfns
  2021-01-11 17:42 ` [PATCH v20210111 15/39] tools/guest: save: move batch_pfns Olaf Hering
@ 2021-02-08 17:46   ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 17:46 UTC (permalink / raw)
  To: Andrew Cooper, Olaf Hering; +Cc: xen-devel, Wei Liu, Anthony PERARD

Olaf Hering writes ("[PATCH v20210111 15/39] tools/guest: save: move batch_pfns"):
> The batch_pfns array is already allocated in advance.
> Move it into the preallocated area.

I think these patche really need a review from someone who understands
the migration code.  Ideally, Andy, who unfortunately has been very
busy.

I doubt this is going to make it for 4.15 :-( but maybe Andy or
someone else has an opinion.

Thanks,
Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate
  2021-02-08 17:30     ` Olaf Hering
@ 2021-02-08 17:47       ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 17:47 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu, Anthony PERARD

Olaf Hering writes ("Re: [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate"):
> Am Mon, 8 Feb 2021 16:22:54 +0000
> schrieb Ian Jackson <iwj@xenproject.org>:
> 
> > I wonder if I can get a quick second option from someone on the API
> > question.  Using up a single letter option is something I don't want
> > to just rush into.
> 
> Maybe put "-T" or "-t" into xl.c:main() instead, so that every command prints timestamp+pid?

Yes, I think following some informal irc discussions that that would
be best.

> For everything beside "migrate" it will only be useful along with a couple of "-v" to enable global debug output.

Right.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option
  2021-02-08 17:23     ` Olaf Hering
@ 2021-02-08 17:48       ` Ian Jackson
  2021-02-08 17:54         ` Olaf Hering
  0 siblings, 1 reply; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 17:48 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu

Olaf Hering writes ("Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option"):
> The reason is the ordering of assignments in the file:
> AC_ARG_WITH comes early in the file, XEN_CONFIG_DIR= is assigned much later.

Ah.

> It seems the assignments for CONFIG_DIR and XEN_CONFIG_DIR can be moved up, because $sysconfdir is expected to be set already. As a result the new AC_ARG_WITH= can continue to use "$XEN_CONFIG_DIR/scripts" for the default case.

That would be best I think.

> I assume the current ordering is to have a separate AC_ARG_WITH and AC_SUBST section.

I could be wrong, but I don't think the location of AC_SUBST matters.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option
  2021-02-08 17:48       ` Ian Jackson
@ 2021-02-08 17:54         ` Olaf Hering
  2021-02-08 17:55           ` Ian Jackson
  0 siblings, 1 reply; 62+ messages in thread
From: Olaf Hering @ 2021-02-08 17:54 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Wei Liu

[-- Attachment #1: Type: text/plain, Size: 433 bytes --]

Am Mon, 8 Feb 2021 17:48:31 +0000
schrieb Ian Jackson <iwj@xenproject.org>:

> > It seems the assignments for CONFIG_DIR and XEN_CONFIG_DIR can be moved up, because $sysconfdir is expected to be set already. As a result the new AC_ARG_WITH= can continue to use "$XEN_CONFIG_DIR/scripts" for the default case.  
> 
> That would be best I think.

I will split this into individual changes and send a separate series.


Olaf

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option
  2021-02-08 17:54         ` Olaf Hering
@ 2021-02-08 17:55           ` Ian Jackson
  0 siblings, 0 replies; 62+ messages in thread
From: Ian Jackson @ 2021-02-08 17:55 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Wei Liu

Olaf Hering writes ("Re: [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option"):
> Am Mon, 8 Feb 2021 17:48:31 +0000
> schrieb Ian Jackson <iwj@xenproject.org>:
> > > It seems the assignments for CONFIG_DIR and XEN_CONFIG_DIR can be moved up, because $sysconfdir is expected to be set already. As a result the new AC_ARG_WITH= can continue to use "$XEN_CONFIG_DIR/scripts" for the default case.  
> > 
> > That would be best I think.
> 
> I will split this into individual changes and send a separate series.

OK, thanks, that will help with de-risking this from a release PoV.

Ian.


^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate
  2021-02-08 16:22   ` Ian Jackson
  2021-02-08 17:30     ` Olaf Hering
@ 2021-02-08 18:53     ` Olaf Hering
  1 sibling, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-02-08 18:53 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Wei Liu, Anthony PERARD

[-- Attachment #1: Type: text/plain, Size: 607 bytes --]

Am Mon, 8 Feb 2021 16:22:54 +0000
schrieb Ian Jackson <iwj@xenproject.org>:

> With my maintainer hat on: this is a useful development but I am not
> sure about the choice of -T, and the choice to make this a
> migrate-specific option.  Most unix things that have an option to
> print timestamps use `-t`.  But we have already stolen `-t` as a
> global option for "prinht CR as well as LF".  Hrmf.

Was 'xl -t' intentionally left out of xl.c:help()?
It is only mentioned in the xl man page.

If yes, my change will also omit it.
If no, I will add it along with the global -T option.


Olaf

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

* Re: [PATCH v20210111 08/39] xl: fix description of migrate --debug
  2021-02-08 16:39     ` Andrew Cooper
@ 2021-02-09 12:42       ` Olaf Hering
  0 siblings, 0 replies; 62+ messages in thread
From: Olaf Hering @ 2021-02-09 12:42 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Ian Jackson, xen-devel, Wei Liu, Anthony PERARD

[-- Attachment #1: Type: text/plain, Size: 1203 bytes --]

Am Mon, 8 Feb 2021 16:39:01 +0000
schrieb Andrew Cooper <andrew.cooper3@citrix.com>:

> It is possibly worth noting that you typically do see changed data when
> using --debug, because of how the front/back pairs work.  This was a bit
> of a curveball during development.

I just noticed "migrate --debug" is a noop, "verify" works just for remus or colo, per send_domain_memory_live():
- libxl_domain_remus_start sets checkpointed_stream to COLO/REMUS
- libxl_domain_suspend sets checkpointed_stream to NONE.
- external callers can not influence this internal state.
- main_migrate_receive sets it based on the command line option.


In case we want a "verify" functionality also for migration, the "stream_type" check could be removed to make it work everywhere.
The domU is suspended, it should not make much difference how often its memory is passed around in this suspended state.
But this would be a separate thing to explore.

Having a "LIBXL_SUSPEND_DEBUG/XCFLAGS_DEBUG" might be useful, but in its current state the flags should have "STREAM_VERIFY" in their name.

So instead of changing the help string I suggest to remove "--debug" altogether from the xl UI.


Olaf

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 62+ messages in thread

end of thread, other threads:[~2021-02-09 12:43 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-11 17:41 [PATCH v20210111 00/39] leftover from 2020 Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 01/39] stubdom: fix tpm_version Olaf Hering
2021-01-11 18:06   ` Samuel Thibault
2021-01-11 17:41 ` [PATCH v20210111 02/39] xl: use proper name for bash_completion file Olaf Hering
2021-02-08 15:48   ` Ian Jackson
2021-01-11 17:41 ` [PATCH v20210111 03/39] docs: remove stale create example from xl.1 Olaf Hering
2021-02-08 15:41   ` Ian Jackson
2021-02-08 15:42   ` Ian Jackson
2021-01-11 17:41 ` [PATCH v20210111 04/39] docs: substitute XEN_CONFIG_DIR in xl.conf.5 Olaf Hering
2021-02-08 15:45   ` Ian Jackson
2021-01-11 17:41 ` [PATCH v20210111 05/39] tools: add with-xen-scriptdir configure option Olaf Hering
2021-02-08 16:03   ` Ian Jackson
2021-02-08 17:23     ` Olaf Hering
2021-02-08 17:48       ` Ian Jackson
2021-02-08 17:54         ` Olaf Hering
2021-02-08 17:55           ` Ian Jackson
2021-01-11 17:41 ` [PATCH v20210111 06/39] Use XEN_SCRIPT_DIR to refer to /etc/xen/scripts Olaf Hering
2021-02-08 16:04   ` Ian Jackson
2021-02-08 16:23     ` Ian Jackson
2021-01-11 17:41 ` [PATCH v20210111 07/39] xl: optionally print timestamps during xl migrate Olaf Hering
2021-02-08 16:22   ` Ian Jackson
2021-02-08 17:30     ` Olaf Hering
2021-02-08 17:47       ` Ian Jackson
2021-02-08 18:53     ` Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 08/39] xl: fix description of migrate --debug Olaf Hering
2021-02-08 16:25   ` Ian Jackson
2021-02-08 16:39     ` Andrew Cooper
2021-02-09 12:42       ` Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 09/39] tools: add readv_exact to libxenctrl Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 10/39] tools: add xc_is_known_page_type " Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 11/39] tools: use xc_is_known_page_type Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 12/39] tools: unify type checking for data pfns in migration stream Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 13/39] tools: show migration transfer rate in send_dirty_pages Olaf Hering
2021-01-11 17:41 ` [PATCH v20210111 14/39] tools/guest: prepare to allocate arrays once Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 15/39] tools/guest: save: move batch_pfns Olaf Hering
2021-02-08 17:46   ` Ian Jackson
2021-01-11 17:42 ` [PATCH v20210111 16/39] tools/guest: save: move mfns array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 17/39] tools/guest: save: move types array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 18/39] tools/guest: save: move errors array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 19/39] tools/guest: save: move iov array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 20/39] tools/guest: save: move rec_pfns array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 21/39] tools/guest: save: move guest_data array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 22/39] tools/guest: save: move local_pages array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 23/39] tools/guest: restore: move pfns array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 24/39] tools/guest: restore: move types array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 25/39] tools/guest: restore: move mfns array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 26/39] tools/guest: restore: move map_errs array Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 27/39] tools/guest: restore: move mfns array in populate_pfns Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 28/39] tools/guest: restore: move pfns " Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 29/39] tools/guest: restore: split record processing Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 30/39] tools/guest: restore: split handle_page_data Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 31/39] tools/guest: restore: write data directly into guest Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 32/39] tools: remove tabs from code produced by libxl_save_msgs_gen.pl Olaf Hering
2021-02-08 16:28   ` Ian Jackson
2021-01-11 17:42 ` [PATCH v20210111 33/39] tools: recognize LIBXL_API_VERSION for 4.15 Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 34/39] tools: adjust libxl_domain_suspend to receive a struct props Olaf Hering
2021-01-12  9:17   ` Christian Lindig
2021-01-11 17:42 ` [PATCH v20210111 35/39] tools: change struct precopy_stats to precopy_stats_t Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 36/39] tools: add callback to libxl for precopy_policy and precopy_stats_t Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 37/39] tools: add --max_iters to libxl_domain_suspend Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 38/39] tools: add --min_remaining " Olaf Hering
2021-01-11 17:42 ` [PATCH v20210111 39/39] tools: add --abort_if_busy " Olaf Hering

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.