diff --git a/criu/crtools.c b/criu/crtools.c index fd94d3705..f8ba9f171 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -282,6 +282,7 @@ int main(int argc, char *argv[], char *envp[]) { "cgroup-dump-controller", required_argument, 0, 1082 }, { SK_INFLIGHT_PARAM, no_argument, 0, 1083 }, { "deprecated", no_argument, 0, 1084 }, + { "display-stats", no_argument, 0, 1086 }, { }, }; @@ -594,6 +595,9 @@ int main(int argc, char *argv[], char *envp[]) pr_msg("Turn deprecated stuff ON\n"); opts.deprecated_ok = true; break; + case 1086: + opts.display_stats = true; + break; case 'V': pr_msg("Version: %s\n", CRIU_VERSION); if (strcmp(CRIU_GITID, "0")) @@ -913,6 +917,7 @@ usage: " -v2|-vv - also warnings (default level)\n" " -v3|-vvv - also information messages and timestamps\n" " -v4|-vvvv - lots of debug\n" +" --display-stats print out dump/restore stats\n" "\n" "* Memory dumping options:\n" " --track-mem turn on memory changes tracker in kernel\n" diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h index e618c8cd0..cbf248502 100644 --- a/criu/include/cr_options.h +++ b/criu/include/cr_options.h @@ -115,6 +115,7 @@ struct cr_options { * to turn one ON while the code is in. */ bool deprecated_ok; + bool display_stats; }; extern struct cr_options opts; diff --git a/criu/stats.c b/criu/stats.c index e7251d53d..7e62d7ae8 100644 --- a/criu/stats.c +++ b/criu/stats.c @@ -3,6 +3,7 @@ #include #include "int.h" #include "atomic.h" +#include "cr_options.h" #include "rst-malloc.h" #include "protobuf.h" #include "stats.h" @@ -102,6 +103,38 @@ static void encode_time(int t, u_int32_t *to) *to = tm->total.tv_sec * USEC_PER_SEC + tm->total.tv_usec; } +static void display_stats(int what, StatsEntry *stats) +{ + if (what == DUMP_STATS) { + pr_msg("Displaying dump stats:\n"); + pr_msg("Freezing time: %d us\n", stats->dump->freezing_time); + pr_msg("Frozen time: %d us\n", stats->dump->frozen_time); + pr_msg("Memory dump time: %d us\n", stats->dump->memdump_time); + pr_msg("Memory write time: %d us\n", stats->dump->memwrite_time); + if (stats->dump->has_irmap_resolve) + pr_msg("IRMAP resolve time: %d us\n", stats->dump->irmap_resolve); + pr_msg("Memory pages scanned: %" PRIu64 " (0x%" PRIx64 ")\n", stats->dump->pages_scanned, + stats->dump->pages_scanned); + pr_msg("Memory pages skipped from parent: %" PRIu64 " (0x%" PRIx64 ")\n", + stats->dump->pages_skipped_parent, + stats->dump->pages_skipped_parent); + pr_msg("Memory pages written: %" PRIu64 " (0x%" PRIx64 ")\n", stats->dump->pages_written, + stats->dump->pages_written); + } else if (what == RESTORE_STATS) { + pr_msg("Displaying restore stats:\n"); + pr_msg("Pages compared: %" PRIu64 " (0x%" PRIx64 ")\n", stats->restore->pages_compared, + stats->restore->pages_compared); + pr_msg("Pages skipped COW: %" PRIu64 " (0x%" PRIx64 ")\n", stats->restore->pages_skipped_cow, + stats->restore->pages_skipped_cow); + if (stats->restore->has_pages_restored) + pr_msg("Pages restored: %" PRIu64 " (0x%" PRIx64 ")\n", stats->restore->pages_restored, + stats->restore->pages_restored); + pr_msg("Restore time: %d us\n", stats->restore->restore_time); + pr_msg("Forking time: %d us\n", stats->restore->forking_time); + } else + return; +} + void write_stats(int what) { StatsEntry stats = STATS_ENTRY__INIT; @@ -146,6 +179,9 @@ void write_stats(int what) pb_write_one(img, &stats, PB_STATS); close_image(img); } + + if (opts.display_stats) + display_stats(what, &stats); } int init_stats(int what)