I suspect that do_gettimeoffset() may be, on occasion,
returning a negative number. The normalizing code then
works with this (unsigned) value until it is < 1,000,000.
If it came back as -1, this would generate an error of about
1.19 hours. I suspect the best fix would be to test the
result from do_gettimeoffset() for something greater than
say 20ms and if so set it to 0.
-g
>
> I suspect that somehow the either do_gettimeoffset() or xtime.tv_usec in do_gettimeofday is returning a ridiculously large value. I would like to get to the bottom of this problem, but am not familiar with this part of the timing infrastructure. Has anyone seen this bug before? Would using a different locking mode (SMP vs none SMP, or wahtever) possibly help this problem? Is there a document online describing how this works in Linux?
>
> In the meantime, I want to hack up a patch to fix this on my box. I'm thinking I could give up a few seconds of clock precision in exchange for monotonic clock behavior, and so I want to comment out the adjustments to usec. What are the possible ramifications of this hack?
>
> Alan
>
> Original do_gettimeofday:
>
> void do_gettimeofday(struct timeval *tv)
> {
> unsigned long flags;
> unsigned long usec, sec;
>
> read_lock_irqsave(&xtime_lock, flags);
> usec = do_gettimeoffset();
> {
> unsigned long lost = jiffies - wall_jiffies;
> if (lost)
> usec += lost * (1000000 / HZ);
> }
> sec = xtime.tv_sec;
> usec += xtime.tv_usec;
> read_unlock_irqrestore(&xtime_lock, flags);
>
> while (usec >= 1000000) {
> usec -= 1000000;
> sec++;
> }
>
> tv->tv_sec = sec;
> tv->tv_usec = usec;
> }
>
> My proposed hack (for my system):
>
> void do_gettimeofday(struct timeval *tv)
> {
> unsigned long flags;
> unsigned long usec, sec;
>
> read_lock_irqsave(&xtime_lock, flags);
> usec = do_gettimeoffset();
> /* {
> unsigned long lost = jiffies - wall_jiffies;
> if (lost)
> usec += lost * (1000000 / HZ);
> } */
> sec = xtime.tv_sec;
> usec = xtime.tv_usec;
> read_unlock_irqrestore(&xtime_lock, flags);
>
> while (usec >= 1000000) {
> usec -= 1000000;
> sec++;
> }
>
> tv->tv_sec = sec;
> tv->tv_usec = usec;
> }
> -
> 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/
-- George Anzinger george@mvista.com High-res-timers: http://sourceforge.net/projects/high-res-timers/ Real time sched: http://sourceforge.net/projects/rtsched/ Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml - 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/