H. Peter Anvin | 1965aae | 2008-10-22 22:26:29 -0700 | [diff] [blame] | 1 | #ifndef _ASM_X86_VGTOD_H |
| 2 | #define _ASM_X86_VGTOD_H |
Andi Kleen | 2aae950 | 2007-07-21 17:10:01 +0200 | [diff] [blame] | 3 | |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 4 | #include <linux/compiler.h> |
Andi Kleen | 2aae950 | 2007-07-21 17:10:01 +0200 | [diff] [blame] | 5 | #include <linux/clocksource.h> |
| 6 | |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 7 | #ifdef BUILD_VDSO32_64 |
| 8 | typedef u64 gtod_long_t; |
| 9 | #else |
| 10 | typedef unsigned long gtod_long_t; |
| 11 | #endif |
| 12 | /* |
| 13 | * vsyscall_gtod_data will be accessed by 32 and 64 bit code at the same time |
| 14 | * so be carefull by modifying this structure. |
| 15 | */ |
Andi Kleen | 2aae950 | 2007-07-21 17:10:01 +0200 | [diff] [blame] | 16 | struct vsyscall_gtod_data { |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 17 | unsigned seq; |
Andi Kleen | 2aae950 | 2007-07-21 17:10:01 +0200 | [diff] [blame] | 18 | |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 19 | int vclock_mode; |
| 20 | cycle_t cycle_last; |
| 21 | cycle_t mask; |
| 22 | u32 mult; |
| 23 | u32 shift; |
Andy Lutomirski | 91ec87d | 2012-03-22 21:15:51 -0700 | [diff] [blame] | 24 | |
| 25 | /* open coded 'struct timespec' */ |
John Stultz | 650ea02 | 2012-09-04 16:14:46 -0400 | [diff] [blame] | 26 | u64 wall_time_snsec; |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 27 | gtod_long_t wall_time_sec; |
| 28 | gtod_long_t monotonic_time_sec; |
John Stultz | 650ea02 | 2012-09-04 16:14:46 -0400 | [diff] [blame] | 29 | u64 monotonic_time_snsec; |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 30 | gtod_long_t wall_time_coarse_sec; |
| 31 | gtod_long_t wall_time_coarse_nsec; |
| 32 | gtod_long_t monotonic_time_coarse_sec; |
| 33 | gtod_long_t monotonic_time_coarse_nsec; |
Andy Lutomirski | 91ec87d | 2012-03-22 21:15:51 -0700 | [diff] [blame] | 34 | |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 35 | int tz_minuteswest; |
| 36 | int tz_dsttime; |
Andi Kleen | 2aae950 | 2007-07-21 17:10:01 +0200 | [diff] [blame] | 37 | }; |
Andi Kleen | 2aae950 | 2007-07-21 17:10:01 +0200 | [diff] [blame] | 38 | extern struct vsyscall_gtod_data vsyscall_gtod_data; |
| 39 | |
Stefani Seibold | 7c03156 | 2014-03-17 23:22:10 +0100 | [diff] [blame^] | 40 | static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s) |
| 41 | { |
| 42 | unsigned ret; |
| 43 | |
| 44 | repeat: |
| 45 | ret = ACCESS_ONCE(s->seq); |
| 46 | if (unlikely(ret & 1)) { |
| 47 | cpu_relax(); |
| 48 | goto repeat; |
| 49 | } |
| 50 | smp_rmb(); |
| 51 | return ret; |
| 52 | } |
| 53 | |
| 54 | static inline int gtod_read_retry(const struct vsyscall_gtod_data *s, |
| 55 | unsigned start) |
| 56 | { |
| 57 | smp_rmb(); |
| 58 | return unlikely(s->seq != start); |
| 59 | } |
| 60 | |
| 61 | static inline void gtod_write_begin(struct vsyscall_gtod_data *s) |
| 62 | { |
| 63 | ++s->seq; |
| 64 | smp_wmb(); |
| 65 | } |
| 66 | |
| 67 | static inline void gtod_write_end(struct vsyscall_gtod_data *s) |
| 68 | { |
| 69 | smp_wmb(); |
| 70 | ++s->seq; |
| 71 | } |
| 72 | |
H. Peter Anvin | 1965aae | 2008-10-22 22:26:29 -0700 | [diff] [blame] | 73 | #endif /* _ASM_X86_VGTOD_H */ |