Hi, I wonder how an interrupt handler work, and so try to make one by myself. The first problem is which irq number should I select to hook an interrupt handler on it. In terms of the following messages, I think irq 0 can be adopted because the number of interrupts raised remains 145 and does not increase any more. This case may imply the interrupt handler of rtc clock is not working and can be replaced by another one. Furthermore, I also notice that the Local timer interrupts is increasing, and guess that the clock ticks are driven by this clock chip. That means the irq 0 may be deprecated and its handler can be replaced safely. root [ ~/work/moduleprog ]# cat /proc/interrupts CPU0 0: 145 XT-PIC-XT timer <---- is not working 1: 8 XT-PIC-XT i8042 2: 0 XT-PIC-XT cascade 5: 402 XT-PIC-XT eth0 6: 3 XT-PIC-XT floppy 9: 0 XT-PIC-XT acpi 10: 0 XT-PIC-XT uhci_hcd:usb2 11: 45 XT-PIC-XT ioc0, ehci_hcd:usb1 12: 116 XT-PIC-XT i8042 14: 750 XT-PIC-XT ide0 15: 48 XT-PIC-XT ide1 NMI: 0 Non-maskable interrupts LOC: 4932 Local timer interrupts <---- is working really SPU: 0 Spurious interrupts ... ... ... ... ... The kernel module code: #include <linux/module.h> #include <linux/kernel.h> #include <linux/interrupt.h> static irqreturn_t my_interrupt(int irq, void *dev) { return IRQ_HANDLED; } int init_module(void) { free_irq(0, NULL); if (request_irq(0, my_interrupt, IRQF_SHARED, "myinterrupt", (void *)my_interrupt)){ printk(KERN_ALERT "Can not install interrupt handler of irq 0.\n"); } return 0; } void cleanup_module(void) { } MODULE_LICENSE("GPL"); MODULE_AUTHOR("parmenides"); MODULE_SUPPORTED_DEVICE("mydevice"); Compile it and then invork insmod, I get these messages: Aug 27 23:18:35 lfs kernel: ------------[ cut here ]------------ Aug 27 23:18:35 lfs kernel: kernel BUG at mm/slab.c:521! Aug 27 23:18:35 lfs kernel: invalid opcode: 0000 [#1] SMP Aug 27 23:18:35 lfs kernel: last sysfs file: /sys/kernel/uevent_seqnum Aug 27 23:18:35 lfs kernel: Modules linked in: mydevice(+) Aug 27 23:18:35 lfs kernel: Aug 27 23:18:35 lfs kernel: Pid: 1688, comm: insmod Not tainted 2.6.34 #1 440BX Desktop Reference Platform/VMware Virtual Platform Aug 27 23:18:35 lfs kernel: EIP: 0060:[<c108a835>] EFLAGS: 00010046 CPU: 0 Aug 27 23:18:35 lfs kernel: EIP is at kfree+0x67/0x96 Aug 27 23:18:35 lfs kernel: EAX: 00000000 EBX: c155eb40 ECX: 00000000 EDX: c16cdde0 Aug 27 23:18:35 lfs kernel: ESI: 00000282 EDI: c156fc80 EBP: 00000000 ESP: cf323f70 Aug 27 23:18:35 lfs kernel: DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Aug 27 23:18:35 lfs kernel: Process insmod (pid: 1688, ti=cf322000 task=cfbaa030 task.ti=cf322000) Aug 27 23:18:35 lfs kernel: Stack: Aug 27 23:18:35 lfs kernel: c155eb40 00000000 00000000 c1054076 d0846080 00000000 d0846007 d0846010 Aug 27 23:18:35 lfs kernel: <0> c100112d d0846080 00000000 f63d4e2e cf322000 c10517ce 0804b018 080488f0 Aug 27 23:18:35 lfs kernel: <0> c138ba4d 0804b018 00000826 0804b008 080488f0 f63d4e2e bfddbfb8 00000080 Aug 27 23:18:35 lfs kernel: Call Trace: Aug 27 23:18:35 lfs kernel: [<c1054076>] ? free_irq+0x2e/0x40 Aug 27 23:18:35 lfs kernel: [<d0846007>] ? init_module+0x0/0x3d [mydevice] Aug 27 23:18:35 lfs kernel: [<d0846010>] ? init_module+0x9/0x3d [mydevice] Aug 27 23:18:35 lfs kernel: [<c100112d>] ? do_one_initcall+0x44/0x120 Aug 27 23:18:35 lfs kernel: [<c10517ce>] ? sys_init_module+0xa7/0x1d9 Aug 27 23:18:35 lfs kernel: [<c138ba4d>] ? syscall_call+0x7/0xb Aug 27 23:18:35 lfs kernel: Code: e2 05 03 15 c0 65 68 c1 8b 02 25 00 80 00 00 66 85 c0 74 03 8b 52 0c 8b 02 25 00 80 00 00 66 85 c0 74 03 8b 52 0c 80 3a 00 78 04 <0f> 0b eb fe 8b 4a 18 64 a1 e8 5d 5f c1 8b 1c 81 8b 03 3b 43 04 Aug 27 23:18:35 lfs kernel: EIP: [<c108a835>] kfree+0x67/0x96 SS:ESP 0068:cf323f70 Aug 27 23:18:35 lfs kernel: ---[ end trace 00973d9f77f0e389 ]--- The problem is likely caused by free_irq(), but I don't know why and how to resolve it.
Hi... On Sat, Aug 27, 2011 at 22:23, Parmenides <mobile.parmenides@gmail.com> wrote:
I wonder how an interrupt handler work, and so try to make one by myself. The first problem is which irq number should I select to hook an interrupt handler on it. In terms of the following messages, I think irq 0 can be adopted because the number of interrupts raised remains 145 and does not increase any more.
are you really sure? in my system (laptop with core duo cpu) it is increased by around 1000-2000 every 2 seconds and AFAIK it is using HPET. So maybe IMO free_irq() is causing your cpu referencing null instruction...that might be due to free_irq is not checking whether it is safe to delete a handler.... -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
are you really sure? in my system (laptop with core duo cpu) it is increased by around 1000-2000 every 2 seconds and AFAIK it is using HPET.
Yes. How can I see the timer is i8253 or HPET? I just found 'timer' in terms of the output of 'cat /proc/interrupts'.
So maybe IMO free_irq() is causing your cpu referencing null instruction...that might be due to free_irq is not checking whether it is safe to delete a handler....
After enabling the RTC support, I have recompiled the kernel and try to use the irq 8. But, it seems that the 'irq_request()' can not register my hangler. 2011/8/28 Mulyadi Santosa <mulyadi.santosa@gmail.com>:
Hi...
On Sat, Aug 27, 2011 at 22:23, Parmenides <mobile.parmenides@gmail.com> wrote:
I wonder how an interrupt handler work, and so try to make one by myself. The first problem is which irq number should I select to hook an interrupt handler on it. In terms of the following messages, I think irq 0 can be adopted because the number of interrupts raised remains 145 and does not increase any more.
are you really sure? in my system (laptop with core duo cpu) it is increased by around 1000-2000 every 2 seconds and AFAIK it is using HPET.
So maybe IMO free_irq() is causing your cpu referencing null instruction...that might be due to free_irq is not checking whether it is safe to delete a handler....
-- regards,
Mulyadi Santosa Freelance Linux trainer and consultant
blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
Hi... On Sun, Aug 28, 2011 at 03:59, Parmenides <mobile.parmenides@gmail.com> wrote:
are you really sure? in my system (laptop with core duo cpu) it is increased by around 1000-2000 every 2 seconds and AFAIK it is using HPET.
Yes. How can I see the timer is i8253 or HPET? I just found 'timer' in terms of the output of 'cat /proc/interrupts'.
try dumping the output of "/sys/devices/system/clocksource/clocksource*/current_clocksource"
So maybe IMO free_irq() is causing your cpu referencing null instruction...that might be due to free_irq is not checking whether it is safe to delete a handler....
After enabling the RTC support, I have recompiled the kernel and try to use the irq 8. But, it seems that the 'irq_request()' can not register my hangler.
isn't that 8 occupied by rtc? and it might be occupied exclusively....a.k.a you can put more handler there -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
After enabling the RTC support, I have recompiled the kernel and try to use the irq 8. But, it seems that the 'irq_request()' can not register my hangler.
isn't that 8 occupied by rtc? and it might be occupied exclusively....a.k.a you can put more handler there
The irq 8 is really occupied by rtc and its initial flags is set as IRQF_DISABLED. At the beginning, I think the irq's registration is invoked in drivers/char/rtc.c, but this is not really the case. Then, I have to find where the registration is done. I modified the request_irq() to the other function name, and compiled the kernel. Checking the error messages from gcc I found that the actual registration is done in drivers/rtc/rtc-cmos.c like this: retval = request_irq(rtc_irq, rtc_cmos_int_handler, IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), cmos_rtc.rtc); It is obviously that the irq8 (rtc_irq == 8) is not permitted to be shared with other interrupt handlers. So, I changed IRQF_DISABLED to IRQF_SHARED, recompiled the kernel, installed it, and then reboot. After my module inserted, I get the following messages: root [ ~ ]# cat /proc/interrupts CPU0 0: 150 XT-PIC-XT timer 1: 8 XT-PIC-XT i8042 2: 0 XT-PIC-XT cascade 5: 2871 XT-PIC-XT eth0 6: 3 XT-PIC-XT floppy 8: 132 XT-PIC-XT rtc0, myinterrupt 9: 0 XT-PIC-XT acpi 10: 0 XT-PIC-XT uhci_hcd:usb2 11: 45 XT-PIC-XT ioc0, ehci_hcd:usb1 12: 116 XT-PIC-XT i8042 14: 2016 XT-PIC-XT ide0 15: 48 XT-PIC-XT ide1 NMI: 0 Non-maskable interrupts LOC: 14033 Local timer interrupts SPU: 0 Spurious interrupts PMI: 0 Performance monitoring interrupts PND: 0 Performance pending work RES: 0 Rescheduling interrupts CAL: 0 Function call interrupts TLB: 0 TLB shootdowns TRM: 0 Thermal event interrupts THR: 0 Threshold APIC interrupts MCE: 0 Machine check exceptions MCP: 8 Machine check polls The 'rtc0' and 'myinterrupt' share the irq8 really. Then, I executed the test program from Documentation/rtc.txt to activate some periodic interrupts from the rtc, and found that the handler of 'myinterrupt' invoked several times by its output to /var/log/messages. But I don't think this is an ideal solution to share irq owing to the modification to kernel code directly. So, I wonder whether there is any EXPORTed funciton which can modify the flags of an existing interrupt handler. 2011/8/28 Mulyadi Santosa <mulyadi.santosa@gmail.com>:
Hi...
On Sun, Aug 28, 2011 at 03:59, Parmenides <mobile.parmenides@gmail.com> wrote:
are you really sure? in my system (laptop with core duo cpu) it is increased by around 1000-2000 every 2 seconds and AFAIK it is using HPET.
Yes. How can I see the timer is i8253 or HPET? I just found 'timer' in terms of the output of 'cat /proc/interrupts'.
try dumping the output of "/sys/devices/system/clocksource/clocksource*/current_clocksource"
So maybe IMO free_irq() is causing your cpu referencing null instruction...that might be due to free_irq is not checking whether it is safe to delete a handler....
-- regards,
Mulyadi Santosa Freelance Linux trainer and consultant
blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
Hi :) On Sun, Aug 28, 2011 at 17:13, Parmenides <mobile.parmenides@gmail.com> wrote:
The irq 8 is really occupied by rtc and its initial flags is set as IRQF_DISABLED.
Ah, great you found it :) I could only guess it...
At the beginning, I think the irq's registration is invoked in drivers/char/rtc.c, but this is not really the case. Then, I have to find where the registration is done. I modified the request_irq() to the other function name, and compiled the kernel. Checking the error messages from gcc I found that the actual registration is done in drivers/rtc/rtc-cmos.c like this:
retval = request_irq(rtc_irq, rtc_cmos_int_handler, IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), cmos_rtc.rtc);
I think it is somewhat make sense to use IRQF_DISABLED here, since this kind of irq should ask for exclusive line and none other should ever bug with it. That way RTC handling is handled as fast and as efficiently as possible.
But I don't think this is an ideal solution to share irq owing to the modification to kernel code directly. So, I wonder whether there is any EXPORTed funciton which can modify the flags of an existing interrupt handler.
I don't think there is any, but I could be wrong here.... -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com
2011/8/29 Mulyadi Santosa <mulyadi.santosa@gmail.com>:
Hi :)
On Sun, Aug 28, 2011 at 17:13, Parmenides <mobile.parmenides@gmail.com> wrote:
The irq 8 is really occupied by rtc and its initial flags is set as IRQF_DISABLED.
Ah, great you found it :) I could only guess it...
Thanks for your encouragement. Your guess is really my important guide. :-)
I think it is somewhat make sense to use IRQF_DISABLED here, since this kind of irq should ask for exclusive line and none other should ever bug with it. That way RTC handling is handled as fast and as efficiently as possible.
So, it is an good idea to maintain kernel's logical integrity. I am just do it for funning rather than productive purpose.
participants (2)
-
Mulyadi Santosa -
Parmenides