ashutosh mehra
2007-Nov-02 20:59 UTC
[Xen-devel] Trouble with xenbus_write in a timer handler
Hi, I made a module which intends to periodically update the value of a node in xenstore, using xenstore_write(...). The xenstore_write() call was working fine when I put it in init_module(), but when I put it in a timer handler, it makes the module crash (causes a kernel oops and the system reboot. (dom0 or domU depending on where I insmod it). What could be the problem here? This is the source code: #include <linux/init.h> #include <linux/module.h> #include <linux/uio.h> #include <linux/kernel.h> #include <linux/syscalls.h> #include <linux/timer.h> #include <asm-i386/param.h> #include <xen/xenbus.h> struct timer_list freememupdate_timer; int delay = 5 * HZ; void freememupdate_handler(unsigned long data) { // Get free system memory char freemembuf[33]=""; long freemem; int cnt = 0; int i, ret; struct sysinfo info; printk(KERN_INFO "freememupdate_handler called\n"); si_meminfo(&info); freemem = info.freeram * info.mem_unit; //sprintf(freemembuf, "%ld", freemem); while(freemem > 0) { int a = freemem % 10; freemembuf[cnt++] = (char) (a + ''0''); freemem /= 10; } freemembuf[cnt]=''\0''; for(i=0; i<cnt/2; i++) freemembuf[i] = freemembuf[cnt-i-1]; ret = xenbus_write(XBT_NIL, "memory", "freemem", "12345"); // <--- MAKES THE MODULE CRASH AND THE SYSTEM REBOOT //printk("Ret val: %d, Freemem: %ld, Freemembuf: %s\n", ret, freemem, freemembuf); //add_timer(&freememupdate_timer); } static int init() { printk("Init 1\n"); init_timer(&freememupdate_timer); freememupdate_timer.expires = jiffies + delay; freememupdate_timer.data = 0; freememupdate_timer.function = freememupdate_handler; printk("Init 2\n"); add_timer(&freememupdate_timer); printk("Init 3\n"); return 0; } static void clean_up() { printk("Cleanup"); del_timer(&freememupdate_timer); printk(KERN_ALERT "Module ended"); } module_init(init); module_exit(clean_up); MODULE_LICENSE("GPL"); klogd messages: Nov 2 20:10:59 guest kernel: Init 1 Nov 2 20:10:59 guest kernel: Init 2 Nov 2 20:10:59 guest kernel: Init 3 BUG: scheduling while atomic: swapper/0x00000100/0 bad: scheduling from the idle thread! BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000 printing eip: 0704d000 -> *pde = 00000000:14e0f001 086cc000 -> *pme = 00000000:00000000 Oops: 0002 [#1] SMP Modules linked in: xenfreememupdate evdev 8250 serial_core processor ext3 jbd CPU: 0 EIP: 0061:[<c011ae52>] Not tainted VLI EFLAGS: 00010082 (2.6.18-xen #2) EIP is at dequeue_task+0x12/0x50 eax: c034d2c0 ebx: c034d2e8 ecx: c034d2c0 edx: 00000000 esi: 00000000 edi: c03afe30 ebp: c03afd6c esp: c03afd64 ds: 007b es: 007b ss: 0069 Process swapper (pid: 0, ti=c03ae000 task=c034d2c0 task.ti=c03ae000) Stack: c034d2c0 c034d3e4 c03afd78 c011aefa c14e4a00 c03afdf4 c02f74bf c0313de0 c034d46c 00000100 00000000 c011afb9 00000000 00000001 00000001 c034d2c0 c034fd6c 91c1623f 00000080 01cc5f58 c034d3e4 c14e4a00 00000000 00000001 Call Trace: [<c011aefa>] deactivate_task+0x1a/0x30 [<c02f74bf>] schedule+0x48f/0x920 [<c011afb9>] __wake_up_common+0x39/0x60 [<c0249a39>] xb_write+0xa9/0x210 [<c0138a10>] prepare_to_wait+0x20/0x70 [<c0249f85>] read_reply+0x75/0xf0 [<c0138860>] autoremove_wake_function+0x0/0x50 [<c024a131>] xs_talkv+0xa1/0x180 [<c024a529>] xenbus_write+0x79/0xa0 [<c902410a>] freememupdate_handler+0x5a/0x84 [xenfreememupdate] [<c013bce5>] hrtimer_run_queues+0xc5/0x1b0 [<c012dfbb>] run_timer_softirq+0x13b/0x1f0 [<c90240b0>] freememupdate_handler+0x0/0x84 [xenfreememupdate] [<c0128a52>] __do_softirq+0x92/0x130 [<c0128b69>] do_softirq+0x79/0x80 [<c0107344>] do_IRQ+0x44/0xa0 [<c02441fe>] evtchn_do_upcall+0xbe/0x100 [<c010581d>] hypervisor_callback+0x3d/0x45 [<c0108b1a>] raw_safe_halt+0x9a/0x120 [<c0104439>] xen_idle+0x29/0x50 [<c010359d>] cpu_idle+0x6d/0xc0 [<c03b4835>] start_kernel+0x3a5/0x480 [<c03b4220>] unknown_bootoption+0x0/0x270 Code: b9 01 00 00 00 29 d0 89 c2 c1 ea 1f 01 c2 d1 fa 85 d2 5d 0f 4f ca 89 c8 c3 55 89 e5 83 ec 08 89 1c 24 Corresponding ksysoops output:>>EIP; c011ae52 <dequeue_task+12/50> <==== >>eax; c034d2c0 <init_task+0/580> >>ebx; c034d2e8 <init_task+28/580> >>ecx; c034d2c0 <init_task+0/580> >>edi; c03afe30 <init_thread_union+1e30/2000> >>ebp; c03afd6c <init_thread_union+1d6c/2000> >>esp; c03afd64 <init_thread_union+1d64/2000>Trace; c011aefa <deactivate_task+1a/30> Trace; c02f74bf <schedule+48f/920> Trace; c011afb9 <__wake_up_common+39/60> Trace; c0249a39 <xb_write+a9/210> Trace; c0138a10 <prepare_to_wait+20/70> Trace; c0249f85 <read_reply+75/f0> Trace; c0138860 <autoremove_wake_function+0/50> Trace; c024a131 <xs_talkv+a1/180> Trace; c024a529 <xenbus_write+79/a0> Trace; c902410a <__crc_prepare_to_wait+12161f/22aedb> Trace; c013bce5 <hrtimer_run_queues+c5/1b0> Trace; c012dfbb <run_timer_softirq+13b/1f0> Trace; c90240b0 <__crc_prepare_to_wait+1215c5/22aedb> Trace; c0128a52 <__do_softirq+92/130> Trace; c0128b69 <do_softirq+79/80> Trace; c0107344 <do_IRQ+44/a0> Trace; c02441fe <evtchn_do_upcall+be/100> Trace; c010581d <hypervisor_callback+3d/45> Trace; c0108b1a <raw_safe_halt+9a/120> Trace; c0104439 <xen_idle+29/50> Trace; c010359d <cpu_idle+6d/c0> Trace; c03b4835 <start_kernel+3a5/480> Trace; c03b4220 <unknown_bootoption+0/270> Code; c011ae52 <dequeue_task+12/50> 00000000 <_EIP>: Code; c011ae52 <dequeue_task+12/50> <==== 0: b9 01 00 00 00 mov $0x1,%ecx <====Code; c011ae57 <dequeue_task+17/50> 5: 29 d0 sub %edx,%eax Code; c011ae59 <dequeue_task+19/50> 7: 89 c2 mov %eax,%edx Code; c011ae5b <dequeue_task+1b/50> 9: c1 ea 1f shr $0x1f,%edx Code; c011ae5e <dequeue_task+1e/50> c: 01 c2 add %eax,%edx Code; c011ae60 <dequeue_task+20/50> e: d1 fa sar %edx Code; c011ae62 <dequeue_task+22/50> 10: 85 d2 test %edx,%edx Code; c011ae64 <dequeue_task+24/50> 12: 5d pop %ebp Code; c011ae65 <dequeue_task+25/50> 13: 0f 4f ca cmovg %edx,%ecx Code; c011ae68 <dequeue_task+28/50> 16: 89 c8 mov %ecx,%eax Code; c011ae6a <dequeue_task+2a/50> 18: c3 ret Code; c011ae6b <dequeue_task+2b/50> 19: 55 push %ebp Code; c011ae6c <dequeue_task+2c/50> 1a: 89 e5 mov %esp,%ebp Code; c011ae6e <dequeue_task+2e/50> 1c: 83 ec 08 sub $0x8,%esp Code; c011ae71 <dequeue_task+31/50> 1f: 89 1c 24 mov %ebx,(%esp) Regards, Ashutosh _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2007-Nov-03 07:39 UTC
Re: [Xen-devel] Trouble with xenbus_write in a timer handler
You canĀ¹t do xenbus stuff from softirq context. Timer callbacks run in softirq context. If you must trigger xenbus activity based on a timeout, use schedule_work() or similar. That can be used in softirq context to defer work to a kernel thread, from which it is safe to do xenbus stuff. -- Keir On 2/11/07 20:59, "ashutosh mehra" <ashutosh.xen@gmail.com> wrote:> Hi, > > I made a module which intends to periodically update the value of a node in > xenstore, using xenstore_write(...). The xenstore_write() call was working > fine when I put it in init_module(), but when I put it in a timer handler, it > makes the module crash (causes a kernel oops and the system reboot. (dom0 or > domU depending on where I insmod it). What could be the problem here? This is > the source code: > > #include <linux/init.h> > #include <linux/module.h> > #include <linux/uio.h> > #include <linux/kernel.h> > #include <linux/syscalls.h> > #include <linux/timer.h> > > #include <asm-i386/param.h> > > #include <xen/xenbus.h> > > struct timer_list freememupdate_timer; > > int delay = 5 * HZ; > > void freememupdate_handler(unsigned long data) > { > // Get free system memory > char freemembuf[33]=""; > long freemem; > int cnt = 0; > int i, ret; > struct sysinfo info; > > printk(KERN_INFO "freememupdate_handler called\n"); > si_meminfo(&info); > > freemem = info.freeram * info.mem_unit; > //sprintf(freemembuf, "%ld", freemem); > while(freemem > 0) > { > int a = freemem % 10; > freemembuf[cnt++] = (char) (a + ''0''); > freemem /= 10; > } > freemembuf[cnt]=''\0''; > for(i=0; i<cnt/2; i++) > freemembuf[i] = freemembuf[cnt-i-1]; > > ret = xenbus_write(XBT_NIL, "memory", "freemem", "12345"); // <--- > MAKES THE MODULE CRASH AND THE SYSTEM REBOOT > > //printk("Ret val: %d, Freemem: %ld, Freemembuf: %s\n", ret, freemem, > freemembuf); > //add_timer(&freememupdate_timer); > } > > static int init() > { > printk("Init 1\n"); > init_timer(&freememupdate_timer); > freememupdate_timer.expires = jiffies + delay; > freememupdate_timer.data = 0; > freememupdate_timer.function = freememupdate_handler; > printk("Init 2\n"); > add_timer(&freememupdate_timer); > printk("Init 3\n"); > return 0; > } > > static void clean_up() > { > printk("Cleanup"); > del_timer(&freememupdate_timer); > printk(KERN_ALERT "Module ended"); > } > > module_init(init); > module_exit(clean_up); > MODULE_LICENSE("GPL"); > > > > > klogd messages: > > > Nov 2 20:10:59 guest kernel: Init 1 > Nov 2 20:10:59 guest kernel: Init 2 > Nov 2 20:10:59 guest kernel: Init 3 > BUG: scheduling while atomic: swapper/0x00000100/0 > bad: scheduling from the idle thread! > BUG: unable to handle kernel NULL pointer dereference at virtual address > 00000000 > printing eip: > 0704d000 -> *pde = 00000000:14e0f001 > 086cc000 -> *pme = 00000000:00000000 > Oops: 0002 [#1] > SMP > Modules linked in: xenfreememupdate evdev 8250 serial_core processor ext3 jbd > CPU: 0 > EIP: 0061:[<c011ae52>] Not tainted VLI > EFLAGS: 00010082 (2.6.18-xen #2) > EIP is at dequeue_task+0x12/0x50 > eax: c034d2c0 ebx: c034d2e8 ecx: c034d2c0 edx: 00000000 > esi: 00000000 edi: c03afe30 ebp: c03afd6c esp: c03afd64 > ds: 007b es: 007b ss: 0069 > Process swapper (pid: 0, ti=c03ae000 task=c034d2c0 task.ti=c03ae000) > Stack: c034d2c0 c034d3e4 c03afd78 c011aefa c14e4a00 c03afdf4 c02f74bf c0313de0 > c034d46c 00000100 00000000 c011afb9 00000000 00000001 00000001 c034d2c0 > c034fd6c 91c1623f 00000080 01cc5f58 c034d3e4 c14e4a00 00000000 00000001 > Call Trace: > [<c011aefa>] deactivate_task+0x1a/0x30 > [<c02f74bf>] schedule+0x48f/0x920 > [<c011afb9>] __wake_up_common+0x39/0x60 > [<c0249a39>] xb_write+0xa9/0x210 > [<c0138a10>] prepare_to_wait+0x20/0x70 > [<c0249f85>] read_reply+0x75/0xf0 > [<c0138860>] autoremove_wake_function+0x0/0x50 > [<c024a131>] xs_talkv+0xa1/0x180 > [<c024a529>] xenbus_write+0x79/0xa0 > [<c902410a>] freememupdate_handler+0x5a/0x84 [xenfreememupdate] > [<c013bce5>] hrtimer_run_queues+0xc5/0x1b0 > [<c012dfbb>] run_timer_softirq+0x13b/0x1f0 > [<c90240b0>] freememupdate_handler+0x0/0x84 [xenfreememupdate] > [<c0128a52>] __do_softirq+0x92/0x130 > [<c0128b69>] do_softirq+0x79/0x80 > [<c0107344>] do_IRQ+0x44/0xa0 > [<c02441fe>] evtchn_do_upcall+0xbe/0x100 > [<c010581d>] hypervisor_callback+0x3d/0x45 > [<c0108b1a>] raw_safe_halt+0x9a/0x120 > [<c0104439>] xen_idle+0x29/0x50 > [<c010359d>] cpu_idle+0x6d/0xc0 > [<c03b4835>] start_kernel+0x3a5/0x480 > [<c03b4220>] unknown_bootoption+0x0/0x270 > Code: b9 01 00 00 00 29 d0 89 c2 c1 ea 1f 01 c2 d1 fa 85 d2 5d 0f 4f ca 89 c8 > c3 55 89 e5 83 ec 08 89 1c 24 > > > > > > Corresponding ksysoops output: > >>> >>EIP; c011ae52 <dequeue_task+12/50> <====> >>> >>eax; c034d2c0 <init_task+0/580> >>> >>ebx; c034d2e8 <init_task+28/580> >>> >>ecx; c034d2c0 <init_task+0/580> >>> >>edi; c03afe30 <init_thread_union+1e30/2000> >>> >>ebp; c03afd6c <init_thread_union+1d6c/2000> >>> >>esp; c03afd64 <init_thread_union+1d64/2000> > > Trace; c011aefa <deactivate_task+1a/30> > Trace; c02f74bf <schedule+48f/920> > Trace; c011afb9 <__wake_up_common+39/60> > Trace; c0249a39 <xb_write+a9/210> > Trace; c0138a10 <prepare_to_wait+20/70> > Trace; c0249f85 <read_reply+75/f0> > Trace; c0138860 <autoremove_wake_function+0/50> > Trace; c024a131 <xs_talkv+a1/180> > Trace; c024a529 <xenbus_write+79/a0> > Trace; c902410a <__crc_prepare_to_wait+12161f/22aedb> > Trace; c013bce5 <hrtimer_run_queues+c5/1b0> > Trace; c012dfbb <run_timer_softirq+13b/1f0> > Trace; c90240b0 <__crc_prepare_to_wait+1215c5/22aedb> > Trace; c0128a52 <__do_softirq+92/130> > Trace; c0128b69 <do_softirq+79/80> > Trace; c0107344 <do_IRQ+44/a0> > Trace; c02441fe <evtchn_do_upcall+be/100> > Trace; c010581d <hypervisor_callback+3d/45> > Trace; c0108b1a <raw_safe_halt+9a/120> > Trace; c0104439 <xen_idle+29/50> > Trace; c010359d <cpu_idle+6d/c0> > Trace; c03b4835 <start_kernel+3a5/480> > Trace; c03b4220 <unknown_bootoption+0/270> > > Code; c011ae52 <dequeue_task+12/50> > 00000000 <_EIP>: > Code; c011ae52 <dequeue_task+12/50> <====> 0: b9 01 00 00 00 mov $0x1,%ecx <====> Code; c011ae57 <dequeue_task+17/50> > 5: 29 d0 sub %edx,%eax > Code; c011ae59 <dequeue_task+19/50> > 7: 89 c2 mov %eax,%edx > Code; c011ae5b <dequeue_task+1b/50> > 9: c1 ea 1f shr $0x1f,%edx > Code; c011ae5e <dequeue_task+1e/50> > c: 01 c2 add %eax,%edx > Code; c011ae60 <dequeue_task+20/50> > e: d1 fa sar %edx > Code; c011ae62 <dequeue_task+22/50> > 10: 85 d2 test %edx,%edx > Code; c011ae64 <dequeue_task+24/50> > 12: 5d pop %ebp > Code; c011ae65 <dequeue_task+25/50> > 13: 0f 4f ca cmovg %edx,%ecx > Code; c011ae68 <dequeue_task+28/50> > 16: 89 c8 mov %ecx,%eax > Code; c011ae6a <dequeue_task+2a/50> > 18: c3 ret > Code; c011ae6b <dequeue_task+2b/50> > 19: 55 push %ebp > Code; c011ae6c <dequeue_task+2c/50> > 1a: 89 e5 mov %esp,%ebp > Code; c011ae6e <dequeue_task+2e/50> > 1c: 83 ec 08 sub $0x8,%esp > Code; c011ae71 <dequeue_task+31/50> > 1f: 89 1c 24 mov %ebx,(%esp) > > Regards, > Ashutosh > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel