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