Re: time jumps (again)

From: Andries Brouwer (aebr@win.tue.nl)
Date: Mon Aug 04 2003 - 20:08:48 EST


> Tim Schmielau wrote:

> >>What happens: when doing a
> >> $ while true; do date; done
> >>I'm noticing time jumps _exactly_ at the beginning of a "new" second (or
> >>at the end of an "old" one). the jump is exactly 4294 (4295) seconds
> >>into the future. Example:
> >>...
> >>Mon Aug 4 18:11:06 CEST 2003
> >>Mon Aug 4 19:22:41 CEST 2003
> >>Mon Aug 4 18:11:07 CEST 2003
> >>...

> >--- linux-2.4.20/arch/i386/kernel/time.c.orig Mon Aug 4 23:38:47 2003
> >+++ linux-2.4.20/arch/i386/kernel/time.c Mon Aug 4 23:40:53 2003
> >@@ -274,8 +274,8 @@
> > read_lock_irqsave(&xtime_lock, flags);
> > usec = do_gettimeoffset();
> > {
> >- unsigned long lost = jiffies - wall_jiffies;
> >- if (lost)
> >+ long lost = jiffies - wall_jiffies;
> >+ if (lost>0)
> > usec += lost * (1000000 / HZ);
> > }
> > sec = xtime.tv_sec;

At first sight jiffies and wall_jiffies increase monotonically, and
wall_jiffies always has a value jiffies had a moment earlier, so the
difference jiffies - wall_jiffies ought to be nonnegative.

On the other hand, do_gettimeoffset() is a much more obscure function,
and the jumps are also explained if that can return a negative value.

Depending on CONFIG_X86_TSC it does do_slow_gettimeoffset or
do_fast_gettimeoffset. Both offer plenty of opportunities to
return a negative value. Things depend on hardware details.

So, instead of adding a test inside { } I would propose to catch
problems after the {}, e.g. by
        if (usec < 0)
                usec = 0;

There should be a clue in the fact that the jump happens at the
start of a new second. I don't know what it is.

Andries

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 07 2003 - 22:00:26 EST