The patch titled When CONFIG_BASE_SAMLL=1, cascade() may enter an infinite loop has been added to the -mm tree. Its filename is when-config_base_samll=1-the-kernel-261611-cascade-in-kernel-timerc-may-enter-the-infinite-loop.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this From: Porpoise <porpoise.chiang@xxxxxxxxx> When CONFIG_BASE_SAMLL=1, cascade() in may enter the infinite loop. Because of CONFIG_BASE_SMALL=1(TVR_BITS=6 and TVN_BITS=4), the list base->tv5 may cascade into base->tv5. So, the kernel enters the infinite loop in the function cascade(). I created a test module to verify this bug, and a patch to fix it. #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/timer.h> #if 0 #include <linux/kdb.h> #else #define kdb_printf printk #endif #define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6) #define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8) #define TVN_SIZE (1 << TVN_BITS) #define TVR_SIZE (1 << TVR_BITS) #define TVN_MASK (TVN_SIZE - 1) #define TVR_MASK (TVR_SIZE - 1) #define TV_SIZE(N) (N*TVN_BITS + TVR_BITS) struct timer_list timer0; struct timer_list dummy_timer1; struct timer_list dummy_timer2; void dummy_timer_fun(unsigned long data) { } unsigned long j=0; void check_timer_base(unsigned long data) { kdb_printf("check_timer_base %08x\n",jiffies); mod_timer(&timer0,(jiffies & (~0xFFF)) + 0x1FFF); } int init_module(void) { init_timer(&timer0); timer0.data = (unsigned long)0; timer0.function = check_timer_base; mod_timer(&timer0,jiffies+1); init_timer(&dummy_timer1); dummy_timer1.data = (unsigned long)0; dummy_timer1.function = dummy_timer_fun; init_timer(&dummy_timer2); dummy_timer2.data = (unsigned long)0; dummy_timer2.function = dummy_timer_fun; j=jiffies; j&=(~((1<<TV_SIZE(3))-1)); j+=(1<<TV_SIZE(3)); j+=(1<<TV_SIZE(4)); kdb_printf("mod_timer %08x\n",j); mod_timer(&dummy_timer1, j ); mod_timer(&dummy_timer2, j ); return 0; } void cleanup_module() { del_timer_sync(&timer0); del_timer_sync(&dummy_timer1); del_timer_sync(&dummy_timer2); } Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: Matt Mackall <mpm@xxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- kernel/timer.c | 30 +++++++++++++++++++++++++++++- 1 files changed, 29 insertions(+), 1 deletion(-) diff -puN kernel/timer.c~when-config_base_samll=1-the-kernel-261611-cascade-in-kernel-timerc-may-enter-the-infinite-loop kernel/timer.c --- devel/kernel/timer.c~when-config_base_samll=1-the-kernel-261611-cascade-in-kernel-timerc-may-enter-the-infinite-loop 2006-05-08 10:52:35.000000000 -0700 +++ devel-akpm/kernel/timer.c 2006-05-08 10:52:35.000000000 -0700 @@ -380,6 +380,34 @@ int del_timer_sync(struct timer_list *ti EXPORT_SYMBOL(del_timer_sync); #endif +#if (CONFIG_BASE_SMALL != 0) +static int cascade_safe(tvec_base_t *base, tvec_t *tv, int index) +{ + /* cascade all the timers from tv up one level */ + struct list_head *head, *curr; + struct list_head dummy_head; + + head = tv->vec + index; + + list_add(&dummy_head,head); + list_del_init(head); + + curr = dummy_head.next; + while (curr != &dummy_head) { + struct timer_list *tmp; + + tmp = list_entry(curr, struct timer_list, entry); + BUG_ON(tmp->base != &base->t_base); + curr = curr->next; + internal_add_timer(base, tmp); + } + + return index; +} +#else +#define cascade_safe(base,tv,index) cascade(base,tv,index) +#endif + static int cascade(tvec_base_t *base, tvec_t *tv, int index) { /* cascade all the timers from tv up one level */ @@ -430,7 +458,7 @@ static inline void __run_timers(tvec_bas (!cascade(base, &base->tv2, INDEX(0))) && (!cascade(base, &base->tv3, INDEX(1))) && !cascade(base, &base->tv4, INDEX(2))) - cascade(base, &base->tv5, INDEX(3)); + cascade_safe(base, &base->tv5, INDEX(3)); ++base->timer_jiffies; list_splice_init(base->tv1.vec + index, &work_list); while (!list_empty(head)) { _ Patches currently in -mm which might be from porpoise.chiang@xxxxxxxxx are when-config_base_samll=1-the-kernel-261611-cascade-in-kernel-timerc-may-enter-the-infinite-loop.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html