aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/entry/vdso/vclock_gettime.c35
1 files changed, 7 insertions, 28 deletions
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
index 2c73e7f57316..1351b76638fb 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -205,35 +205,12 @@ notrace static inline u64 vgetsns(int *mode)
205 return v * gtod->mult; 205 return v * gtod->mult;
206} 206}
207 207
208/* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ 208notrace static int do_hres(clockid_t clk, struct timespec *ts)
209notrace static int __always_inline do_realtime(struct timespec *ts)
210{ 209{
211 struct vgtod_ts *base = &gtod->basetime[CLOCK_REALTIME]; 210 struct vgtod_ts *base = &gtod->basetime[clk];
212 unsigned int seq; 211 unsigned int seq;
213 u64 ns;
214 int mode; 212 int mode;
215
216 do {
217 seq = gtod_read_begin(gtod);
218 mode = gtod->vclock_mode;
219 ts->tv_sec = base->sec;
220 ns = base->nsec;
221 ns += vgetsns(&mode);
222 ns >>= gtod->shift;
223 } while (unlikely(gtod_read_retry(gtod, seq)));
224
225 ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
226 ts->tv_nsec = ns;
227
228 return mode;
229}
230
231notrace static int __always_inline do_monotonic(struct timespec *ts)
232{
233 struct vgtod_ts *base = &gtod->basetime[CLOCK_MONOTONIC];
234 unsigned int seq;
235 u64 ns; 213 u64 ns;
236 int mode;
237 214
238 do { 215 do {
239 seq = gtod_read_begin(gtod); 216 seq = gtod_read_begin(gtod);
@@ -278,11 +255,11 @@ notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
278{ 255{
279 switch (clock) { 256 switch (clock) {
280 case CLOCK_REALTIME: 257 case CLOCK_REALTIME:
281 if (do_realtime(ts) == VCLOCK_NONE) 258 if (do_hres(CLOCK_REALTIME, ts) == VCLOCK_NONE)
282 goto fallback; 259 goto fallback;
283 break; 260 break;
284 case CLOCK_MONOTONIC: 261 case CLOCK_MONOTONIC:
285 if (do_monotonic(ts) == VCLOCK_NONE) 262 if (do_hres(CLOCK_MONOTONIC, ts) == VCLOCK_NONE)
286 goto fallback; 263 goto fallback;
287 break; 264 break;
288 case CLOCK_REALTIME_COARSE: 265 case CLOCK_REALTIME_COARSE:
@@ -305,7 +282,9 @@ int clock_gettime(clockid_t, struct timespec *)
305notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) 282notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
306{ 283{
307 if (likely(tv != NULL)) { 284 if (likely(tv != NULL)) {
308 if (unlikely(do_realtime((struct timespec *)tv) == VCLOCK_NONE)) 285 struct timespec *ts = (struct timespec *) tv;
286
287 if (unlikely(do_hres(CLOCK_REALTIME, ts) == VCLOCK_NONE))
309 return vdso_fallback_gtod(tv, tz); 288 return vdso_fallback_gtod(tv, tz);
310 tv->tv_usec /= 1000; 289 tv->tv_usec /= 1000;
311 } 290 }