aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/vdso/vclock_gettime.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/vdso/vclock_gettime.c')
-rw-r--r--arch/x86/vdso/vclock_gettime.c22
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
83notrace static inline long vgetns(void) 83notrace 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. */
98notrace static int __always_inline do_realtime(struct timespec *ts) 98notrace 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(&gtod->seq); 106 seq = read_seqcount_begin(&gtod->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(&gtod->seq, seq))); 112 } while (unlikely(read_seqcount_retry(&gtod->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
115notrace static int do_monotonic(struct timespec *ts) 118notrace 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(&gtod->seq); 126 seq = read_seqcount_begin(&gtod->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(&gtod->seq, seq))); 132 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
127 timespec_add_ns(ts, ns); 133 timespec_add_ns(ts, ns);
128 134