diff options
| -rw-r--r-- | arch/i386/kernel/time.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 4db7f942440f..5a8183a31eea 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -266,6 +266,41 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg } /* + * Lost tick detection and compensation + */ +static inline void detect_lost_tick(void) +{ + /* read time since last interrupt */ + unsigned long delta = timer->get_offset(); + static unsigned long dbg_print; + + /* check if delta is greater then two ticks */ + if(delta >= 2*(1000000/HZ)){ + + /* + * only print debug info first 5 times + */ + /* + * AKPM: disable this for now; it's nice, but irritating. + */ + if (0 && dbg_print < 5) { + printk(KERN_WARNING "\nWarning! Detected %lu " + "micro-second gap between interrupts.\n", + delta); + printk(KERN_WARNING " Compensating for %lu lost " + "ticks.\n", + delta/(1000000/HZ)-1); + dump_stack(); + dbg_print++; + } + /* calculate number of missed ticks */ + delta = delta/(1000000/HZ)-1; + jiffies += delta; + } + +} + +/* * This is the same as the above, except we _also_ save the current * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. @@ -281,6 +316,7 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ write_lock(&xtime_lock); + detect_lost_tick(); timer->mark_offset(); do_timer_interrupt(irq, NULL, regs); |
