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)  } -notrace static inline long vgetns(void) +notrace static inline u64 vgetsns(void)  {  	long v;  	cycles_t cycles; @@ -91,21 +91,24 @@ notrace static inline long vgetns(void)  	else  		return 0;  	v = (cycles - gtod->clock.cycle_last) & gtod->clock.mask; -	return (v * gtod->clock.mult) >> gtod->clock.shift; +	return v * gtod->clock.mult;  }  /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */  notrace static int __always_inline do_realtime(struct timespec *ts)  { -	unsigned long seq, ns; +	unsigned long seq; +	u64 ns;  	int mode; +	ts->tv_nsec = 0;  	do {  		seq = read_seqcount_begin(>od->seq);  		mode = gtod->clock.vclock_mode;  		ts->tv_sec = gtod->wall_time_sec; -		ts->tv_nsec = gtod->wall_time_nsec; -		ns = vgetns(); +		ns = gtod->wall_time_snsec; +		ns += vgetsns(); +		ns >>= gtod->clock.shift;  	} while (unlikely(read_seqcount_retry(>od->seq, seq)));  	timespec_add_ns(ts, ns); @@ -114,15 +117,18 @@ notrace static int __always_inline do_realtime(struct timespec *ts)  notrace static int do_monotonic(struct timespec *ts)  { -	unsigned long seq, ns; +	unsigned long seq; +	u64 ns;  	int mode; +	ts->tv_nsec = 0;  	do {  		seq = read_seqcount_begin(>od->seq);  		mode = gtod->clock.vclock_mode;  		ts->tv_sec = gtod->monotonic_time_sec; -		ts->tv_nsec = gtod->monotonic_time_nsec; -		ns = vgetns(); +		ns = gtod->monotonic_time_snsec; +		ns += vgetsns(); +		ns >>= gtod->clock.shift;  	} while (unlikely(read_seqcount_retry(>od->seq, seq)));  	timespec_add_ns(ts, ns);  |