You are not logged in.
Pages: 1
I'm writing a serial port driver and I encounter a problem, wierd.
I registered an interrupt routine in my module. When data comes it goes into my routine.
But I dont know why every 100000 times interrupts will cause one kernel action - kernel disable my interrupt:
irq 4: nobody cared (try booting with the "irqpoll" option)
[<c015a314>] __report_bad_irq+0x24/0x90
[<c012760b>] printk+0x1b/0x20
[<c015a5b8>] note_interrupt+0x238/0x270
[<deb831dc>] interrupt_read_char+0x6c/0xf0 [hellomod]
[<c0159855>] handle_IRQ_event+0x25/0x60
[<c015aff5>] handle_edge_irq+0xc5/0x140
[<c0105d99>] do_IRQ+0x69/0xd0
[<c0103ca2>] common_interrupt+0x1a/0x20
[<deb83036>] read_hello+0x6/0x60 [hellomod]
[<c017e6ac>] vfs_read+0xbc/0x180
[<deb83030>] read_hello+0x0/0x60 [hellomod]
[<c017ec21>] sys_read+0x41/0x70
[<c01032b1>] sysenter_past_esp+0x56/0x79
=======================
handlers:
[<deb83170>] (interrupt_read_char+0x0/0xf0 [hellomod])
Disabling IRQ #4
And I'm sure there was no nested irq happened.
--------------------
See interrupt count before I use my serial driver:
[root@sgu log]# cat /proc/interrupts
CPU0
0: 16931115 IO-APIC-edge timer
1: 28306 IO-APIC-edge i8042
4: 0 IO-APIC-edge hellomod_irq_handle
And after my interrupt was disabled by kernel:
[root@sgu log]# cat /proc/interrupts
CPU0
0: 17262952 IO-APIC-edge timer
1: 29354 IO-APIC-edge i8042
4: 100000 IO-APIC-edge hellomod_irq_handle
But this does not happen to system's serial driver ( you can cat file > /dev/ttyS0 and receive at target side by cat /dev/ttyS0 , and see the interrupt count, though it's a bit slow )
Who know why?
Offline
See this:
I try to open and close /dev/ttyS0 infinite times:
#include <stdio>
#include <unistd>
#include <errno>
#include <fcntl>
int main()
{
int i=0;
while(1) {
int fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);
if(fd < 0)
fprintf(stderr, "%sn", strerror(errno));
else
close(fd);
i++;
}
printf("%dn");
return 0;
}
By watching dmesg and /proc/stat [intr], I find that, IRQ is disabled every 100 000 times of interrupt occured:
irq 4: nobody cared (try booting with the "irqpoll" option)
[<c015a314>] __report_bad_irq+0x24/0x90
[<c015a5b8>] note_interrupt+0x238/0x270
[<c0159855>] handle_IRQ_event+0x25/0x60
[<c015aff5>] handle_edge_irq+0xc5/0x140
[<c0105d99>] do_IRQ+0x69/0xd0
[<c0103ca2>] common_interrupt+0x1a/0x20
[<c03621b8>] _spin_unlock_irqrestore+0x8/0x20
[<c029d5a9>] serial8250_startup+0x169/0x430
[<c0298f49>] uart_startup+0x49/0x150
[<c0299128>] uart_open+0xd8/0x440
[<c024b1d7>] check_tty_count+0x47/0xb0
[<c024e37a>] tty_open+0x16a/0x330
[<c0180b53>] chrdev_open+0xd3/0x1c0
[<c0189369>] open_namei+0x79/0x620
[<c0180a80>] chrdev_open+0x0/0x1c0
[<c017c4c4>] __dentry_open+0xe4/0x260
[<c017c6f5>] nameidata_to_filp+0x35/0x40
[<c017c74b>] do_filp_open+0x4b/0x60
[<c017c3cc>] get_unused_fd+0xbc/0xd0
[<c017c7aa>] do_sys_open+0x4a/0xe0
[<c017c87c>] sys_open+0x1c/0x20
[<c01032b1>] sysenter_past_esp+0x56/0x79
=======================
handlers:
[<c029d8f0>] (serial8250_interrupt+0x0/0x100)
Disabling IRQ #4
Why? Are there any tricks?
Offline
I find the trick.
In the ISR (interrupt service routine) we should return IRQ_HANDLED if irq was handled.
Or kernel will consider the interrupt as a "noboddy cared" interrupt.
Offline
Pages: 1