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: macro@ds2.pg.gda.pl, 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;
|