[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