[CRIU] [PATCH 8/8] restorer: Use gettimeofday() from rt-vdso for log timings

Dmitry Safonov dima at arista.com
Fri Jul 26 01:01:14 MSK 2019


Omit calling raw syscalls and use vdso for the purpose of logging.
That will eliminate as much as one-syscall-per-PIE-message.
Getting time without switching to kernel will speed up C/R,
keeping logs as informative as they were.

Fixes: #346

I haven't enabled vdso timings for ia32 applications as it needs more
changes and complexity.. Maybe later.

Signed-off-by: Dmitry Safonov <dima at arista.com>
---
 criu/arch/aarch64/include/asm/vdso.h |  1 +
 criu/arch/arm/include/asm/vdso.h     |  1 +
 criu/arch/ppc64/include/asm/vdso.h   |  1 +
 criu/arch/s390/include/asm/vdso.h    |  3 +-
 criu/arch/x86/include/asm/vdso.h     |  3 +-
 criu/include/parasite-vdso.h         |  1 +
 criu/pie/parasite-vdso.c             | 59 +++++++++++++++++++++++++---
 criu/pie/restorer.c                  |  2 +
 8 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/criu/arch/aarch64/include/asm/vdso.h b/criu/arch/aarch64/include/asm/vdso.h
index a7802a279b83..8a65e0947cc4 100644
--- a/criu/arch/aarch64/include/asm/vdso.h
+++ b/criu/arch/aarch64/include/asm/vdso.h
@@ -10,6 +10,7 @@
  * we should support at the moment.
  */
 #define VDSO_SYMBOL_MAX		4
+#define VDSO_SYMBOL_GTOD	2
 
 /*
  * Workaround for VDSO array symbol table's relocation.
diff --git a/criu/arch/arm/include/asm/vdso.h b/criu/arch/arm/include/asm/vdso.h
index cf9d500bec75..f57790ac28f1 100644
--- a/criu/arch/arm/include/asm/vdso.h
+++ b/criu/arch/arm/include/asm/vdso.h
@@ -10,6 +10,7 @@
  * Poke from kernel file arch/arm/vdso/vdso.lds.S
  */
 #define VDSO_SYMBOL_MAX		2
+#define VDSO_SYMBOL_GTOD	1
 #define ARCH_VDSO_SYMBOLS			\
 	"__vdso_clock_gettime",		\
 	"__vdso_gettimeofday"
diff --git a/criu/arch/ppc64/include/asm/vdso.h b/criu/arch/ppc64/include/asm/vdso.h
index 9546e2460cf1..6c92348d6d40 100644
--- a/criu/arch/ppc64/include/asm/vdso.h
+++ b/criu/arch/ppc64/include/asm/vdso.h
@@ -13,6 +13,7 @@
  * inside the text page which should not be used as is from user space.
  */
 #define VDSO_SYMBOL_MAX		10
+#define VDSO_SYMBOL_GTOD	5
 #define ARCH_VDSO_SYMBOLS			\
 	"__kernel_clock_getres",		\
 	"__kernel_clock_gettime",		\
diff --git a/criu/arch/s390/include/asm/vdso.h b/criu/arch/s390/include/asm/vdso.h
index 63e7e046408e..c54d848ad242 100644
--- a/criu/arch/s390/include/asm/vdso.h
+++ b/criu/arch/s390/include/asm/vdso.h
@@ -8,7 +8,8 @@
  * This is a minimal amount of symbols
  * we should support at the moment.
  */
-#define VDSO_SYMBOL_MAX	4
+#define VDSO_SYMBOL_MAX		4
+#define VDSO_SYMBOL_GTOD	0
 
 /*
  * This definition is used in pie/util-vdso.c to initialize the vdso symbol
diff --git a/criu/arch/x86/include/asm/vdso.h b/criu/arch/x86/include/asm/vdso.h
index 046db2336c9c..28ae2d15a487 100644
--- a/criu/arch/x86/include/asm/vdso.h
+++ b/criu/arch/x86/include/asm/vdso.h
@@ -12,7 +12,8 @@
  * This is a minimal amount of symbols
  * we should support at the moment.
  */
-#define VDSO_SYMBOL_MAX	6
+#define VDSO_SYMBOL_MAX		6
+#define VDSO_SYMBOL_GTOD	2
 
 /*
  * XXX: we don't patch __kernel_vsyscall as it's too small:
diff --git a/criu/include/parasite-vdso.h b/criu/include/parasite-vdso.h
index 872105133ad8..9ee32f2a7ac2 100644
--- a/criu/include/parasite-vdso.h
+++ b/criu/include/parasite-vdso.h
@@ -81,6 +81,7 @@ static inline bool is_vdso_mark(void *addr)
 	return false;
 }
 
+extern void vdso_update_gtod_addr(struct vdso_maps *rt);
 extern int vdso_do_park(struct vdso_maps *rt, unsigned long park_at,
 			unsigned long park_size);
 extern int vdso_map_compat(unsigned long map_at);
diff --git a/criu/pie/parasite-vdso.c b/criu/pie/parasite-vdso.c
index be90090dee29..38da766804ab 100644
--- a/criu/pie/parasite-vdso.c
+++ b/criu/pie/parasite-vdso.c
@@ -12,7 +12,8 @@
 #include "int.h"
 #include "types.h"
 #include "page.h"
-#include <compel/plugins/std/syscall.h>
+#include "compel/plugins/std/syscall.h"
+#include "compel/plugins/std/log.h"
 #include "image.h"
 #include "parasite-vdso.h"
 #include "vma.h"
@@ -43,14 +44,62 @@ static int remap_one(char *who, unsigned long *from, unsigned long to, size_t si
 
 static int park_at(struct vdso_maps *rt, unsigned long vdso, unsigned long vvar)
 {
+	unsigned long vvar_size = rt->sym.vvar_size;
+	unsigned long vdso_size = rt->sym.vdso_size;
 	int ret;
 
-	ret = remap_one("rt-vdso", &rt->vdso_start, vdso, rt->sym.vdso_size);
-
-	if (ret || !vvar)
+	ret = remap_one("rt-vdso", &rt->vdso_start, vdso, vdso_size);
+	if (ret)
 		return ret;
 
-	return remap_one("rt-vvar", &rt->vvar_start, vvar, rt->sym.vvar_size);
+	std_log_set_gettimeofday(NULL); /* stop using vdso for timings */
+
+	if (vvar)
+		ret = remap_one("rt-vvar", &rt->vvar_start, vvar, vvar_size);
+
+	if (!ret)
+		vdso_update_gtod_addr(rt);
+
+	return ret;
+}
+
+void vdso_update_gtod_addr(struct vdso_maps *rt)
+{
+	struct vdso_symbol *gtod_sym;
+	void *gtod;
+
+	if (rt->vdso_start == VDSO_BAD_ADDR) {
+		pr_debug("No rt-vdso - no fast gettimeofday()\n");
+		return;
+	}
+
+	if (VDSO_SYMBOL_GTOD < 0) {
+		pr_debug("Arch doesn't support gettimeofday() from vdso\n");
+		return;
+	}
+
+	/*
+	 * XXX: Don't enable vdso timings for compatible applications.
+	 * We would need to temporary map 64-bit vdso for timings in restorer
+	 * and remap it with compatible at the end of restore.
+	 * And vdso proxification should be done much later.
+	 * Also, restorer should have two sets of vdso_maps in arguments.
+	 */
+	if (rt->compatible) {
+		pr_debug("compat mode: using syscall for gettimeofday()\n");
+		return;
+	}
+
+	gtod_sym = &rt->sym.symbols[VDSO_SYMBOL_GTOD];
+	if (gtod_sym->offset == VDSO_BAD_ADDR) {
+		pr_debug("No gettimeofday() on rt-vdso\n");
+		return;
+	}
+
+	gtod = (void*)(rt->vdso_start + gtod_sym->offset);
+	pr_info("Using gettimeofday() on vdso at %p\n", gtod);
+
+	std_log_set_gettimeofday(gtod);
 }
 
 /*
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 9d49a831373b..4fff2c85d070 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1402,6 +1402,8 @@ long __export_restore_task(struct task_restore_args *args)
 	if (args->can_map_vdso && (map_vdso(args, args->compatible_mode) < 0))
 		goto core_restore_end;
 
+	vdso_update_gtod_addr(&args->vdso_maps_rt);
+
 	/* Shift private vma-s to the left */
 	for (i = 0; i < args->vmas_n; i++) {
 		vma_entry = args->vmas + i;
-- 
2.22.0



More information about the CRIU mailing list