

Catch people doing init_timer() on a pending timer.


 include/linux/timer.h    |   14 +-------------
 kernel/fork.c            |    1 +
 kernel/ksyms.c           |    1 +
 kernel/timer.c           |   31 +++++++++++++++++++++++++++++++
 net/ipv4/tcp_minisocks.c |    1 +
 5 files changed, 35 insertions(+), 13 deletions(-)

diff -puN include/linux/timer.h~init_timer-debug-trap include/linux/timer.h
--- 25/include/linux/timer.h~init_timer-debug-trap	2003-06-27 14:18:21.000000000 -0700
+++ 25-akpm/include/linux/timer.h	2003-06-27 14:18:21.000000000 -0700
@@ -31,19 +31,7 @@ struct timer_list {
 		.lock = SPIN_LOCK_UNLOCKED,			\
 	}
 
-/***
- * init_timer - initialize a timer.
- * @timer: the timer to be initialized
- *
- * init_timer() must be done to a timer prior calling *any* of the
- * other timer functions.
- */
-static inline void init_timer(struct timer_list * timer)
-{
-	timer->base = NULL;
-	timer->magic = TIMER_MAGIC;
-	spin_lock_init(&timer->lock);
-}
+void init_timer(struct timer_list *timer);
 
 /***
  * timer_pending - is a timer pending?
diff -puN kernel/timer.c~init_timer-debug-trap kernel/timer.c
--- 25/kernel/timer.c~init_timer-debug-trap	2003-06-27 14:18:21.000000000 -0700
+++ 25-akpm/kernel/timer.c	2003-06-27 14:18:21.000000000 -0700
@@ -1303,3 +1303,34 @@ unregister_time_interpolator(struct time
 	spin_unlock(&time_interpolator_lock);
 }
 #endif /* CONFIG_TIME_INTERPOLATION */
+
+/***
+ * init_timer - initialize a timer.
+ * @timer: the timer to be initialized
+ *
+ * init_timer() must be done to a timer prior calling *any* of the
+ * other timer functions.
+ */
+void init_timer(struct timer_list *timer)
+{
+	static int whine_count;
+
+	if (timer_pending(timer) && timer->magic == TIMER_MAGIC &&
+				whine_count < 10) {
+		int i;
+
+		for (i = 0; i < NR_CPUS; i++) {
+			if (timer->base == &per_cpu(tvec_bases, i))
+				break;
+		}
+		if (i < NR_CPUS) {
+			whine_count++;
+			printk("%s: timer is pending!\n", __FUNCTION__);
+			dump_stack();
+		}
+	}
+
+	timer->base = NULL;
+	timer->magic = TIMER_MAGIC;
+	spin_lock_init(&timer->lock);
+}
diff -puN kernel/ksyms.c~init_timer-debug-trap kernel/ksyms.c
--- 25/kernel/ksyms.c~init_timer-debug-trap	2003-06-27 14:18:21.000000000 -0700
+++ 25-akpm/kernel/ksyms.c	2003-06-27 14:18:21.000000000 -0700
@@ -622,3 +622,4 @@ EXPORT_SYMBOL(ptrace_notify);
 EXPORT_SYMBOL(console_printk);
 
 EXPORT_SYMBOL(current_kernel_time);
+EXPORT_SYMBOL(init_timer);
diff -puN kernel/fork.c~init_timer-debug-trap kernel/fork.c
--- 25/kernel/fork.c~init_timer-debug-trap	2003-06-27 14:18:21.000000000 -0700
+++ 25-akpm/kernel/fork.c	2003-06-27 14:18:21.000000000 -0700
@@ -880,6 +880,7 @@ struct task_struct *copy_process(unsigne
 
 	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
 	p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
+	p->real_timer.base = NULL;	/* avoid false positive */
 	init_timer(&p->real_timer);
 	p->real_timer.data = (unsigned long) p;
 
diff -puN net/ipv4/tcp_minisocks.c~init_timer-debug-trap net/ipv4/tcp_minisocks.c
--- 25/net/ipv4/tcp_minisocks.c~init_timer-debug-trap	2003-06-27 14:18:21.000000000 -0700
+++ 25-akpm/net/ipv4/tcp_minisocks.c	2003-06-27 14:18:21.000000000 -0700
@@ -680,6 +680,7 @@ struct sock *tcp_create_openreq_child(st
 		struct sk_filter *filter;
 
 		memcpy(newsk, sk, sizeof(struct tcp_sock));
+		newsk->sk_timer.base = NULL;
 		newsk->sk_state = TCP_SYN_RECV;
 
 		/* SANITY */

_
