Commit 9d64273c authored by David Mosberger's avatar David Mosberger Committed by Linus Torvalds

[PATCH] time-offset patch

On ia64 MP machines, we use the cycle counter register of each CPU to
obtain fine-grained time-stamps.  At boot-time, we synchronize the
counters as close as possible (similar to x86, though with a different
algorithm).  But even with this synchronization, there is still a
small (really: tiny) chance that a process bouncing from one CPU to
another could observe time going backwards.  To guard against this, I
maintain a global variable called "last_time_offset" which keeps track
of the largest time-interpolation value returned so far.  Most of this
is in platform-specific code (arch/ia64/kernel/time.c), but there are
a handful of places in platform-independent code where this variable
needs to be cleared to zero.  This is what the patch below does.  I
didn't put it inside CONFIG_IA64 because I think this can be useful
for other platforms, too.  I suppose I could put it inside CONFIG_SMP
though this would make the code uglier.  If you think it's OK, please
apply, otherwise, I'd appreciate your feedback.
parent 5d29ce55
......@@ -39,6 +39,7 @@ struct timezone sys_tz;
/* The xtime_lock is not only serializing the xtime read/writes but it's also
serializing all accesses to the global NTP variables now. */
extern rwlock_t xtime_lock;
extern unsigned long last_time_offset;
#if !defined(__alpha__) && !defined(__ia64__)
......@@ -82,6 +83,7 @@ asmlinkage long sys_stime(int * tptr)
write_lock_irq(&xtime_lock);
xtime.tv_sec = value;
xtime.tv_usec = 0;
last_time_offset = 0;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
......@@ -127,6 +129,7 @@ inline static void warp_clock(void)
{
write_lock_irq(&xtime_lock);
xtime.tv_sec += sys_tz.tz_minuteswest * 60;
last_time_offset = 0;
write_unlock_irq(&xtime_lock);
}
......@@ -386,6 +389,7 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
txc->calcnt = pps_calcnt;
txc->errcnt = pps_errcnt;
txc->stbcnt = pps_stbcnt;
last_time_offset = 0;
write_unlock_irq(&xtime_lock);
do_gettimeofday(&txc->time);
return(result);
......
......@@ -630,6 +630,7 @@ unsigned long wall_jiffies;
* This spinlock protect us from races in SMP while playing with xtime. -arca
*/
rwlock_t xtime_lock = RW_LOCK_UNLOCKED;
unsigned long last_time_offset;
static inline void update_times(void)
{
......@@ -647,6 +648,7 @@ static inline void update_times(void)
wall_jiffies += ticks;
update_wall_time(ticks);
}
last_time_offset = 0;
write_unlock_irq(&xtime_lock);
calc_load(ticks);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment