blob: ce290e9783668797b9d48f8221532cb9e1870209 [file] [log] [blame]
From 137118f73bcc5a97d742749627bbf72264deb785 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Fri, 3 Jul 2009 08:44:00 -0500
Subject: [PATCH] x86: GTOD: offer scalable vgettimeofday
commit 4b10b24a38155ecba8d585788b846119ae689a1b in tip.
offer scalable vgettimeofday independently of whether the TSC
is synchronous or not. Off by default.
this patch also fixes an SMP bug in sys_vtime(): we should read
__vsyscall_gtod_data.wall_time_tv.tv_sec only once.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 6520c37..00f768f 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -125,6 +125,25 @@ static __always_inline void do_vgettimeofday(struct timeval * tv)
unsigned seq;
unsigned long mult, shift, nsec;
cycle_t (*vread)(void);
+
+ if (likely(__vsyscall_gtod_data.sysctl_enabled == 2)) {
+ struct timeval tmp;
+
+ do {
+ barrier();
+ tv->tv_sec = __vsyscall_gtod_data.wall_time_sec;
+ tv->tv_usec = __vsyscall_gtod_data.wall_time_nsec;
+ barrier();
+ tmp.tv_sec = __vsyscall_gtod_data.wall_time_sec;
+ tmp.tv_usec = __vsyscall_gtod_data.wall_time_nsec;
+
+ } while (tmp.tv_usec != tv->tv_usec ||
+ tmp.tv_sec != tv->tv_sec);
+
+ tv->tv_usec /= NSEC_PER_USEC;
+ return;
+ }
+
do {
seq = read_raw_seqbegin(&__vsyscall_gtod_data.lock);
--
1.7.1.1