Messages in this thread | | | Date | Tue, 5 Aug 2003 03:08:48 +0200 | From | Andries Brouwer <> | Subject | Re: time jumps (again) |
| |
> 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/
| |