| 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 |
| |