http://blog.csdn.net/droidphone/article/details/7445825
enable_irq注意事项
对同一个中断,调用两次enable_irq(fpga_irq[0].irq);
后,程序将打印出:
------------[ cut here ]------------
WARNING: at kernel/irq/manage.c:274 __enable_irq+0x60/0x90()
Unbalanced enable for IRQ 62
Modules linked in: lcd_mini fpga_me [last unloaded: lcd_mini]
Backtrace:
[<c00341cc>] (dump_backtrace+0x0/0x10c) from [<c03297d0>] (dump_stack+0x18/0x1c)
r7:c03dfde8 r6:00000112 r5:c006fc10 r4:c3b07e48
[<c03297b8>] (dump_stack+0x0/0x1c) from [<c0048a80>] (warn_slowpath_common+0x4c/0x64)
[<c0048a34>] (warn_slowpath_common+0x0/0x64) from [<c0048ae4>] (warn_slowpath_fmt+0x30/0x38)
r7:bf000d5c r6:0000003e r5:60000013 r4:c044e4bc
[<c0048ab4>] (warn_slowpath_fmt+0x0/0x38) from [<c006fc10>] (__enable_irq+0x60/0x90)
r3:0000003e r2:c03dfe48
[<c006fbb0>] (__enable_irq+0x0/0x90) from [<c0070114>] (enable_irq+0x48/0x7c)
r5:60000013 r4:c044e4bc
[<c00700cc>] (enable_irq+0x0/0x7c) from [<bf000600>] (fpga_me_ioctl+0x294/0x4a0 [fpga_me])
r7:bf000d5c r6:00000000 r5:0000630b r4:c3afe3e0
[<bf00036c>] (fpga_me_ioctl+0x0/0x4a0 [fpga_me]) from [<c00a7a2c>] (vfs_ioctl+0x74/0x7c)
r7:00000003 r6:00000000 r5:0000630b r4:c3b0e500
[<c00a79b8>] (vfs_ioctl+0x0/0x7c) from [<c00a7ce8>] (do_vfs_ioctl+0x6c/0x5d4)
r7:00000003 r6:0000630b r5:00000000 r4:00000000
[<c00a7c7c>] (do_vfs_ioctl+0x0/0x5d4) from [<c00a8290>] (sys_ioctl+0x40/0x68)
[<c00a8250>] (sys_ioctl+0x0/0x68) from [<c002fee0>] (ret_fast_syscall+0x0/0x28)
r7:00000036 r6:00000000 r5:00000000 r4:00000000
---[ end trace fdde0938a9f4c6fd ]---
|
原因解析:
The enable_irq unbalanced messages are harmless. It just means that when the driver called disable_irq there were no devices already using the irq, and as such it was already disabled, so the call to disable_irq was forgotten by the kernel, so when we call enable_irq the core kernel code thinks it's unbalanced when it isn't.
我们再来跟一下这个unbalanced的代码:
void enable_irq(unsigned int irq)
{
struct irqdesc *desc = irq_desc + irq;
unsigned long flags;
spin_lock_irqsave(&irq_controller_lock, flags);
if (unlikely(!desc->disable_depth)) {
printk("enable_irq(%u) unbalanced from %p\n", irq,
__builtin_return_address(0));
} else if (!--desc->disable_depth) {
desc->probing = 0;
desc->chip->unmask(irq);
/*
* If the interrupt is waiting to be processed,
* try to re-run it. We can't directly run it
* from here since the caller might be in an
* interrupt-protected region.
*/
if (desc->pending && list_empty(&desc->pend)) {
desc->pending = 0;
if (!desc->chip->retrigger ||
desc->chip->retrigger(irq))
list_add(&desc->pend, &irq_pending);
}
}
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
|
可见unbalanced这个问题只会发生在enalbe_irq函数中,这里要提到一个变量disable_depth,这是一个标志中断禁止否的变量,如果调用disabled,这个变量会++,是正数,表示禁止中断,如果是enable,这个变量会--,是0,表示允许,一般都会一一对应。
而如果这个变量本身就是0,enable的时候,我们再去enable它的时候系统会去检查你这个是不是0,如果是0的话表示你这个中断本来就是打开的,你现在再去打开没有必要,这就是unbalanced了,所以可见这本身就是一个无害的信息。
阅读(11408) | 评论(0) | 转发(2) |