Re: [patch] jiffies wraparound [Re: 2.1.125 Show stopper list: Draft]

Andrea Arcangeli (andrea@e-mind.com)
Fri, 16 Oct 1998 20:53:03 +0200 (CEST)


On Fri, 16 Oct 1998, Andrea Arcangeli wrote:

>>I don't think the patched kernel is happy. I've been playing with some

You should have CONFIG_APM enabled to been able to boot the kernel...

The same here (now that I can boot too). The tty stop responding when
jiffies wrap. SysRQ keys works though. The hd seems slow too.

>It' s not. I catched very big problems in the do_fast_gettimeoffset() at
>least. In such function the jiffies static initialization change cause
>problems (just fixed also in other arch).

This part of the new jiffies-5 patch should fix the get_fast_timeoffset()
jiffies wrap bug (extracted from the now patch and posted to the list to
allow more people to complain). Note that JIFFIES_OFFSET should be set to
0 for production. My patch set it to -120*HZ _only_ to allow catching wrap
bugs.

Index: linux/arch/i386/kernel/time.c
diff -u linux/arch/i386/kernel/time.c:1.1.1.1 linux/arch/i386/kernel/time.c:1.1.1.1.14.1
--- linux/arch/i386/kernel/time.c:1.1.1.1 Fri Oct 2 19:23:36 1998
+++ linux/arch/i386/kernel/time.c Fri Oct 16 20:41:23 1998
@@ -53,6 +53,13 @@
unsigned long high;
} init_timer_cc, last_timer_cc;

+static void __init_timer_cc(void)
+{
+ __asm__("rdtsc"
+ :"=a" (init_timer_cc.low),
+ "=d" (init_timer_cc.high));
+}
+
static unsigned long do_fast_gettimeoffset(void)
{
register unsigned long eax asm("ax");
@@ -68,12 +75,12 @@
*/
static unsigned long cached_quotient=0;

- tmp = jiffies;
+ tmp = jiffies - JIFFIES_OFFSET;

quotient = cached_quotient;
low_timer = last_timer_cc.low;

- if (last_jiffies != tmp) {
+ if (tmp && last_jiffies != tmp) {
last_jiffies = tmp;

/* Get last timer tick in absolute kernel time */
@@ -110,7 +117,7 @@
}

/* Read the time counter */
- __asm__("rdtsc" : "=a" (eax), "=d" (edx));
+ __asm__("rdtsc" : "=a" (eax) : : "edx");

/* .. relative to previous jiffy (32 bits is enough) */
edx = 0;
@@ -191,7 +198,7 @@
* We do this guaranteed double memory access instead of a _p
* postfix in the previous port access. Wheee, hackady hack
*/
- jiffies_t = jiffies;
+ jiffies_t = jiffies - JIFFIES_OFFSET;

count |= inb_p(0x40) << 8;

@@ -380,6 +387,7 @@
static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_timer(regs);
+
/*
* In the SMP case we use the local APIC timer interrupt to do the
* profiling, except when we simulate SMP mode on a uniprocessor
@@ -444,6 +452,14 @@
:"=a" (last_timer_cc.low),
"=d" (last_timer_cc.high));
timer_interrupt(irq, NULL, regs);
+
+ if (!(jiffies - JIFFIES_OFFSET))
+ /*
+ * If jiffies has overflowed in this timer_interrupt we must
+ * update the init_timer_cc to make the do_fast_gettimeoffset()
+ * quotient calc still valid. -arca
+ */
+ __init_timer_cc();
}
#endif

@@ -552,9 +568,7 @@
}

/* read Pentium cycle counter */
- __asm__("rdtsc"
- :"=a" (init_timer_cc.low),
- "=d" (init_timer_cc.high));
+ __init_timer_cc();
irq0.handler = pentium_timer_interrupt;
}
#endif

>Seems that such function cause a div_by_zero fault if run when jiffies ==
>0 if I understand well this:
>
>(divl %2) == (dx:ax / %2)

Yes was so.

>Unfortunately I had not time to understand what do_fast_gettimeoffset()
>does, I was going to work on it now.

This new patch (that include the time.c patch over and the sd.c fix)
allow me to boot and everything is fine as far jiffies doesn' t wrap. I
had not time to understand what' s happening to the tty driver. I' ll try
to work on it tomorrow...

ftp://e-mind.com/pub/linux/kernel-patches/jiffies-5....

Andrea Arcangeli

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