[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Trouble with xenbus_write in a timer handler


  • To: ashutosh mehra <ashutosh.xen@xxxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
  • Date: Sat, 03 Nov 2007 07:39:49 +0000
  • Delivery-date: Sat, 03 Nov 2007 00:34:59 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: Acgd7LZq9PnAK4nfEdyjrwAWy6hiGQ==
  • Thread-topic: [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@xxxxxxxxx> 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 = "">     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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.