Subject: [patch] More time fixes: do_gettimeofday() & do_settimeofday()

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 1 Aug 2003 14:04:29 +0200 (MET DST)

Hello,

 Here are fixes for do_gettimeofday() and do_settimeofday() not taking the
wall time and the value of tick properly into account.  OK to apply? 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email-masked], PGP key available        +

patch-mips-2.4.21-20030725-mips-timeofday-0
diff -up --recursive --new-file linux-mips-2.4.21-20030725.macro/arch/mips/kernel/time.c linux-mips-2.4.21-20030725/arch/mips/kernel/time.c
--- linux-mips-2.4.21-20030725.macro/arch/mips/kernel/time.c	2003-07-25 02:56:34.000000000 +0000
+++ linux-mips-2.4.21-20030725/arch/mips/kernel/time.c	2003-07-31 21:27:18.000000000 +0000
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/time.h>
+#include <linux/timex.h>
 #include <linux/smp.h>
 #include <linux/kernel_stat.h>
 #include <linux/spinlock.h>
@@ -70,22 +71,23 @@ int (*rtc_set_mmss)(unsigned long);
  */
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags;
+	unsigned long flags, lost;
 
 	read_lock_irqsave(&xtime_lock, flags);
+
 	*tv = xtime;
 	tv->tv_usec += do_gettimeoffset();
-
 	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
+	 * xtime is atomically updated in timer_bh.  jiffies - wall_jiffies
+	 * is nonzero if the timer bottom half hasn't executed yet.
 	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+	lost = jiffies - wall_jiffies;
+	if (lost)
+		tv->tv_usec += lost * tick;
 
 	read_unlock_irqrestore(&xtime_lock, flags);
 
-	if (tv->tv_usec >= 1000000) {
+	while (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
 		tv->tv_sec++;
 	}
@@ -95,18 +97,20 @@ void do_settimeofday(struct timeval *tv)
 {
 	write_lock_irq(&xtime_lock);
 
-	/* This is revolting. We need to set the xtime.tv_usec
-	 * correctly. However, the value in this location is
-	 * is value at the last tick.
-	 * Discover what correction gettimeofday
-	 * would have done, and then undo it!
+	/*
+	 * This is revolting.  We need to set "xtime" correctly.  However,
+	 * the value in this location is the value at the most recent update
+	 * of wall time.  Discover what correction gettimeofday() would have
+	 * done, and then undo it!
 	 */
 	tv->tv_usec -= do_gettimeoffset();
+	tv->tv_usec -= (jiffies - wall_jiffies) * tick;
 
-	if (tv->tv_usec < 0) {
+	while (tv->tv_usec < 0) {
 		tv->tv_usec += 1000000;
 		tv->tv_sec--;
 	}
+
 	xtime = *tv;
 	time_adjust = 0;			/* stop active adjtime() */
 	time_status |= STA_UNSYNC;

---

From: Jun Sun <[email-masked]>
Date: Fri, 1 Aug 2003 10:24:43 -0700

> wall time and the value of tick properly into account.  OK to apply? 

That looks right to me.  I have fixed them internally, but never get around
to push into the linux-mips tree.

To be nit-picking, I might want to replace 'tick' with 'USECS_PER_JIFFY'.

Jun

---

From: Ralf Baechle <[email-masked]>
Date: Sat, 2 Aug 2003 19:05:42 +0200

> wall time and the value of tick properly into account.  OK to apply? 

Yes, looks good.  One user less of USECS_PER_JIFFY ...

  Ralf

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 4 Aug 2003 16:29:06 +0200 (MET DST)

> To be nit-picking, I might want to replace 'tick' with 'USECS_PER_JIFFY'.

 OK -- since I want to keep USECS_PER_JIFFY_FRAC as otherwise
unrecoverable, I decided to keep USECS_PER_JIFFY as well for consistency. 
But that's only after (or together with) the next patch.

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 4 Aug 2003 16:31:19 +0200 (MET DST)

> Yes, looks good.  One user less of USECS_PER_JIFFY ...

 Actually, I decided to keep USECS_PER_JIFFY, only redefining it more
sanely.