[1/4] zdtm: add an option to show criu statistics

Submitted by Andrei Vagin on Nov. 7, 2017, 12:02 a.m.

Details

Message ID 20171107000237.27668-2-avagin@openvz.org
State New
Series "Optimize a number of pipes to splice memory"
Headers show

Commit Message

Andrei Vagin Nov. 7, 2017, 12:02 a.m.
From: Andrei Vagin <avagin@virtuozzo.com>

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
---
 criu/include/stats.h |  2 ++
 criu/page-pipe.c     |  3 +++
 criu/stats.c         |  4 ++++
 images/stats.proto   |  2 ++
 test/zdtm.py         | 15 ++++++++++++++-
 5 files changed, 25 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/stats.h b/criu/include/stats.h
index d30be6a39..07690b8ea 100644
--- a/criu/include/stats.h
+++ b/criu/include/stats.h
@@ -26,6 +26,8 @@  enum {
 	CNT_PAGES_SKIPPED_PARENT,
 	CNT_PAGES_WRITTEN,
 	CNT_PAGES_LAZY,
+	CNT_PAGE_PIPES,
+	CNT_PAGE_PIPE_BUFS,
 
 	DUMP_CNT_NR_STATS,
 };
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index a47119b18..7da8bebc3 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -9,6 +9,7 @@ 
 #include "criu-log.h"
 #include "page-pipe.h"
 #include "fcntl.h"
+#include "stats.h"
 
 /* can existing iov accumulate the page? */
 static inline bool iov_grow_page(struct iovec *iov, unsigned long addr)
@@ -34,12 +35,14 @@  static struct page_pipe_buf *ppb_alloc(struct page_pipe *pp)
 	ppb = xmalloc(sizeof(*ppb));
 	if (!ppb)
 		return NULL;
+	cnt_add(CNT_PAGE_PIPE_BUFS, 1);
 
 	if (pipe(ppb->p)) {
 		xfree(ppb);
 		pr_perror("Can't make pipe for page-pipe");
 		return NULL;
 	}
+	cnt_add(CNT_PAGE_PIPES, 1);
 
 	ppb->pipe_size = fcntl(ppb->p[0], F_GETPIPE_SZ, 0) / PAGE_SIZE;
 	pp->nr_pipes++;
diff --git a/criu/stats.c b/criu/stats.c
index 2b0c1a60b..64679b134 100644
--- a/criu/stats.c
+++ b/criu/stats.c
@@ -160,6 +160,10 @@  void write_stats(int what)
 		ds_entry.pages_skipped_parent = dstats->counts[CNT_PAGES_SKIPPED_PARENT];
 		ds_entry.pages_written = dstats->counts[CNT_PAGES_WRITTEN];
 		ds_entry.pages_lazy = dstats->counts[CNT_PAGES_LAZY];
+		ds_entry.page_pipes = dstats->counts[CNT_PAGE_PIPES];
+		ds_entry.has_page_pipes = true;
+		ds_entry.page_pipe_bufs = dstats->counts[CNT_PAGE_PIPE_BUFS];
+		ds_entry.has_page_pipe_bufs = true;
 
 		name = "dump";
 	} else if (what == RESTORE_STATS) {
diff --git a/images/stats.proto b/images/stats.proto
index ad6279a81..d76503441 100644
--- a/images/stats.proto
+++ b/images/stats.proto
@@ -14,6 +14,8 @@  message dump_stats_entry {
 	optional uint32			irmap_resolve		= 8;
 
 	required uint64			pages_lazy		= 9;
+	optional uint64			page_pipes		= 10;
+	optional uint64			page_pipe_bufs		= 11;
 }
 
 message restore_stats_entry {
diff --git a/test/zdtm.py b/test/zdtm.py
index 145959c71..1a0ef6741 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -838,6 +838,7 @@  class criu:
 		self.__remote = (opts['remote'] and True or False)
 		self.__criu = (opts['rpc'] and criu_rpc or criu_cli)
 		self.__check_only = (opts['check_only'] and True or False)
+		self.__show_stats = (opts['show_stats'] and True or False)
 		self.__lazy_pages_p = None
 		self.__page_server_p = None
 
@@ -971,6 +972,14 @@  class criu:
 			else:
 				raise test_fail_exc("CRIU %s" % action)
 
+	def show_stats(self, action):
+		if not self.__show_stats:
+			return
+
+		subprocess.Popen(["../crit/crit", "show",
+				os.path.join(self.__dump_path,
+				str(self.__iter), "stats-%s" % action)]).wait()
+
 	def dump(self, action, opts = []):
 		self.__iter += 1
 		os.mkdir(self.__ddir())
@@ -1039,6 +1048,8 @@  class criu:
 		if self.__mdedup and self.__iter > 1:
 			self.__criu_act("dedup", opts = [])
 
+		self.show_stats("dump")
+
 		if self.__leave_stopped:
 			pstree_check_stopped(self.__test.getpid())
 			pstree_signal(self.__test.getpid(), signal.SIGKILL)
@@ -1089,6 +1100,7 @@  class criu:
 			self.__criu_act("restore", opts = r_opts + ["--restore-detached"] + ['--check-only'])
 
 		self.__criu_act("restore", opts = r_opts + ["--restore-detached"])
+		self.show_stats("restore")
 
 		if self.__leave_stopped:
 			pstree_check_stopped(self.__test.getpid())
@@ -1567,7 +1579,7 @@  class Launcher:
 		nd = ('nocr', 'norst', 'pre', 'iters', 'page_server', 'sibling', 'stop', 'empty_ns',
 				'fault', 'keep_img', 'report', 'snaps', 'sat', 'script', 'rpc', 'lazy_pages',
 				'join_ns', 'dedup', 'sbs', 'freezecg', 'user', 'dry_run', 'noauto_dedup',
-				'remote_lazy_pages', 'remote', 'check_only')
+				'remote_lazy_pages', 'remote', 'check_only', 'show_stats')
 		arg = repr((name, desc, flavor, {d: self.__opts[d] for d in nd}))
 
 		if self.__use_log:
@@ -2122,6 +2134,7 @@  rp.add_argument("--lazy-pages", help = "restore pages on demand", action = 'stor
 rp.add_argument("--remote-lazy-pages", help = "simulate lazy migration", action = 'store_true')
 rp.add_argument("--title", help = "A test suite title", default = "criu")
 rp.add_argument("--check-only", help = "Additionally try to dump/restore in --check-only mode", action = 'store_true')
+rp.add_argument("--show-stats", help = "Show criu statistics", action = 'store_true')
 
 lp = sp.add_parser("list", help = "List tests")
 lp.set_defaults(action = list_tests)

Comments

Mike Rapoport Nov. 7, 2017, 1:04 p.m.
On Tue, Nov 07, 2017 at 03:02:34AM +0300, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@virtuozzo.com>
>
> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
> ---
>  criu/include/stats.h |  2 ++
>  criu/page-pipe.c     |  3 +++
>  criu/stats.c         |  4 ++++
>  images/stats.proto   |  2 ++
>  test/zdtm.py         | 15 ++++++++++++++-
>  5 files changed, 25 insertions(+), 1 deletion(-)

Sounds like two patches to me:
Add pipes and pipe buffers stats
zdtm: add an option to show criu statistics

> diff --git a/criu/include/stats.h b/criu/include/stats.h
> index d30be6a39..07690b8ea 100644
> --- a/criu/include/stats.h
> +++ b/criu/include/stats.h
> @@ -26,6 +26,8 @@ enum {
>  	CNT_PAGES_SKIPPED_PARENT,
>  	CNT_PAGES_WRITTEN,
>  	CNT_PAGES_LAZY,
> +	CNT_PAGE_PIPES,
> +	CNT_PAGE_PIPE_BUFS,
> 
>  	DUMP_CNT_NR_STATS,
>  };
> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
> index a47119b18..7da8bebc3 100644
> --- a/criu/page-pipe.c
> +++ b/criu/page-pipe.c
> @@ -9,6 +9,7 @@
>  #include "criu-log.h"
>  #include "page-pipe.h"
>  #include "fcntl.h"
> +#include "stats.h"
> 
>  /* can existing iov accumulate the page? */
>  static inline bool iov_grow_page(struct iovec *iov, unsigned long addr)
> @@ -34,12 +35,14 @@ static struct page_pipe_buf *ppb_alloc(struct page_pipe *pp)
>  	ppb = xmalloc(sizeof(*ppb));
>  	if (!ppb)
>  		return NULL;
> +	cnt_add(CNT_PAGE_PIPE_BUFS, 1);
> 
>  	if (pipe(ppb->p)) {
>  		xfree(ppb);
>  		pr_perror("Can't make pipe for page-pipe");
>  		return NULL;
>  	}
> +	cnt_add(CNT_PAGE_PIPES, 1);
> 
>  	ppb->pipe_size = fcntl(ppb->p[0], F_GETPIPE_SZ, 0) / PAGE_SIZE;
>  	pp->nr_pipes++;
> diff --git a/criu/stats.c b/criu/stats.c
> index 2b0c1a60b..64679b134 100644
> --- a/criu/stats.c
> +++ b/criu/stats.c
> @@ -160,6 +160,10 @@ void write_stats(int what)
>  		ds_entry.pages_skipped_parent = dstats->counts[CNT_PAGES_SKIPPED_PARENT];
>  		ds_entry.pages_written = dstats->counts[CNT_PAGES_WRITTEN];
>  		ds_entry.pages_lazy = dstats->counts[CNT_PAGES_LAZY];
> +		ds_entry.page_pipes = dstats->counts[CNT_PAGE_PIPES];
> +		ds_entry.has_page_pipes = true;
> +		ds_entry.page_pipe_bufs = dstats->counts[CNT_PAGE_PIPE_BUFS];
> +		ds_entry.has_page_pipe_bufs = true;
> 
>  		name = "dump";
>  	} else if (what == RESTORE_STATS) {
> diff --git a/images/stats.proto b/images/stats.proto
> index ad6279a81..d76503441 100644
> --- a/images/stats.proto
> +++ b/images/stats.proto
> @@ -14,6 +14,8 @@ message dump_stats_entry {
>  	optional uint32			irmap_resolve		= 8;
> 
>  	required uint64			pages_lazy		= 9;
> +	optional uint64			page_pipes		= 10;
> +	optional uint64			page_pipe_bufs		= 11;
>  }
> 
>  message restore_stats_entry {
> diff --git a/test/zdtm.py b/test/zdtm.py
> index 145959c71..1a0ef6741 100755
> --- a/test/zdtm.py
> +++ b/test/zdtm.py
> @@ -838,6 +838,7 @@ class criu:
>  		self.__remote = (opts['remote'] and True or False)
>  		self.__criu = (opts['rpc'] and criu_rpc or criu_cli)
>  		self.__check_only = (opts['check_only'] and True or False)
> +		self.__show_stats = (opts['show_stats'] and True or False)
>  		self.__lazy_pages_p = None
>  		self.__page_server_p = None
> 
> @@ -971,6 +972,14 @@ class criu:
>  			else:
>  				raise test_fail_exc("CRIU %s" % action)
> 
> +	def show_stats(self, action):
> +		if not self.__show_stats:
> +			return
> +
> +		subprocess.Popen(["../crit/crit", "show",
> +				os.path.join(self.__dump_path,
> +				str(self.__iter), "stats-%s" % action)]).wait()
> +

I think it's worth defining crit_bin and using it for Popen()

>  	def dump(self, action, opts = []):
>  		self.__iter += 1
>  		os.mkdir(self.__ddir())
> @@ -1039,6 +1048,8 @@ class criu:
>  		if self.__mdedup and self.__iter > 1:
>  			self.__criu_act("dedup", opts = [])
> 
> +		self.show_stats("dump")
> +
>  		if self.__leave_stopped:
>  			pstree_check_stopped(self.__test.getpid())
>  			pstree_signal(self.__test.getpid(), signal.SIGKILL)
> @@ -1089,6 +1100,7 @@ class criu:
>  			self.__criu_act("restore", opts = r_opts + ["--restore-detached"] + ['--check-only'])
> 
>  		self.__criu_act("restore", opts = r_opts + ["--restore-detached"])
> +		self.show_stats("restore")
> 
>  		if self.__leave_stopped:
>  			pstree_check_stopped(self.__test.getpid())
> @@ -1567,7 +1579,7 @@ class Launcher:
>  		nd = ('nocr', 'norst', 'pre', 'iters', 'page_server', 'sibling', 'stop', 'empty_ns',
>  				'fault', 'keep_img', 'report', 'snaps', 'sat', 'script', 'rpc', 'lazy_pages',
>  				'join_ns', 'dedup', 'sbs', 'freezecg', 'user', 'dry_run', 'noauto_dedup',
> -				'remote_lazy_pages', 'remote', 'check_only')
> +				'remote_lazy_pages', 'remote', 'check_only', 'show_stats')
>  		arg = repr((name, desc, flavor, {d: self.__opts[d] for d in nd}))
> 
>  		if self.__use_log:
> @@ -2122,6 +2134,7 @@ rp.add_argument("--lazy-pages", help = "restore pages on demand", action = 'stor
>  rp.add_argument("--remote-lazy-pages", help = "simulate lazy migration", action = 'store_true')
>  rp.add_argument("--title", help = "A test suite title", default = "criu")
>  rp.add_argument("--check-only", help = "Additionally try to dump/restore in --check-only mode", action = 'store_true')
> +rp.add_argument("--show-stats", help = "Show criu statistics", action = 'store_true')
> 
>  lp = sp.add_parser("list", help = "List tests")
>  lp.set_defaults(action = list_tests)
> -- 
> 2.13.6
> 
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
>