免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: humjb_1983
打印 上一主题 下一主题

[中断] 中断嵌套问题 [复制链接]

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
11 [报告]
发表于 2014-01-14 15:33 |只看该作者
google 到一段话, 开起来x86下中断嵌套可能会引发GP异常:
Because IA-32 architecture tasks are not re-entrant, an interrupt-handler task must disable interrupts between the time it completes handling the interrupt and the time it executes the IRET instruction. This action prevents another interrupt from occurring while the interrupt task’s TSS is still marked busy, which would cause a general-protection (#GP) exception.

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
12 [报告]
发表于 2014-01-14 15:36 |只看该作者
gaojl0728 发表于 2014-01-14 15:11
研究了下最新的内核3.12.6
虽然在中断函数里可以手动开中断,但是在执行完当前中断处理函数之后内核会检测 ...

大概看了下git记录,应该是出于防范内核栈溢出的风险,而考虑尽力去除了中断嵌套的可能:
https://git.kernel.org/cgit/linu ... f640a0670433f794922
而且在检查到有人打开后,给出相应的警告,并强制关掉:
https://git.kernel.org/cgit/linu ... 5763b01bf9201779e50

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
13 [报告]
发表于 2014-01-14 17:18 |只看该作者
不错啊, 终于知道为什么要这样了哈:)

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
14 [报告]
发表于 2014-01-14 18:00 |只看该作者

我发现一个严重的问题, 就是IRQF_DISABLED被拿掉之后,会影响内核抢占, 从此以后内核从中断返回时再也不会发生抢占了:), 意外啊
看代码:
ret_from_exception:
        preempt_stop(CLBR_ANY)
ret_from_intr:
        .....省略....
        jb resume_kernel                # not returning to v8086 or userspace
   
ENTRY(resume_kernel)
        DISABLE_INTERRUPTS(CLBR_ANY)
        cmpl $0,TI_preempt_count(%ebp)        # non-zero preempt_count ?
        jnz restore_all
need_resched:
        movl TI_flags(%ebp), %ecx        # need_resched set ?
        testb $_TIF_NEED_RESCHED, %cl
        jz restore_all
        testl $X86_EFLAGS_IF,PT_EFLAGS(%esp)        # interrupts off (exception path) ?
        jz restore_all
        call preempt_schedule_irq
        jmp need_resched
END(resume_kernel)


在resume_kernel中,中断肯定是关掉的, 所以testl $X86_EFLAGS_IF,PT_EFLAGS(%esp)肯定是置位的,所以每次都走jz restore_all分支哈

但是在以前老的内核中,也就是IRQF_DISABLED存在的时候,一般注册中断的时候不会设置IRQF_DISABLED, 所以默认是开中断的,每次都会掉preempt_schedule_irq而发生抢占调度。
看来拿掉IRQF_DISABLED虽然能避免堆栈溢出,但是导致内核抢占的机会少了很多啊。也许得不偿失啊

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
15 [报告]
发表于 2014-01-14 18:09 |只看该作者
而且在新的内核中, 中断栈已经是固定8K而且跟内核栈是分开的, 溢出的可能性应该比较小了,

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
16 [报告]
发表于 2014-01-14 19:40 |只看该作者
gaojl0728 发表于 2014-01-14 18:00
我发现一个严重的问题, 就是IRQF_DISABLED被拿掉之后,会影响内核抢占, 从此以后内核从中断返回时再也不 ...

这个并不是问题,在关中断的情况下,本身就是不应该发生调度的,因为中断都关了,时钟中断也没有了,此时发生调度,切换到其他进程已经没有意义了,只会增加系统关中断的时间,导致更多的异常。

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
17 [报告]
发表于 2014-01-14 20:40 |只看该作者
需要指出的是 系统时钟中断跟进程切换没有直接关系, 时钟中断只是设置了need_resched标记以及更新时间片等等, 具体的进程切换还是发生在schedule的时候, 关中断了一样会发生任务切换。

以前老的内核内核只支持用户抢占,从linux2.6内核才开始支持内核抢占,而发生内核抢占的点大概也就两种:
1.从中断或异常返回内核空间
2. 其他就是手动调用schedule的时候,具体情况很多,比如手动调用schedle, spin_unlock, preemt_enable等等直接或间接调用schedule。

现在从中断返回这条路被关掉了, 我觉得影响还是比较大的,我猜他们在拿掉IRQF_DISABLED的时候也许没考虑到这点。
我说的中断也包括了系统时钟中断,系统时钟中断返回的代码路径跟普通中断是一样。

在实时系统里,关中断时间是个很重要的指标,但是linux不是实时系统,关中断的时间不是一个关键参数,linux这样实现内核抢占没有什么问题。

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
18 [报告]
发表于 2014-01-14 23:14 |只看该作者
回复 11# gaojl0728


    这段话其实是intel手册3A 6.12.2。
这里说的是TSS和任务门的使用规则,但好象linux不使用任务门,所以和本帖问题无关。

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
19 [报告]
发表于 2014-01-14 23:54 |只看该作者
回复 14# gaojl0728


    PT_EFLAGS应该是按esp取栈低保存的先前的eflags,而先前的可能是在进程上下文,IF可能是开的。
同样因为是直接取栈低,所以就只能使用非嵌套方式。

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
20 [报告]
发表于 2014-01-15 09:33 |只看该作者
回复 19# smalloc


    我感觉这个和能不能嵌套关系不大吧,esp应该是栈顶(x86栈向下增长,栈顶就是低地址), 而且栈里存的值应该是前面common_interrupt通过SAVE_ALL压进来的,所以就算嵌套应该也没关系。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP