Commit 5c38b5da authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] gettimeofday resolution fix

From: Stephen Hemminger <shemminger@osdl.org>

The original problem all this is solving is that when NTP is slowing the clock
there existed real cases where time appeared to go backwards. Assuming NTP was
slowing the clock, then it would update the xtime by 999us at the next timer interrupt.
If a program read time three times:

A:	    xtime = t0
B: A+1000   xtime = t0 + 1000
C: B+1	    xtime = t0 + 999

To behave correctly C > B > A; but we were returning C < B

The code does have bug if we are losing clock interrupts.  The test for
lost interrupts needs to be after the interval clamp.
parent d4680c6f
......@@ -94,6 +94,7 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long seq;
unsigned long usec, sec;
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
unsigned long lost;
......@@ -102,16 +103,20 @@ void do_gettimeofday(struct timeval *tv)
usec = cur_timer->get_offset();
lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
/*
* If time_adjust is negative then NTP is slowing the clock
* so make sure not to go into next possible interval.
* Better to lose some accuracy than have time go backwards..
*/
if (unlikely(time_adjust < 0) && usec > tickadj)
usec = tickadj;
if (unlikely(time_adjust < 0)) {
usec = min(usec, max_ntp_tick);
if (lost)
usec += lost * max_ntp_tick;
}
else if (unlikely(lost))
usec += lost * tick_usec;
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment