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 */ _