Generic part of an interface to allow debuggers to update time after having halted the system for perhaps extended periods of time. This generally requires arch-dependent changes, too, unless the arch- dependent time handling is already overflow-safe. Signed-Off-By: Jan Beulich Index: 2.6.14-nlkd/include/linux/jiffies.h =================================================================== --- 2.6.14-nlkd.orig/include/linux/jiffies.h 2005-11-09 10:40:17.000000000 +0100 +++ 2.6.14-nlkd/include/linux/jiffies.h 2005-11-04 16:19:34.000000000 +0100 @@ -83,6 +83,11 @@ */ extern u64 __jiffy_data jiffies_64; extern unsigned long volatile __jiffy_data jiffies; +#ifndef CONFIG_DEBUG_KERNEL +# define debugger_jiffies 0 +#else +extern u64 debugger_jiffies; +#endif #if (BITS_PER_LONG < 64) u64 get_jiffies_64(void); Index: 2.6.14-nlkd/kernel/timer.c =================================================================== --- 2.6.14-nlkd.orig/kernel/timer.c 2005-11-09 10:40:17.000000000 +0100 +++ 2.6.14-nlkd/kernel/timer.c 2005-11-07 15:20:27.000000000 +0100 @@ -46,6 +46,10 @@ static void time_interpolator_update(lon #define time_interpolator_update(x) #endif +#ifdef CONFIG_DEBUG_KERNEL +u64 debugger_jiffies; +#endif + /* * per-CPU timer vector definitions: */ @@ -935,6 +939,28 @@ static inline void update_times(void) ticks = jiffies - wall_jiffies; if (ticks) { wall_jiffies += ticks; +#ifndef debugger_jiffies + if (ticks > 1 + && debugger_jiffies + && jiffies_64 - debugger_jiffies > 1) { + u64 nsec64 = (u64)(ticks - 1) * tick_nsec; + unsigned long nsec = do_div(nsec64, NSEC_PER_SEC); + unsigned long sec = nsec64; + + if (sec > 0 + && xtime.tv_nsec + nsec + tick_nsec < NSEC_PER_SEC) { + /* Make sure xtime.tv_nsec exceeds a second when + checked (in update_wall_time). */ + sec--; + nsec += NSEC_PER_SEC; + } + xtime.tv_sec += sec; + xtime.tv_nsec += nsec; + touch_softlockup_watchdog(); + ticks = 1; + } + debugger_jiffies = 0; +#endif update_wall_time(ticks); } calc_load(ticks);