x86-64: Vclock_gettime(CLOCK_MONOTONIC) can't ever see nsec < 0
vclock_gettime's do_monotonic helper can't ever generate a negative nsec value, so it doesn't need to check whether it's negative. In the CLOCK_MONOTONIC_COARSE case, ns can't ever exceed 2e9-1, so we can avoid the loop entirely. This saves a single easily-predicted branch. Signed-off-by: Andy Lutomirski <luto@mit.edu> Cc: Andi Kleen <andi@firstfloor.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Borislav Petkov <bp@amd64.org> Link: http://lkml.kernel.org/r/%3Cd6d528d32c7a21618057cfc9005942a0fe5cb54a.1306156808.git.luto%40mit.edu%3E Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
3729db5ca2
commit
0f51f2852c
|
@ -55,22 +55,6 @@ notrace static noinline int do_realtime(struct timespec *ts)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Copy of the version in kernel/time.c which we cannot directly access */
|
||||
notrace static void
|
||||
vset_normalized_timespec(struct timespec *ts, long sec, long nsec)
|
||||
{
|
||||
while (nsec >= NSEC_PER_SEC) {
|
||||
nsec -= NSEC_PER_SEC;
|
||||
++sec;
|
||||
}
|
||||
while (nsec < 0) {
|
||||
nsec += NSEC_PER_SEC;
|
||||
--sec;
|
||||
}
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = nsec;
|
||||
}
|
||||
|
||||
notrace static noinline int do_monotonic(struct timespec *ts)
|
||||
{
|
||||
unsigned long seq, ns, secs;
|
||||
|
@ -81,7 +65,17 @@ notrace static noinline int do_monotonic(struct timespec *ts)
|
|||
secs += gtod->wall_to_monotonic.tv_sec;
|
||||
ns += gtod->wall_to_monotonic.tv_nsec;
|
||||
} while (unlikely(read_seqretry(>od->lock, seq)));
|
||||
vset_normalized_timespec(ts, secs, ns);
|
||||
|
||||
/* wall_time_nsec, vgetns(), and wall_to_monotonic.tv_nsec
|
||||
* are all guaranteed to be nonnegative.
|
||||
*/
|
||||
while (ns >= NSEC_PER_SEC) {
|
||||
ns -= NSEC_PER_SEC;
|
||||
++secs;
|
||||
}
|
||||
ts->tv_sec = secs;
|
||||
ts->tv_nsec = ns;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,7 +100,17 @@ notrace static noinline int do_monotonic_coarse(struct timespec *ts)
|
|||
secs += gtod->wall_to_monotonic.tv_sec;
|
||||
ns += gtod->wall_to_monotonic.tv_nsec;
|
||||
} while (unlikely(read_seqretry(>od->lock, seq)));
|
||||
vset_normalized_timespec(ts, secs, ns);
|
||||
|
||||
/* wall_time_nsec and wall_to_monotonic.tv_nsec are
|
||||
* guaranteed to be between 0 and NSEC_PER_SEC.
|
||||
*/
|
||||
if (ns >= NSEC_PER_SEC) {
|
||||
ns -= NSEC_PER_SEC;
|
||||
++secs;
|
||||
}
|
||||
ts->tv_sec = secs;
|
||||
ts->tv_nsec = ns;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue