Hi, I am test out a simple schedule_timeout() code. When I insert the module kernel goes in a infinite loop printing this in the log : Jul 6 22:04:35 ubuntupc kernel: [ 5738.281659] Pid: 0, comm: swapper Not tainted 2.6.35-22-generic #33-Ubuntu Jul 6 22:04:35 ubuntupc kernel: [ 5738.281663] Call Trace: Jul 6 22:04:35 ubuntupc kernel: [ 5738.281671] [<ffffffff8104d15a>] dequeue_task_idle+0x3a/0x50 Jul 6 22:04:35 ubuntupc kernel: [ 5738.281679] [<ffffffff81052d6a>] dequeue_task+0x9a/0xb0 Jul 6 22:04:35 ubuntupc kernel: [ 5738.281687] [<ffffffff81052dae>] deactivate_task+0x2e/0x40 Jul 6 22:04:35 ubuntupc kernel: [ 5738.281693] [<ffffffff81586ba9>] schedule+0x4a9/0x830 Jul 6 22:04:35 ubuntupc kernel: [ 5738.281702] [<ffffffff81008ddb>] cpu_idle+0xeb/0x110 Jul 6 22:04:35 ubuntupc kernel: [ 5738.281710] [<ffffffff815832ad>] start_secondary+0x100/0x102 Any ideas on what is going on ? ---------------------------------- <testmod.c> ---------------------------------- #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/timer.h> #include <linux/delay.h> #include <linux/sched.h> struct timer_list tim; void timfunc(unsigned long data) { printk("hi this is a timer %lu\n", data); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(10 * HZ); printk("hi again this is a timer after timeout %lu\n", data); } static int __init init_testmod(void) { init_timer(&tim); tim.expires = jiffies + HZ*5; tim.data = 1000; tim.function = timfunc; add_timer(&tim); return 0; } static void __exit exit_testmod(void) { printk("end of module\n"); return; } module_init(init_testmod); module_exit(exit_testmod); MODULE_LICENSE("GPL"); ------------------------------ </testmod.c> ---------------------------------- ---------------------------------- <Makefile> ---------------------------------- obj-m += testmod.o KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions depend .depend dep: $(CC) $(CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) include .depend endif ---------------------------------- </Makefile> ----------------------------------
Hello Prashant,
struct timer_list tim;
void timfunc(unsigned long data) { [..] schedule_timeout(10 * HZ); [..] }
static int __init init_testmod(void) { init_timer(&tim); tim.expires = jiffies + HZ*5; tim.data = 1000; tim.function = timfunc; add_timer(&tim); return 0; }
You can find here ([1]) a good source for documenting on kernel timers API. Basically, the kernel has a list with registered timers and runs the associated handlers when timeout expires. Looking at your code, you've initialized the timer but you didn't added it to kernel timers list. You can find here a simple example of how to setup a timer ([2]). Please read this [3], and figure out why even after you'll correctly setup the timer, your timer handler will cause you trouble. thanks, Daniel. [1] http://www.ibm.com/developerworks/linux/library/l-timers-list/index.html [2] http://lxr.linux.no/linux+v2.6.39/arch/blackfin/kernel/nmi.c#L176 [3] http://www.kernel.org/pub/linux/kernel/people/rusty/kernel-locking/c557.html
On Wed, Jul 6, 2011 at 11:48 PM, Daniel Baluta <daniel.baluta@gmail.com> wrote:
Hello Prashant,
struct timer_list tim;
void timfunc(unsigned long data) { [..] schedule_timeout(10 * HZ); [..] }
static int __init init_testmod(void) { init_timer(&tim); tim.expires = jiffies + HZ*5; tim.data = 1000; tim.function = timfunc; add_timer(&tim); return 0; }
You can find here ([1]) a good source for documenting on kernel timers API.
Basically, the kernel has a list with registered timers and runs the associated handlers when timeout expires.
Looking at your code, you've initialized the timer but you didn't added it to kernel timers list.
You can find here a simple example of how to setup a timer ([2]).
Oh, so it seems you called add_timer :D, I just missed it. Then the problem is the one pointed below (schedule_timeout called in interrupt context).
Please read this [3], and figure out why even after you'll correctly setup the timer, your timer handler will cause you trouble.
Hi, On Thu, Jul 7, 2011 at 2:48 PM, Daniel Baluta <daniel.baluta@gmail.com> wrote:
On Wed, Jul 6, 2011 at 11:48 PM, Daniel Baluta <daniel.baluta@gmail.com> wrote:
Hello Prashant,
is the one pointed below (schedule_timeout called in interrupt context).
Yes indeed ! the call to in_interrupt() returns 256 Thanks.
Hi.. Trying to add another perspective, feel free to take or not :) On Wed, Jul 6, 2011 at 23:52, Prashant Shah <pshah.mumbai@gmail.com> wrote:
void timfunc(unsigned long data) { printk("hi this is a timer %lu\n", data); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(10 * HZ); printk("hi again this is a timer after timeout %lu\n", data); }
static int __init init_testmod(void) { init_timer(&tim); tim.expires = jiffies + HZ*5; tim.data = 1000; tim.function = timfunc; add_timer(&tim); return 0; }
If my brain still works correctly, then I think the core of the problem is that you're doing schedule() inside timer function. The thing is, timer function is running in bottom halves...or in other word, you are not supposed to do that in interrupt-handler alike function. What you need to do in order to wake up ten minutes later (10*HZ) is to reinsert the function and make it expire 10*HZ later. Just my 2 cents :) -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
On Thu, Jul 7, 2011 at 12:19 PM, Mulyadi Santosa <mulyadi.santosa@gmail.com> wrote:
Hi..
Trying to add another perspective, feel free to take or not :)
On Wed, Jul 6, 2011 at 23:52, Prashant Shah <pshah.mumbai@gmail.com> wrote:
void timfunc(unsigned long data) { printk("hi this is a timer %lu\n", data); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(10 * HZ); printk("hi again this is a timer after timeout %lu\n", data); }
static int __init init_testmod(void) { init_timer(&tim); tim.expires = jiffies + HZ*5; tim.data = 1000; tim.function = timfunc; add_timer(&tim); return 0; }
If my brain still works correctly, then I think the core of the problem is that you're doing schedule() inside timer function. The thing is, timer function is running in bottom halves...or in other word, you are not supposed to do that in interrupt-handler alike function.
What you need to do in order to wake up ten minutes later (10*HZ) is
10*HZ is for 10 mins or for 10 seconds?
to reinsert the function and make it expire 10*HZ later.
Just my 2 cents :)
-- regards,
Mulyadi Santosa Freelance Linux trainer and consultant
blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Thu, Jul 7, 2011 at 13:58, Vishal Thanki <vishalthanki@gmail.com> wrote:
On Thu, Jul 7, 2011 at 12:19 PM, Mulyadi Santosa <mulyadi.santosa@gmail.com> wrote:
Hi..
Trying to add another perspective, feel free to take or not :)
On Wed, Jul 6, 2011 at 23:52, Prashant Shah <pshah.mumbai@gmail.com> wrote:
void timfunc(unsigned long data) { printk("hi this is a timer %lu\n", data); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(10 * HZ); printk("hi again this is a timer after timeout %lu\n", data); }
static int __init init_testmod(void) { init_timer(&tim); tim.expires = jiffies + HZ*5; tim.data = 1000; tim.function = timfunc; add_timer(&tim); return 0; }
If my brain still works correctly, then I think the core of the problem is that you're doing schedule() inside timer function. The thing is, timer function is running in bottom halves...or in other word, you are not supposed to do that in interrupt-handler alike function.
What you need to do in order to wake up ten minutes later (10*HZ) is
10*HZ is for 10 mins or for 10 seconds?
whoops sorry, it should be 10*HZ=10 seconds...thanks for noticing the error :) -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
participants (4)
-
Daniel Baluta -
Mulyadi Santosa -
Prashant Shah -
Vishal Thanki