[2/8] compel/std/uapi: Provide setter for gettimeofday()

Submitted by Dmitry Safonov on July 25, 2019, 10:01 p.m.

Details

Message ID 20190725220114.16977-3-dima@arista.com
State Accepted
Series "vdso: Use gettimeofday() from vdso for timings"
Headers show

Commit Message

Dmitry Safonov July 25, 2019, 10:01 p.m.
Provide a way to set gettimeofday() function for an infected task.
CRIU's parasite & restorer are very voluble as more logs are better
than lesser in terms of bug investigations.
In all modern kernels there is a way to get time without entering
kernel: vdso. So, add a way to reduce the cost of logging without making
it less valuable.

[I'm not particularly fond of std_log_set_gettimeofday() name, so
 if someone can come with a better naming - I'm up for a change]

Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 compel/plugins/include/uapi/std/log.h | 12 ++++++++++++
 compel/plugins/std/log.c              | 16 +++++++++++++++-
 2 files changed, 27 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/compel/plugins/include/uapi/std/log.h b/compel/plugins/include/uapi/std/log.h
index 7b27b12508c1..f21b6df0d943 100644
--- a/compel/plugins/include/uapi/std/log.h
+++ b/compel/plugins/include/uapi/std/log.h
@@ -8,6 +8,18 @@ 
 extern void std_log_set_fd(int fd);
 extern void std_log_set_loglevel(enum __compel_log_levels level);
 extern void std_log_set_start(struct timeval *tv);
+
+/*
+ * Provides a function to get time *in the infected task* for log timings.
+ * Expected use-case: address on the vdso page to get time.
+ * If not set or called with NULL - compel will use raw syscall,
+ * which requires enter in the kernel and as a result affects performance.
+ */
+typedef int (*gettimeofday_t)(struct timeval *tv, struct timezone *tz);
+extern void std_log_set_gettimeofday(gettimeofday_t gtod);
+/* std plugin helper to get time (hopefully, efficiently) */
+extern int std_gettimeofday(struct timeval *tv, struct timezone *tz);
+
 extern int std_vprint_num(char *buf, int blen, int num, char **ps);
 extern void std_sprintf(char output[STD_LOG_SIMPLE_CHUNK], const char *format, ...)
 	__attribute__ ((__format__ (__printf__, 2, 3)));
diff --git a/compel/plugins/std/log.c b/compel/plugins/std/log.c
index 06b9894aea38..f9be432ea835 100644
--- a/compel/plugins/std/log.c
+++ b/compel/plugins/std/log.c
@@ -16,6 +16,7 @@  struct simple_buf {
 static int logfd = -1;
 static int cur_loglevel = COMPEL_DEFAULT_LOGLEVEL;
 static struct timeval start;
+static gettimeofday_t __std_gettimeofday;
 
 static void sbuf_log_flush(struct simple_buf *b);
 
@@ -54,7 +55,7 @@  static void sbuf_log_init(struct simple_buf *b)
 	if (start.tv_sec != 0) {
 		struct timeval now;
 
-		sys_gettimeofday(&now, NULL);
+		std_gettimeofday(&now, NULL);
 		timediff(&start, &now);
 
 		/* Seconds */
@@ -130,6 +131,19 @@  void std_log_set_start(struct timeval *s)
 	start = *s;
 }
 
+void std_log_set_gettimeofday(gettimeofday_t gtod)
+{
+	__std_gettimeofday = gtod;
+}
+
+int std_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+	if (__std_gettimeofday != NULL)
+		return __std_gettimeofday(tv, tz);
+
+	return sys_gettimeofday(tv, tz);
+}
+
 static void print_string(const char *msg, struct simple_buf *b)
 {
 	while (*msg) {