From: Tim Schmielau <tim@physik3.uni-rostock.de>

Force jiffies to start out at five-minutes-before-wrap.  To find
jiffy-wrapping bugs.



 alpha/kernel/time.c     |    2 +-
 arm/kernel/time.c       |    2 +-
 cris/kernel/time.c      |    2 +-
 i386/kernel/time.c      |    2 +-
 ia64/kernel/time.c      |    2 +-
 m68k/kernel/time.c      |    2 +-
 m68knommu/kernel/time.c |    2 +-
 mips/kernel/time.c      |    2 +-
 parisc/kernel/time.c    |    2 +-
 ppc/kernel/time.c       |    2 +-
 ppc64/kernel/time.c     |    2 +-
 s390/kernel/time.c      |    2 +-
 s390x/kernel/time.c     |    2 +-
 sh/kernel/time.c        |    2 +-
 sparc/kernel/time.c     |    2 +-
 sparc64/kernel/time.c   |    2 +-
 v850/kernel/time.c      |    2 +-
 x86_64/kernel/time.c    |    2 +-
 proc/array.c            |    3 ++-
 proc/proc_misc.c        |    4 ++--
 linux/time.h            |    6 ++++++
 timer.c                 |   11 +++++++++--
 22 files changed, 37 insertions(+), 23 deletions(-)

diff -puN arch/alpha/kernel/time.c~initial-jiffies arch/alpha/kernel/time.c
--- 25/arch/alpha/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/alpha/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -50,7 +50,7 @@
 #include "proto.h"
 #include "irq_impl.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern unsigned long wall_jiffies;	/* kernel/timer.c */
 
diff -puN arch/arm/kernel/time.c~initial-jiffies arch/arm/kernel/time.c
--- 25/arch/arm/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/arm/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -32,7 +32,7 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern unsigned long wall_jiffies;
 
diff -puN arch/cris/kernel/time.c~initial-jiffies arch/cris/kernel/time.c
--- 25/arch/cris/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/cris/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -45,7 +45,7 @@
 
 #include <asm/svinto.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static int have_rtc;  /* used to remember if we have an RTC or not */
 
diff -puN arch/i386/kernel/time.c~initial-jiffies arch/i386/kernel/time.c
--- 25/arch/i386/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/i386/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -66,7 +66,7 @@ int pit_latch_buggy;              /* ext
 
 #include "do_timer.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
 
diff -puN arch/ia64/kernel/time.c~initial-jiffies arch/ia64/kernel/time.c
--- 25/arch/ia64/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/ia64/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -27,7 +27,7 @@
 extern unsigned long wall_jiffies;
 extern unsigned long last_time_offset;
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 #ifdef CONFIG_IA64_DEBUG_IRQ
 
diff -puN arch/m68k/kernel/time.c~initial-jiffies arch/m68k/kernel/time.c
--- 25/arch/m68k/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/m68k/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -26,7 +26,7 @@
 #include <linux/timex.h>
 #include <linux/profile.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
diff -puN arch/m68knommu/kernel/time.c~initial-jiffies arch/m68knommu/kernel/time.c
--- 25/arch/m68knommu/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/m68knommu/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -26,7 +26,7 @@
 
 #define	TICK_SIZE (tick_nsec / 1000)
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
diff -puN arch/mips/kernel/time.c~initial-jiffies arch/mips/kernel/time.c
--- 25/arch/mips/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/mips/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -32,7 +32,7 @@
 #define USECS_PER_JIFFY (1000000/HZ)
 #define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 /*
  * forward reference
diff -puN arch/parisc/kernel/time.c~initial-jiffies arch/parisc/kernel/time.c
--- 25/arch/parisc/kernel/time.c~initial-jiffies	2003-02-16 20:38:57.000000000 -0800
+++ 25-akpm/arch/parisc/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -32,7 +32,7 @@
 
 #include <linux/timex.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 /* xtime and wall_jiffies keep wall-clock time */
 extern unsigned long wall_jiffies;
diff -puN arch/ppc64/kernel/time.c~initial-jiffies arch/ppc64/kernel/time.c
--- 25/arch/ppc64/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/ppc64/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -65,7 +65,7 @@
 
 void smp_local_timer_interrupt(struct pt_regs *);
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
diff -puN arch/ppc/kernel/time.c~initial-jiffies arch/ppc/kernel/time.c
--- 25/arch/ppc/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/ppc/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -68,7 +68,7 @@
 #include <asm/time.h>
 
 /* XXX false sharing with below? */
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 unsigned long disarm_decr[NR_CPUS];
 
diff -puN arch/s390/kernel/time.c~initial-jiffies arch/s390/kernel/time.c
--- 25/arch/s390/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/s390/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -46,7 +46,7 @@
 
 #define TICK_SIZE tick
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static ext_int_info_t ext_int_info_timer;
 static uint64_t xtime_cc;
diff -puN arch/s390x/kernel/time.c~initial-jiffies arch/s390x/kernel/time.c
--- 25/arch/s390x/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/s390x/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -45,7 +45,7 @@
 
 #define TICK_SIZE tick
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static ext_int_info_t ext_int_info_timer;
 static uint64_t xtime_cc;
diff -puN arch/sh/kernel/time.c~initial-jiffies arch/sh/kernel/time.c
--- 25/arch/sh/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/sh/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -70,7 +70,7 @@
 #endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
 #endif /* __sh3__ or __SH4__ */
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern unsigned long wall_jiffies;
 #define TICK_SIZE tick
diff -puN arch/sparc64/kernel/time.c~initial-jiffies arch/sparc64/kernel/time.c
--- 25/arch/sparc64/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/sparc64/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -47,7 +47,7 @@ unsigned long ds1287_regs = 0UL;
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static unsigned long mstk48t08_regs = 0UL;
 static unsigned long mstk48t59_regs = 0UL;
diff -puN arch/sparc/kernel/time.c~initial-jiffies arch/sparc/kernel/time.c
--- 25/arch/sparc/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/sparc/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -45,7 +45,7 @@
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 enum sparc_clock_type sp_clock_typ;
 spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
diff -puN arch/v850/kernel/time.c~initial-jiffies arch/v850/kernel/time.c
--- 25/arch/v850/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/v850/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -25,7 +25,7 @@
 
 #include "mach.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 #define TICK_SIZE	(tick_nsec / 1000)
 
diff -puN arch/x86_64/kernel/time.c~initial-jiffies arch/x86_64/kernel/time.c
--- 25/arch/x86_64/kernel/time.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/arch/x86_64/kernel/time.c	2003-02-16 20:38:58.000000000 -0800
@@ -30,7 +30,7 @@
 #include <asm/apic.h>
 #endif
 
-u64 jiffies_64; 
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern int using_apic_timer;
 
diff -puN fs/proc/array.c~initial-jiffies fs/proc/array.c
--- 25/fs/proc/array.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/fs/proc/array.c	2003-02-16 20:38:58.000000000 -0800
@@ -358,7 +358,8 @@ int proc_pid_stat(struct task_struct *ta
 		nice,
 		0UL /* removed */,
 		jiffies_to_clock_t(task->it_real_value),
-		(unsigned long long) jiffies_64_to_clock_t(task->start_time),
+		(unsigned long long)
+		    jiffies_64_to_clock_t(task->start_time - INITIAL_JIFFIES),
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
 		task->rlim[RLIMIT_RSS].rlim_cur,
diff -puN fs/proc/proc_misc.c~initial-jiffies fs/proc/proc_misc.c
--- 25/fs/proc/proc_misc.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/fs/proc/proc_misc.c	2003-02-16 20:38:58.000000000 -0800
@@ -104,7 +104,7 @@ static int uptime_read_proc(char *page, 
 	unsigned long uptime_remainder;
 	int len;
 
-	uptime = get_jiffies_64();
+	uptime = get_jiffies_64() - INITIAL_JIFFIES;
 	uptime_remainder = (unsigned long) do_div(uptime, HZ);
 
 #if HZ!=100
@@ -320,7 +320,7 @@ static int kstat_read_proc(char *page, c
 {
 	int i, len;
 	extern unsigned long total_forks;
-	u64 jif = get_jiffies_64();
+	u64 jif = get_jiffies_64() - INITIAL_JIFFIES;
 	unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0;
 
 	for (i = 0 ; i < NR_CPUS; i++) {
diff -puN include/linux/time.h~initial-jiffies include/linux/time.h
--- 25/include/linux/time.h~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/include/linux/time.h	2003-02-16 20:38:58.000000000 -0800
@@ -28,6 +28,12 @@ struct timezone {
 #include <linux/seqlock.h>
 
 /*
+ * Have the 32 bit jiffies value wrap 5 minutes after boot
+ * so jiffies wrap bugs show up earlier.
+ */
+#define INITIAL_JIFFIES (-1UL & (unsigned long)(-300*HZ))
+
+/*
  * Change timeval to jiffies, trying to avoid the
  * most obvious overflows..
  *
diff -puN kernel/timer.c~initial-jiffies kernel/timer.c
--- 25/kernel/timer.c~initial-jiffies	2003-02-16 20:38:58.000000000 -0800
+++ 25-akpm/kernel/timer.c	2003-02-16 20:38:58.000000000 -0800
@@ -755,7 +755,7 @@ static inline void calc_load(unsigned lo
 }
 
 /* jiffies at the most recent update of wall time */
-unsigned long wall_jiffies;
+unsigned long wall_jiffies = INITIAL_JIFFIES;
 
 /*
  * This read-write spinlock protects us from races in SMP while
@@ -1098,7 +1098,7 @@ asmlinkage long sys_sysinfo(struct sysin
 	do {
 		seq = read_seqbegin(&xtime_lock);
 
-		uptime = jiffies_64;
+		uptime = jiffies_64 - INITIAL_JIFFIES;
 		do_div(uptime, HZ);
 		val.uptime = (unsigned long) uptime;
 
@@ -1174,6 +1174,13 @@ static void __devinit init_timers_cpu(in
 	}
 	for (j = 0; j < TVR_SIZE; j++)
 		INIT_LIST_HEAD(base->tv1.vec + j);
+
+	base->timer_jiffies = INITIAL_JIFFIES;
+	base->tv1.index = INITIAL_JIFFIES & TVR_MASK;
+	base->tv2.index = (INITIAL_JIFFIES >> TVR_BITS) & TVN_MASK;
+	base->tv3.index = (INITIAL_JIFFIES >> (TVR_BITS+TVN_BITS)) & TVN_MASK;
+	base->tv4.index = (INITIAL_JIFFIES >> (TVR_BITS+2*TVN_BITS)) & TVN_MASK;
+	base->tv5.index = (INITIAL_JIFFIES >> (TVR_BITS+3*TVN_BITS)) & TVN_MASK;
 }
 	
 static int __devinit timer_cpu_notify(struct notifier_block *self, 

_