diff options
| -rw-r--r-- | arch/x86/entry/vdso/vclock_gettime.c | 35 |
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. */ | 208 | notrace static int do_hres(clockid_t clk, struct timespec *ts) |
| 209 | notrace static int __always_inline do_realtime(struct timespec *ts) | ||
| 210 | { | 209 | { |
| 211 | struct vgtod_ts *base = >od->basetime[CLOCK_REALTIME]; | 210 | struct vgtod_ts *base = >od->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 | |||
| 231 | notrace static int __always_inline do_monotonic(struct timespec *ts) | ||
| 232 | { | ||
| 233 | struct vgtod_ts *base = >od->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 *) | |||
| 305 | notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) | 282 | notrace 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 | } |
