You are not logged in.

#1 2007-01-07 14:37:16

fluke
Member
From: Shaoguan Univ., PRC
Registered: 2005-08-12
Posts: 241
Website

Strange problem about interrupt

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

#2 2007-01-07 14:56:28

fluke
Member
From: Shaoguan Univ., PRC
Registered: 2005-08-12
Posts: 241
Website

Re: Strange problem about interrupt

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

#3 2007-01-08 11:49:48

fluke
Member
From: Shaoguan Univ., PRC
Registered: 2005-08-12
Posts: 241
Website

Re: Strange problem about interrupt

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

Board footer

Powered by FluxBB