views:

348

answers:

2

So the TimerExpire function in my setup_timer() causes a huge panic (will post below), while the regular function call to TimerExpire() will actually print out my input.

void TimerExpire(char* data)
{
    printk("Timer Data: %s\n", data);
}

setup_timer(&my_timer, TimerExpire, (char *)args);
printk("Made timer: %s\n", (char *)args);
TimerExpire((char *)args);

Anybody know why?

This is the error output (by the way this is on a gumstix verdex emulator, which is a linux kernel): (Ignore the very first character backtick, I used it to escape.)

`# Unable to handle kernel paging request at virtual address be940eb2 pgd = c0004000 [be940eb2] *pgd=00000000 Internal error: Oops: 35 [#1] Modules linked in: mytimer ipv6 pxa2xx_cs pxa2xx_core pcmcia pcmcia_core firmware_class pxamci mmc_block mmc_core CPU: 0 PC is at strnlen+0x20/0x34 LR is at vsnprintf+0x318/0x5c8 pc : [] lr : [] Not tainted sp : c01b9d88 ip : c01b9d98 fp : c01b9d94 r10: 00000000 r9 : c01ca148 r8 : ffffffff r7 : c01ce468 r6 : c01c9d54 r5 : be940eb2 r4 : c01b9e94 r3 : c01a0808 r2 : be940eb2 r1 : fffffffe r0 : be940eb2 Flags: NzCv IRQs off FIQs on Mode SVC_32 Segment kernel Control: 7977 Table: A3488000 DAC: 00000017 Process swapper (pid: 0, stack limit = 0xc01b8258) Stack: (0xc01b9d88 to 0xc01ba000) 9d80: c01b9de4 c01b9d98 c00d7d4c c00d6bd4 00000000 c01b9e4c 9da0: 00000989 00000033 c01b9e24 00000400 c01c9d48 bf06523d 000080d5 00000400 9dc0: bf065054 c01b9e94 c01ce468 00000000 69054114 c01b8000 c01b9dfc c01b9de8 9de0: c00d814c c00d7a40 00000000 bf065230 c01b9e74 c01b9e00 c00381b8 c00d8140 9e00: c01b9e24 20000193 00000001 60000113 00000000 c0276db0 00000000 00000003 9e20: c01b9e3c c01b9e30 c003468c c0034508 c01b9e6c c01b9e40 c0033268 c0034684 9e40: 00000989 20000193 c01b9ec4 00000100 bf065054 bf065944 c01ce468 00000000 9e60: 69054114 c01b8000 c01b9e8c c01b9e78 c003845c c003810c bf065944 c01b9e94 9e80: c01b9eac c01b9ea0 bf06504c c0038444 bf065230 be940eb2 c01b9ec8 60000113 9ea0: c01b9ebc c01b9eb0 bf065064 bf065040 c01b9ef4 c01b9ec0 c003ffb8 bf065060 9ec0: bf065960 c0040d08 c01b9ec8 c01b9ec8 00000001 c01ce264 0000000a c01e1d7c 9ee0: a001419c a0014168 c01b9f14 c01b9ef8 c003c7c4 c003fe60 69054114 0000001a 9f00: c01ba680 00000000 c01b9f24 c01b9f18 c003cb88 c003c770 c01b9f44 c01b9f28 9f20: c002957c c003cb50 c00086f4 ffffffff c01b9f7c 04000000 c01b9f9c c01b9f48 9f40: c0028830 c0029540 00000001 c01b8000 a0000013 20000013 c0029d44 c01b8000 9f60: c00153e8 c01e1d7c a001419c 69054114 a0014168 c01b9f9c c01b9f90 c01b9f90 9f80: c0029d8c c0029d98 20000013 ffffffff c01b9fb4 c01b9fa0 c0029b1c c0029d50 9fa0: c01dc20c c01c88b0 c01b9fc4 c01b9fb8 c0028138 c0029af0 c01b9ff4 c01b9fc8 9fc0: c0008adc c0028120 c00083e4 00000000 00000000 c00153e8 00000000 00007975 9fe0: c01c8964 c01be264 00000000 c01b9ff8 a0008030 c00088bc 00000000 00000000 Backtrace: [] (strnlen+0x0/0x34) from [] (vsnprintf+0x318/0x5c8) [] (vsnprintf+0x0/0x5c8) from [] (vscnprintf+0x18/0x24) [] (vscnprintf+0x0/0x24) from [] (vprintk+0xb8/0x334) r4 = BF065230 [] (vprintk+0x0/0x334) from [] (printk+0x28/0x30) [] (printk+0x0/0x30) from [] (PrintMessage+0x18/0x20 [mytimer]) r3 = 60000113 r2 = C01B9EC8 r1 = BE940EB2 r0 = BF065230 [] (PrintMessage+0x0/0x20 [mytimer]) from [] (TimerExpire+0x10/0x14 [mytimer]) [] (TimerExpire+0x0/0x14 [mytimer]) from [] (run_timer_softirq+0x164/0x1e8) [] (run_timer_softirq+0x0/0x1e8) from [] (__do_softirq+0x60/0xd4) [] (__do_softirq+0x0/0xd4) from [] (irq_exit+0x44/0x4c) r6 = 00000000 r5 = C01BA680 r4 = 0000001A [] (irq_exit+0x0/0x4c) from [] (asm_do_IRQ+0x48/0x60) [] (asm_do_IRQ+0x0/0x60) from [] (__irq_svc+0x30/0x80) r6 = 04000000 r5 = C01B9F7C r4 = FFFFFFFF [] (default_idle+0x0/0x5c) from [] (cpu_idle+0x38/0x54) [] (cpu_idle+0x0/0x54) from [] (rest_init+0x24/0x2c) r5 = C01C88B0 r4 = C01DC20C [] (rest_init+0x0/0x2c) from [] (start_kernel+0x22c/0x284) [] (start_kernel+0x0/0x284) from [] (0xa0008030) Code: ea000000 e2800001 e2511001 3a000002 (e5d03000) Kernel panic - not syncing: Aiee, killing interrupt handler!

+1  A: 

Just an extremely wild guess here. But I would suggest to narrow things down by

  • first remove the printk from the timer function (to make sure printk() is the guilty one)
  • if that works make printk print a static string (without parameters), to know if you are allowed to printk from that context (could be that printk is not appreciated form softirq context)
  • then start looking whether data is accessible, you pass a pointer to some string, do you know that string still exists ? is it a global string (and thus accessible, or not).

If you look in timer.h the pointer to the data just gets stored, so if that pointer falls outside the reach or becomes inaccessible I would expect that behavior from a printk.

amo-ej1
I think I figured it out... But I'll still have to code it to see if I'm right. My args is from userland... So I will need to copy_from_user since my kernel module is in kernelspace.
hahuang65
a copy_from_user will not be sufficient, you need to copy it to a location where the timer callback will be able to find it.
amo-ej1
actually, it worked :) Thanks for all the help guys.
hahuang65
+1  A: 

Who controls the memory pointed to by the pointer data? Could that memory have been recycled by the time your timer went off?

Perhaps you should make a copy of that data, some place that you can guarantee it will still be valid later on.

For testing, check if TimerExpire() can print a message without the string. If this works, then you know the problem is with the pointer, not the timer.

Eric Seppanen
You're exactly right. It was a problem with the pointer. I tried it before I posted this, although if I casted it as an int, it works and prints. But in my comment to amo-ej1 above, I mentioned that it might be cuz args is from userspace and I'm trying to use it in kernelspace.
hahuang65