Re: [PATCH] Re: time() glitch on 2.4.18: solved

Jim Paris (jim@jtan.com)
Tue, 5 Nov 2002 12:42:34 -0500


> BTW, why not trying to resync, with something like :
>
> if (count >= LATCH)
> count = (count >> 8) | inb(0x40) << 8;

That's best if we really are out of sync, but it's hard to tell. It
could be that the 8253's latch value got clobbered somehow, in which
case we definitely want to fix that or our timer interrupts will come
out at the wrong rate. We also still need to double-check that
count < LATCH after your code.

Unless we assume that an unpaired read is more common than having the
latch value clobbered in some other way, then I think just resetting
the counter should be okay. Since none of this _should_ ever happen
(but did on my system, grr), it's probably not worth making it too
complicated just to try to figure out what went wrong.

Updated patch with the printk and corrected conditional is below.

-jim

diff -urN linux-2.4.18/arch/i386/kernel/time.c linux-2.4.18-jim/arch/i386/kernel/time.c
--- linux-2.4.18/arch/i386/kernel/time.c Fri Mar 15 18:28:53 2002
+++ linux-2.4.18-jim/arch/i386/kernel/time.c Tue Nov 5 12:39:38 2002
@@ -501,6 +501,18 @@

count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
+
+ /* Any unpaired read will cause the above to swap MSB/LSB
+ forever. Try to detect this and reset the counter. */
+ if (count >= LATCH) {
+ printk(KERN_WARNING
+ "i8253 count too high! resetting..\n");
+ outb_p(0x34, 0x43);
+ outb_p(LATCH & 0xff, 0x40);
+ outb(LATCH >> 8, 0x40);
+ count = LATCH - 1;
+ }
+
spin_unlock(&i8253_lock);

count = ((LATCH-1) - count) * TICK_SIZE;
-
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/