免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 12525 | 回复: 7
打印 上一主题 下一主题

[中断] 请教local_bh_enable()在中断上下文和中断关闭时调用引起警告的原因 [复制链接]

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-19 12:10 |只看该作者 |倒序浏览
local_bh_enable()中简单的调用了_local_bh_enable_ip()
  1. static inline void _local_bh_enable_ip(unsigned long ip)
  2. {
  3.         WARN_ON_ONCE(in_irq() || irqs_disabled());
  4. ......
  5. }
复制代码
请问这个WARNING的理由?

论坛徽章:
0
2 [报告]
发表于 2012-05-21 17:20 |只看该作者
本帖最后由 honkiko 于 2012-05-22 12:25 编辑

回复 1# asuka2001

对于irqs_disabled()的检查,我的理解,在irqs_disabled()的状态下,调用可能打开中断的函数/宏,都是有风险的。而local_bh_enable()就是这样的函数/宏。

在 (!in_irq && irqs_disabled()) 状态,而如果这个local_bh_enable()减掉的是最后一个SOFTIRQ_DISABLE_OFFSET, 就会进入do_softirq() -> __do_softirq(),  里面会无条件打开中断,然后执行所有pending的软中断处理函数。

下面的代码在这样的情况下会跟预期的情况不一样:
/**软中断或进程上下文中*/
local_irq_disable();
...操作链表A                    \
local_bh_enable();            临界区
...继续操作链表A              /
local_irq_enable();

假设某个中断也会操作链表A, 本来这个进程预期通过关中断,确保这个临界区不可能被中断所打断,来保护链表A。
但是,local_bh_enable()可能会打开中断。 这期间那个中断如果发生,也会去操作链表A, 而且是前面的进程也正处在临界区的时候。

在中断上下文,为什么不让调local_bh_enable()?想了一下,好像也有类似的原因:
/**进程上下文中*/
local_bh_disable()
...临界区X
local_bh_enable()

本来进程中认为在临界区X中的代码,是不会被软中断所打断的。 或者说进程在执行临界区X的代码时,不用担心有软中断会进入临界区。
但是,如果在某个中断里面,调用了local_bh_enable(), 那所有进程上下文的类似的临界区,都得不到这样的保证了。
因为在这段临界区,是可能发生中断的,然后如果local_bh_enable,正好减掉了最后一个SOFTIRQ_DISABLE_OFFSET, 在中断返回时,就会调用do_softirq了。



论坛徽章:
0
3 [报告]
发表于 2012-05-21 17:46 |只看该作者
回复 1# asuka2001


    这个检查不是简单的防止什么意外,而是为了检查代码是否遵从了规则。这东西本来就是这么设计的,所有的开发都必须遵从一定的规则,大家都这么搞就不会出乱子,就像是交通法规里面的靠右行驶一样。这里软中断原本就是用来在不太紧急(中断处理属于特殊的紧急事件)的时候处理一些事情,也就是说它原本就应该可以被中断,也就是说应该在硬中断打开的情况下干活,这就是规则。

论坛徽章:
0
4 [报告]
发表于 2012-05-21 18:10 |只看该作者
本帖最后由 honkiko 于 2012-05-21 18:11 编辑

回复 3# 灌水菜鸟

local_bh_enable并不会破坏你所说的规则:在硬中断打开的情况下干软中断的活。 __do_softirq()里面无条件先打开中断,然后干活的。

   

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
5 [报告]
发表于 2012-05-22 09:18 |只看该作者
回复 2# honkiko

非常感谢:)

论坛徽章:
0
6 [报告]
发表于 2013-01-23 13:30 |只看该作者
honkiko 发表于 2012-05-21 17:20
回复 1# asuka2001

对于irqs_disabled()的检查,我的理解,在irqs_disabled()的状态下,调用可能打开中 ...


2.6.36.1内核存在着不少你说的这种不允许中断上下文调local_bh_enable的情况:

__nf_conntrack_find经常在中断上下文调用,它调用了local_bh_disable 和 local_bh_enable

论坛徽章:
0
7 [报告]
发表于 2015-02-03 19:11 |只看该作者
回复 2# honkiko

中断上下文 应该不会有问题
if (unlikely(!in_interrupt() && local_softirq_pending()))
                do_softirq();
保证中断环境 不会进入do_softirq

而之所以产生警告。我认为是 中断环境没必要local_bh_disable()
所以也就不用local_bh_enable()
这个时候应该只是一个警告


而进程上下文 应该是你说的是对的。之前还以为也仅仅是个警告。一看你的回答,才发现不妙,要检查代码去了


   

论坛徽章:
0
8 [报告]
发表于 2015-02-03 19:14 |只看该作者
回复 2# honkiko
其实__do_softirq会local_irq_enable无条件看中断,也很奇怪的说
do_softirq 调用__do_softirq之前 还是用的local_irq_save

这点太奇怪了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP