发现大部分资料都是介绍如何使用 Linux 下的 softirq,tasklet,workqueue 的。并没有解释这些机制究竟是怎么实现 bottom halves 的。感到很疑惑。我的理解:中断发生以后,陷入内核,执行中断处理程序,中断处理程序返回之后,CPU 应该恢复到被中断之前的状态,继续执行。如果是这样的话,我不能理解 bottom halves 什么时候能够得到执行。
1
misaka19000 2018-08-04 18:08:07 +08:00
我感觉你是不是把中断处理和多进程切换搞混了?
|
2
zchpeter 2018-08-04 21:12:41 +08:00 via Android
只要 cpu 能把现在的状态记录下来,运行完 interrupt handler 之后,恢复原状态就好。trick 就是把状态(运行到的指令的行数,local variables,etc) 放在 stack 中,执行完 interrupt handler 再出栈。
本质和 function call 类似 |
3
letianqiu OP @zchpeter 可能我的问题描述不清楚。我不理解的是 bottom halves 是怎么执行的。你描述的就是我说的 top havles。如果 top halves 直接返回到原来被中断的地方执行,那么被 defer 到 bottom halves 里的部分又是怎么能够得到执行的。
|
4
zchpeter 2018-08-04 21:36:39 +08:00 via Android
@letianqiu https://notes.shichao.io/lkd/ch8/
这篇讲的比较好。是我理解错了,之前不知道 top halves 和 bottom halves 的区别。其实 bottom halves 被执行的时间点不固定。很多情况都是 top half 被执行后,立刻执行 bottom half。主要要理解这样做的原因: top half 中,interrupt 都被禁了,所以要尽快执行完。而 bottom half 中是可以被 interrupt 的 |
5
letianqiu OP @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 里?
|
6
ryd994 2018-08-04 23:48:23 +08:00 via Android
@letianqiu "The key is that they run with all interrupts enabled.".
Quora 上的人说错了,或者你理解错了 bottom half 也关中断的话,还要分开来干嘛。可能他说的只是 bottom half 继续处理中断数据的意思。 |
7
lesteryu 2018-08-05 00:31:17 +08:00 via iPhone
Linux 上是怎么做的不熟,但是 Windows 上是通过中断级别 (IRQL) 和 Deferred Procedure Call (DPC,近似于 bottom half) 实现的。DPC 在 IRQL 里的优先级比硬件中断低,比软件中断高,和线程调度共享一个中断级别。当 Windows 在高 IRQL 下执行完中断例程(近似于 top half)之后,会把 IRQL 降低到 DPC 级别,然后执行所有在 DPC queue 里的 bottom halves,最后再把 IRQL 降低到其他的比如 APC 和用户线程级别。
|
8
letianqiu OP |
9
ryd994 2018-08-05 10:24:12 +08:00 via Android 1
@letianqiu 处理中断的时候应该要关低级中断啊,而且 top half 严禁 block
bottom half 是允许调度的,也就允许 block (实际上要看具体 bottom half 用的哪种) 是比普通进程优先,但在其他 upper half 的下面 |