diff options
Diffstat (limited to 'arch/x86/include/asm/vgtod.h')
-rw-r--r-- | arch/x86/include/asm/vgtod.h | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index 46e24d36b7da..3c3366c2e37f 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h | |||
@@ -1,30 +1,73 @@ | |||
1 | #ifndef _ASM_X86_VGTOD_H | 1 | #ifndef _ASM_X86_VGTOD_H |
2 | #define _ASM_X86_VGTOD_H | 2 | #define _ASM_X86_VGTOD_H |
3 | 3 | ||
4 | #include <asm/vsyscall.h> | 4 | #include <linux/compiler.h> |
5 | #include <linux/clocksource.h> | 5 | #include <linux/clocksource.h> |
6 | 6 | ||
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 | */ | ||
7 | struct vsyscall_gtod_data { | 16 | struct vsyscall_gtod_data { |
8 | seqcount_t seq; | 17 | unsigned seq; |
9 | 18 | ||
10 | struct { /* extract of a clocksource struct */ | 19 | int vclock_mode; |
11 | int vclock_mode; | 20 | cycle_t cycle_last; |
12 | cycle_t cycle_last; | 21 | cycle_t mask; |
13 | cycle_t mask; | 22 | u32 mult; |
14 | u32 mult; | 23 | u32 shift; |
15 | u32 shift; | ||
16 | } clock; | ||
17 | 24 | ||
18 | /* open coded 'struct timespec' */ | 25 | /* open coded 'struct timespec' */ |
19 | time_t wall_time_sec; | ||
20 | u64 wall_time_snsec; | 26 | u64 wall_time_snsec; |
27 | gtod_long_t wall_time_sec; | ||
28 | gtod_long_t monotonic_time_sec; | ||
21 | u64 monotonic_time_snsec; | 29 | u64 monotonic_time_snsec; |
22 | time_t monotonic_time_sec; | 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; | ||
23 | 34 | ||
24 | struct timezone sys_tz; | 35 | int tz_minuteswest; |
25 | struct timespec wall_time_coarse; | 36 | int tz_dsttime; |
26 | struct timespec monotonic_time_coarse; | ||
27 | }; | 37 | }; |
28 | extern struct vsyscall_gtod_data vsyscall_gtod_data; | 38 | extern struct vsyscall_gtod_data vsyscall_gtod_data; |
29 | 39 | ||
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 | |||
30 | #endif /* _ASM_X86_VGTOD_H */ | 73 | #endif /* _ASM_X86_VGTOD_H */ |