操作系统是如何实现 interrupt handler 的 bottom halves 的?

2018-08-04 17:48:29 +08:00
 letianqiu

发现大部分资料都是介绍如何使用 Linux 下的 softirq,tasklet,workqueue 的。并没有解释这些机制究竟是怎么实现 bottom halves 的。感到很疑惑。我的理解:中断发生以后,陷入内核,执行中断处理程序,中断处理程序返回之后,CPU 应该恢复到被中断之前的状态,继续执行。如果是这样的话,我不能理解 bottom halves 什么时候能够得到执行。

3049 次点击
所在节点    程序员
11 条回复
misaka19000
2018-08-04 18:08:07 +08:00
我感觉你是不是把中断处理和多进程切换搞混了?
zchpeter
2018-08-04 21:12:41 +08:00
只要 cpu 能把现在的状态记录下来,运行完 interrupt handler 之后,恢复原状态就好。trick 就是把状态(运行到的指令的行数,local variables,etc) 放在 stack 中,执行完 interrupt handler 再出栈。
本质和 function call 类似
letianqiu
2018-08-04 21:19:58 +08:00
@zchpeter 可能我的问题描述不清楚。我不理解的是 bottom halves 是怎么执行的。你描述的就是我说的 top havles。如果 top halves 直接返回到原来被中断的地方执行,那么被 defer 到 bottom halves 里的部分又是怎么能够得到执行的。
zchpeter
2018-08-04 21:36:39 +08:00
@letianqiu https://notes.shichao.io/lkd/ch8/
这篇讲的比较好。是我理解错了,之前不知道 top halves 和 bottom halves 的区别。其实 bottom halves 被执行的时间点不固定。很多情况都是 top half 被执行后,立刻执行 bottom half。主要要理解这样做的原因: top half 中,interrupt 都被禁了,所以要尽快执行完。而 bottom half 中是可以被 interrupt 的
letianqiu
2018-08-04 22:01:50 +08:00
@zchpeter 这篇就是 Robert Love 的 Linux Kernel Development 3rd Edition。我看过,也明白这么做的原因,但是就是不理解具体的实现原理。直接看源码迷失了。Quora 上 Robert Love 有个回答提到 bottom halves 也是在 interrupt context 里执行的,这也是让我迷惑的地方。如果 top halves 直接返回到 process,就变成 process context 了,被 defer 的 bottom halves 怎么能够在 interrupt context 里执行呢。难道说 top halves 返回之后必定跳转到 bottom havles 里执行,然后从 bottom halves 里返回才是回到被中断的 process 里?
ryd994
2018-08-04 23:48:23 +08:00
@letianqiu "The key is that they run with all interrupts enabled.".
Quora 上的人说错了,或者你理解错了
bottom half 也关中断的话,还要分开来干嘛。可能他说的只是 bottom half 继续处理中断数据的意思。
lesteryu
2018-08-05 00:31:17 +08:00
Linux 上是怎么做的不熟,但是 Windows 上是通过中断级别 (IRQL) 和 Deferred Procedure Call (DPC,近似于 bottom half) 实现的。DPC 在 IRQL 里的优先级比硬件中断低,比软件中断高,和线程调度共享一个中断级别。当 Windows 在高 IRQL 下执行完中断例程(近似于 top half)之后,会把 IRQL 降低到 DPC 级别,然后执行所有在 DPC queue 里的 bottom halves,最后再把 IRQL 降低到其他的比如 APC 和用户线程级别。
letianqiu
2018-08-05 09:20:47 +08:00
@ryd994 interrupt context 不是指关中断的情况,就是表示和并不是当前运行的 process 的 process context。我不理解的就是从 top halves 返回之后,究竟返回到什么地方。
@lesteryu 是不是可以这么理解,windows 下,Deferred Procedure Call (bottom halves)也是由 scheduler 调度的,并且 priority 比普通的 process 高,所以可以得到优先调度。这样的话,top halves 完成后,就直接回到被中断的 process context 里,继续执行。
ryd994
2018-08-05 10:24:12 +08:00
@letianqiu 处理中断的时候应该要关低级中断啊,而且 top half 严禁 block
bottom half 是允许调度的,也就允许 block (实际上要看具体 bottom half 用的哪种)
是比普通进程优先,但在其他 upper half 的下面
letianqiu
2018-08-05 13:07:43 +08:00
@ryd994 “处理中断的时候应该要关低级中断啊,而且 top half 严禁 block “ 我是理解的。如果 bottom halves 是被调度的话,我想我就明白了。我原来认为 bottom halves 和 top havles 一样,不是被调度的。
ryd994
2018-08-05 14:30:55 +08:00
@letianqiu 就算不能调度也有意义
因为可以开中断

比如说网卡,如果中断关太久,缓冲不够就只能丢包
网卡 tophalf 其实只要从缓冲里把数据取出,这个是不能被打断的
用 dma 或者 napi 的情况下只需要重设一下硬件状态
包内容的处理可以慢慢来,正常加锁就行,不必担心被打断

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/476886

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX