]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] time-offset patch
authorDavid Mosberger <davidm@napali.hpl.hp.com>
Fri, 31 May 2002 04:13:19 +0000 (21:13 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 31 May 2002 04:13:19 +0000 (21:13 -0700)
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.

kernel/time.c
kernel/timer.c

index 05a005c3a012459d539da531abb8f2ea99cf5e65..edb7eb7b8b73f05ae8e98a4fa3c21ae8707016e1 100644 (file)
@@ -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);
index 5175ebf0bf321423279b57bf81153d35cf05f6fc..62a36b5740a77c59f46e553368d91ae1868825a4 100644 (file)
@@ -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);
 }