Chinaunix首页 | 论坛 | 博客
  • 博客访问: 939267
  • 博文数量: 173
  • 博客积分: 3436
  • 博客等级: 中校
  • 技术积分: 1886
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-07 09:29
文章分类

全部博文(173)

文章存档

2016年(6)

2015年(10)

2014年(14)

2013年(8)

2012年(36)

2011年(63)

2010年(19)

2009年(17)

分类: LINUX

2011-04-04 20:44:26

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了,所以可见这本身就是一个无害的信息。

本文原因解析部分来自CSDN博客,转载请标明出处:http://blog.csdn.net/myleeming/archive/2009/06/02/4235224.aspx


阅读(11307) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~