diff options
Diffstat (limited to 'arch/x86/vdso/vclock_gettime.c')
-rw-r--r-- | arch/x86/vdso/vclock_gettime.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index 885eff49d6a..4df6c373421 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c | |||
@@ -80,7 +80,7 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | 82 | ||
83 | notrace static inline long vgetns(void) | 83 | notrace static inline u64 vgetsns(void) |
84 | { | 84 | { |
85 | long v; | 85 | long v; |
86 | cycles_t cycles; | 86 | cycles_t cycles; |
@@ -91,21 +91,24 @@ notrace static inline long vgetns(void) | |||
91 | else | 91 | else |
92 | return 0; | 92 | return 0; |
93 | v = (cycles - gtod->clock.cycle_last) & gtod->clock.mask; | 93 | v = (cycles - gtod->clock.cycle_last) & gtod->clock.mask; |
94 | return (v * gtod->clock.mult) >> gtod->clock.shift; | 94 | return v * gtod->clock.mult; |
95 | } | 95 | } |
96 | 96 | ||
97 | /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ | 97 | /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ |
98 | notrace static int __always_inline do_realtime(struct timespec *ts) | 98 | notrace static int __always_inline do_realtime(struct timespec *ts) |
99 | { | 99 | { |
100 | unsigned long seq, ns; | 100 | unsigned long seq; |
101 | u64 ns; | ||
101 | int mode; | 102 | int mode; |
102 | 103 | ||
104 | ts->tv_nsec = 0; | ||
103 | do { | 105 | do { |
104 | seq = read_seqcount_begin(>od->seq); | 106 | seq = read_seqcount_begin(>od->seq); |
105 | mode = gtod->clock.vclock_mode; | 107 | mode = gtod->clock.vclock_mode; |
106 | ts->tv_sec = gtod->wall_time_sec; | 108 | ts->tv_sec = gtod->wall_time_sec; |
107 | ts->tv_nsec = gtod->wall_time_nsec; | 109 | ns = gtod->wall_time_snsec; |
108 | ns = vgetns(); | 110 | ns += vgetsns(); |
111 | ns >>= gtod->clock.shift; | ||
109 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); | 112 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); |
110 | 113 | ||
111 | timespec_add_ns(ts, ns); | 114 | timespec_add_ns(ts, ns); |
@@ -114,15 +117,18 @@ notrace static int __always_inline do_realtime(struct timespec *ts) | |||
114 | 117 | ||
115 | notrace static int do_monotonic(struct timespec *ts) | 118 | notrace static int do_monotonic(struct timespec *ts) |
116 | { | 119 | { |
117 | unsigned long seq, ns; | 120 | unsigned long seq; |
121 | u64 ns; | ||
118 | int mode; | 122 | int mode; |
119 | 123 | ||
124 | ts->tv_nsec = 0; | ||
120 | do { | 125 | do { |
121 | seq = read_seqcount_begin(>od->seq); | 126 | seq = read_seqcount_begin(>od->seq); |
122 | mode = gtod->clock.vclock_mode; | 127 | mode = gtod->clock.vclock_mode; |
123 | ts->tv_sec = gtod->monotonic_time_sec; | 128 | ts->tv_sec = gtod->monotonic_time_sec; |
124 | ts->tv_nsec = gtod->monotonic_time_nsec; | 129 | ns = gtod->monotonic_time_snsec; |
125 | ns = vgetns(); | 130 | ns += vgetsns(); |
131 | ns >>= gtod->clock.shift; | ||
126 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); | 132 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); |
127 | timespec_add_ns(ts, ns); | 133 | timespec_add_ns(ts, ns); |
128 | 134 | ||