linux 查看中断被谁占用
几周前解决的一个系统问题中,执行 dmesg 有如下堆栈信息:
[ 2526.575881] irq 19: nobody cared (try booting with the "irqpoll" option)
[ 2526.582587] Pid: 0, comm: swapper Not tainted 2.6.39 #6
[ 2526.589366] Call Trace:
[ 2526.591816] <IRQ> [<ffffffff81082c62>] __report_bad_irq+0x43/0xaf
[ 2526.598116] [<ffffffff8108303c>] note_interrupt+0x165/0x1d9
[ 2526.603771] [<ffffffff81081764>] handle_irq_event_percpu+0x113/0x12b
[ 2526.610203] [<ffffffff810817be>] handle_irq_event+0x42/0x64
[ 2526.615859] [<ffffffff810836f9>] handle_fasteoi_irq+0x82/0xa8
[ 2526.621692] [<ffffffff81005fb2>] handle_irq+0x22/0x2a
[ 2526.626832] [<ffffffff81005ee5>] do_IRQ+0x48/0x9f
[ 2526.631623] [<ffffffff8158f9d3>] common_interrupt+0x13/0x13
[ 2526.637276] <EOI> [<ffffffff8100aa4c>] ? mwait_idle+0x72/0x84
[ 2526.643210] [<ffffffff8100aa3f>] ? mwait_idle+0x65/0x84
[ 2526.648522] [<ffffffff8100324b>] cpu_idle+0x49/0x7a
[ 2526.653483] [<ffffffff8157819e>] rest_init+0x92/0x96
[ 2526.658534] [<ffffffff8196db7e>] start_kernel+0x39b/0x3a6
[ 2526.664012] [<ffffffff8196d2a6>] x86_64_start_reservations+0xb6/0xba
[ 2526.670446] [<ffffffff8196d39c>] x86_64_start_kernel+0xf2/0xf9
[ 2526.676369] handlers:
[ 2526.678639] [<ffffffff81386d7d>] (ata_bmdma_interrupt+0x0/0x15)
[ 2526.684597] Disabling IRQ #19
分析上面的信息,发现与第 19 号中断有关。报错的信息表明,内核没有找到 19 号中断对应的中断处理程序并对此异常做出反应,关闭了 19 号中断。
19 号中断被谁占用?
既然是与 19 号中断有关,那么这个 19 号中断是被谁占用呢?这个问题可以通过检索 /proc/interrupts
这个 proc 文件来确定。/proc/interrupts
文件中记录了中断的一些信息,这些信息包括中断号,每一个 CPU 的中断数量,注册了中断处理程序的设备名称等。
其中注册了中断处理程序的设备名称就是我要寻找的内容。
/proc/interrupts
文件内容的一个典型示例如下:
CPU0 CPU1 CPU2 CPU3
0: 9 0 0 0 IO-APIC 2-edge timer
1: 0 0 0 111 IO-APIC 1-edge i8042
8: 1 0 0 0 IO-APIC 8-edge rtc0
9: 0 0 0 0 IO-APIC 9-fasteoi acpi
12: 0 0 945 0 IO-APIC 12-edge i8042
14: 0 0 0 0 IO-APIC 14-edge ata_piix
上述示例中的最后一列就是占用此中断号的设备名称,一般对应于某个内核模块。
基于这样的知识,要寻找中断被谁占用这个问题就非常容易解决了。我们只需要用中断号作为内容,检索 /proc/interrupts
文件即可。
出问题的机器上,检索得到了如下信息:
19: 94897 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 IO-APIC-fasteoi pata_jmicron
从上面的信息中可以发现,19 号中断是被 pata_jmicron
内核模块占用的。那这个内核模块又与什么设备关联呢?
查看内核模块关联的设备
首先 lsmod | grep ‘pata_jmicron’
查看发现没有找到 pata_jmicron
内核模块。那这个内核模块应该是被直接编译进了内核中。
lspci -v 查询到了可用的信息,相关的信息如下:
12:00.0 IDE interface: JMicron Technology Corp. JMB368 IDE controller (prog-if 85 [Master SecO PriO])
Subsystem: JMicron Technology Corp. JMB368 IDE controller
Flags: bus master, fast devsel, latency 0, IRQ 19
I/O ports at 4040 [size=8]
I/O ports at 4030 [size=4]
I/O ports at 4020 [size=8]
I/O ports at 4010 [size=4]
I/O ports at 4000 [size=16]
Expansion ROM at dfb00000 [disabled] [size=64K]
Capabilities: [68] Power Management version 2
Capabilities: [50] Express Legacy Endpoint, MSI 01
Kernel driver in use: pata_jmicron
从上面的信息中,可以发现 pata_jmicron
为 IDE 硬盘驱动。在找不到 19 号中断对应的中断处理程序之后,内核禁止了 19 号中断。这带来的结果是 IDE 硬盘无法正常读写,系统中的命令无法正常使用。只有通过 sysrq 来重启设备才能够恢复正常。