Index: linux-2.6/arch/ia64/kernel/time.c =================================================================== --- linux-2.6.orig/arch/ia64/kernel/time.c 2005-08-12 11:13:00.684615342 -0700 +++ linux-2.6/arch/ia64/kernel/time.c 2005-08-18 15:04:46.981381332 -0700 @@ -55,6 +55,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned long new_itm; + unsigned long itc; if (unlikely(cpu_is_offline(smp_processor_id()))) { return IRQ_HANDLED; @@ -64,10 +65,20 @@ new_itm = local_cpu_data->itm_next; - if (!time_after(ia64_get_itc(), new_itm)) + itc = ia64_get_itc(); + if (!time_after(itc, new_itm)) printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); + /* If time skipped more than half a second then freeze time instead of repeatedly + * calling the timer interrupt. This will avoid timeouts by devices + */ + if (time_after(itc, new_itm + HZ /2 * local_cpu_data->itm_delta)) { + new_itm = itc - local_cpu_data->itm_delta; + time_interpolator_reset(); + printk(KERN_CRIT "More than half a second between timer ticks. Time frozen to prevent timeouts.\n"); + } + profile_tick(CPU_PROFILING, regs); while (1) {